An appallingly inefficient, but correct, implementation of rcr. On
x86, rcr is a dog. On amd64 it is a mangy dog with fleas on.
git-svn-id: svn://svn.valgrind.org/vex/trunk@1292 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest-amd64/ghelpers.c b/priv/guest-amd64/ghelpers.c
index 5ffc209..ec6ccf1 100644
--- a/priv/guest-amd64/ghelpers.c
+++ b/priv/guest-amd64/ghelpers.c
@@ -1507,6 +1507,75 @@
}
+ULong amd64g_calculate_RCR ( ULong arg,
+ ULong rot_amt,
+ ULong rflags_in,
+ Long szIN )
+{
+ Bool wantRflags = toBool(szIN < 0);
+ ULong sz = wantRflags ? (-szIN) : szIN;
+ ULong tempCOUNT = rot_amt & (sz == 8 ? 0x3F : 0x1F);
+ ULong cf=0, of=0, tempcf;
+
+ switch (sz) {
+ case 8:
+ cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ of = ((arg >> 63) ^ cf) & 1;
+ while (tempCOUNT > 0) {
+ tempcf = arg & 1;
+ arg = (arg >> 1) | (cf << 63);
+ cf = tempcf;
+ tempCOUNT--;
+ }
+ break;
+ case 4:
+ while (tempCOUNT >= 33) tempCOUNT -= 33;
+ cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ of = ((arg >> 31) ^ cf) & 1;
+ while (tempCOUNT > 0) {
+ tempcf = arg & 1;
+ arg = ((arg >> 1) & 0x7FFFFFFFULL) | (cf << 31);
+ cf = tempcf;
+ tempCOUNT--;
+ }
+ break;
+ case 2:
+ while (tempCOUNT >= 17) tempCOUNT -= 17;
+ cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ of = ((arg >> 15) ^ cf) & 1;
+ while (tempCOUNT > 0) {
+ tempcf = arg & 1;
+ arg = ((arg >> 1) & 0x7FFFULL) | (cf << 15);
+ cf = tempcf;
+ tempCOUNT--;
+ }
+ break;
+ case 1:
+ while (tempCOUNT >= 9) tempCOUNT -= 9;
+ cf = (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ of = ((arg >> 7) ^ cf) & 1;
+ while (tempCOUNT > 0) {
+ tempcf = arg & 1;
+ arg = ((arg >> 1) & 0x7FULL) | (cf << 7);
+ cf = tempcf;
+ tempCOUNT--;
+ }
+ break;
+ default:
+ vpanic("calculate_RCR(amd64g): invalid size");
+ }
+
+ cf &= 1;
+ of &= 1;
+ rflags_in &= ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O);
+ rflags_in |= (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O);
+
+ /* caller can ask to have back either the resulting flags or
+ resulting value, but not both */
+ return wantRflags ? rflags_in : arg;
+}
+
+
/*---------------------------------------------------------------*/
/*--- Helpers for MMX/SSE/SSE2. ---*/
/*---------------------------------------------------------------*/