]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Support x86 RCL instructions.
authorJulian Seward <jseward@acm.org>
Tue, 23 Aug 2005 15:41:14 +0000 (15:41 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 23 Aug 2005 15:41:14 +0000 (15:41 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@1341

VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c

index 2d4b899e5ab555b91170198edc6ca3a3238667d0..1df4a446e3b0c1d82889042cf5643d9b060ce921 100644 (file)
@@ -104,7 +104,10 @@ extern UInt  x86g_calculate_condition (
 
 extern UInt  x86g_calculate_FXAM ( UInt tag, ULong dbl );
 
-extern ULong x86g_calculate_RCR  ( 
+extern ULong x86g_calculate_RCR ( 
+                UInt arg, UInt rot_amt, UInt eflags_in, UInt sz 
+             );
+extern ULong x86g_calculate_RCL ( 
                 UInt arg, UInt rot_amt, UInt eflags_in, UInt sz 
              );
 
index db3487f11aad63bb36c7472297f3860cbe79476e..5aaaf9a45b98b2fcb40121f884fd8aa1f51e2730 100644 (file)
@@ -1638,6 +1638,61 @@ ULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
 }
 
 
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
+/* Calculate both flags and value result for rotate left
+   through the carry bit.  Result in low 32 bits, 
+   new flags (OSZACP) in high 32 bits.
+*/
+ULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
+{
+   UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf;
+
+   switch (sz) {
+      case 4:
+         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = (arg >> 31) & 1;
+            arg    = (arg << 1) | (cf & 1);
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         of = ((arg >> 31) ^ cf) & 1;
+         break;
+      case 2:
+         while (tempCOUNT >= 17) tempCOUNT -= 17;
+         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = (arg >> 15) & 1;
+            arg    = 0xFFFF & ((arg << 1) | (cf & 1));
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         of = ((arg >> 15) ^ cf) & 1;
+         break;
+      case 1:
+         while (tempCOUNT >= 9) tempCOUNT -= 9;
+         cf = (eflags_in >> X86G_CC_SHIFT_C) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = (arg >> 7) & 1;
+            arg    = 0xFF & ((arg << 1) | (cf & 1));
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         of = ((arg >> 7) ^ cf) & 1;
+         break;
+      default: 
+         vpanic("calculate_RCL: invalid size");
+   }
+
+   cf &= 1;
+   of &= 1;
+   eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O);
+   eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O);
+
+   return (((ULong)eflags_in) << 32) | ((ULong)arg);
+}
+
+
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (modifies guest state) */
 /* Claim to be a P55C (Intel Pentium/MMX) */
index 2cac30c6ed936b74a8543f79818c7ab03932c85f..f69dc5e1eff41ec510845d4901490e57736bb9f3 100644 (file)
@@ -2146,7 +2146,7 @@ UInt dis_Grp2 ( UChar sorb,
    /* delta on entry points at the modrm byte. */
    HChar  dis_buf[50];
    Int    len;
-   Bool   isShift, isRotate, isRotateRC;
+   Bool   isShift, isRotate, isRotateC;
    IRType ty    = szToITy(sz);
    IRTemp dst0  = newTemp(ty);
    IRTemp dst1  = newTemp(ty);
@@ -2170,16 +2170,18 @@ UInt dis_Grp2 ( UChar sorb,
    isRotate = False;
    switch (gregOfRM(modrm)) { case 0: case 1: isRotate = True; }
 
-   isRotateRC = toBool(gregOfRM(modrm) == 3);
+   isRotateC = False;
+   switch (gregOfRM(modrm)) { case 2: case 3: isRotateC = True; }
 
-   if (!isShift && !isRotate && !isRotateRC) {
+   if (!isShift && !isRotate && !isRotateC) {
       vex_printf("\ncase %d\n", gregOfRM(modrm));
       vpanic("dis_Grp2(Reg): unhandled case(x86)");
    }
 
-   if (isRotateRC) {
-      /* call a helper; this insn is so ridiculous it does not deserve
-         better */
+   if (isRotateC) {
+      /* call a helper; these insns are so ridiculous they do not
+         deserve better */
+      Bool     left = toBool(gregOfRM(modrm) == 2);
       IRTemp   r64  = newTemp(Ity_I64);
       IRExpr** args 
          = mkIRExprVec_4( widenUto32(mkexpr(dst0)), /* thing to rotate */
@@ -2189,7 +2191,8 @@ UInt dis_Grp2 ( UChar sorb,
       assign( r64, mkIRExprCCall(
                       Ity_I64, 
                       0/*regparm*/, 
-                      "x86g_calculate_RCR", &x86g_calculate_RCR,
+                      left ? "x86g_calculate_RCL" : "x86g_calculate_RCR", 
+                      left ? &x86g_calculate_RCL  : &x86g_calculate_RCR,
                       args
                    )
             );