]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86 guest: support rcr{bwl}. Includes some cleaning up of macro
authorJulian Seward <jseward@acm.org>
Sun, 24 Oct 2004 19:20:43 +0000 (19:20 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 24 Oct 2004 19:20:43 +0000 (19:20 +0000)
definitions in gdefs.h and ghelpers.c.

git-svn-id: svn://svn.valgrind.org/vex/trunk@406

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

index 758fe68372f6588abc1f1d18e2042bf8ee91e490..a1d84c9e06ca8386d225daa4b4da76bda310a8a1 100644 (file)
@@ -42,12 +42,19 @@ IRExpr* x86guest_spechelper ( Char* function_name,
 /*---------------------------------------------------------*/
 
 /* eflags masks */
-#define CC_MASK_C    0x0001
-#define CC_MASK_P    0x0004
-#define CC_MASK_A    0x0010
-#define CC_MASK_Z    0x0040
-#define CC_MASK_S    0x0080
-#define CC_MASK_O    0x0800
+#define CC_SHIFT_O   11
+#define CC_SHIFT_S   7
+#define CC_SHIFT_Z   6
+#define CC_SHIFT_A   4
+#define CC_SHIFT_C   0
+#define CC_SHIFT_P   2
+
+#define CC_MASK_O    (1 << CC_SHIFT_O)
+#define CC_MASK_S    (1 << CC_SHIFT_S)
+#define CC_MASK_Z    (1 << CC_SHIFT_Z)
+#define CC_MASK_A    (1 << CC_SHIFT_A)
+#define CC_MASK_C    (1 << CC_SHIFT_C)
+#define CC_MASK_P    (1 << CC_SHIFT_P)
 
 /* FPU flag masks */
 #define FC_MASK_C3   (1 << 14)
index 1717a7dc553c6b75bf7728211d61d91e18efaadb..7dea804603e2670ef8d46711fbda72eb0c8d37ca 100644 (file)
 #include "guest-x86/gdefs.h"
 
 /* --- Forwardses --- */
-       UInt calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt calculate_eflags_c   ( UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt calculate_condition  ( UInt/*Condcode*/ cond, 
-                                   UInt cc_op, UInt cc_src, UInt cc_dst );
-static UInt calculate_FXAM ( UInt tag, ULong dbl );
+
+/* --- CLEAN HELPERS --- */
+static UInt  calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst );
+static UInt  calculate_eflags_c   ( UInt cc_op, UInt cc_src, UInt cc_dst );
+static UInt  calculate_condition  ( UInt/*Condcode*/ cond, 
+                                    UInt cc_op, UInt cc_src, UInt cc_dst );
+static UInt  calculate_FXAM ( UInt tag, ULong dbl );
+static ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
+
+/* --- DIRTY HELPERS --- */
 static ULong loadF80le ( UInt );
 static void  storeF80le ( UInt, ULong );
 
@@ -49,44 +54,40 @@ static void  storeF80le ( UInt, ULong );
 typedef UChar uint8_t;
 typedef UInt  uint32_t;
 
-#define CC_O CC_MASK_O
-#define CC_P CC_MASK_P
-#define CC_C CC_MASK_C
-
 
 static const uint8_t parity_table[256] = {
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
-    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    CC_MASK_P, 0, 0, CC_MASK_P, 0, CC_MASK_P, CC_MASK_P, 0,
+    0, CC_MASK_P, CC_MASK_P, 0, CC_MASK_P, 0, 0, CC_MASK_P,
 };
 
 /* n must be a constant to be efficient */
@@ -131,7 +132,7 @@ inline static Int lshift ( Int x, Int n )
    zf = ((DATA_UTYPE)dst == 0) << 6;                           \
    sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst),              \
-               12 - DATA_BITS) & CC_O;                         \
+               12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -151,7 +152,7 @@ inline static Int lshift ( Int x, Int n )
    zf = ((DATA_UTYPE)dst == 0) << 6;                           \
    sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
    of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst),              \
-                12 - DATA_BITS) & CC_O;                                \
+                12 - DATA_BITS) & CC_MASK_O;                   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -171,7 +172,7 @@ inline static Int lshift ( Int x, Int n )
    zf = ((DATA_UTYPE)dst == 0) << 6;                           \
    sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
    of = lshift((src1 ^ src2) & (src1 ^ dst),                   \
-               12 - DATA_BITS) & CC_O;                                 \
+               12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -191,7 +192,7 @@ inline static Int lshift ( Int x, Int n )
    zf = ((DATA_UTYPE)dst == 0) << 6;                           \
    sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
    of = lshift((src1 ^ src2) & (src1 ^ dst),                   \
-               12 - DATA_BITS) & CC_O;                         \
+               12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -253,13 +254,13 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    int cf, pf, af, zf, sf, of;                                 \
-   cf = (CC_SRC >> (DATA_BITS - 1)) & CC_C;                    \
+   cf = (CC_SRC >> (DATA_BITS - 1)) & CC_MASK_C;               \
    pf = parity_table[(uint8_t)CC_DST];                         \
    af = 0; /* undefined */                                     \
    zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;                \
+   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_MASK_O;   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -275,7 +276,7 @@ inline static Int lshift ( Int x, Int n )
    zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
    sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_O;                \
+   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_MASK_O;   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -287,9 +288,9 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    int fl                                                      \
-      = (CC_SRC & ~(CC_O | CC_C))                              \
-        | (CC_C & CC_DST)                                      \
-        | (CC_O & (lshift(CC_DST, 11-(DATA_BITS-1))            \
+      = (CC_SRC & ~(CC_MASK_O | CC_MASK_C))                    \
+        | (CC_MASK_C & CC_DST)                                 \
+        | (CC_MASK_O & (lshift(CC_DST, 11-(DATA_BITS-1))       \
                    ^ lshift(CC_DST, 11)));                     \
    return fl;                                                  \
 }
@@ -302,9 +303,9 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    int fl                                                      \
-      = (CC_SRC & ~(CC_O | CC_C))                              \
-        | (CC_C & (CC_DST >> (DATA_BITS-1)))                   \
-        | (CC_O & (lshift(CC_DST, 11-(DATA_BITS-1))            \
+      = (CC_SRC & ~(CC_MASK_O | CC_MASK_C))                    \
+        | (CC_MASK_C & (CC_DST >> (DATA_BITS-1)))              \
+        | (CC_MASK_O & (lshift(CC_DST, 11-(DATA_BITS-1))       \
                    ^ lshift(CC_DST, 11-(DATA_BITS-1)+1)));     \
    return fl;                                                  \
 }
@@ -414,9 +415,9 @@ static void initCounts ( void )
 
 #endif /* PROFILE_EFLAGS */
 
-/* CALLED FROM GENERATED CODE */
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate all the 6 flags from the supplied thunk parameters. */
-/*static*/ 
+static
 UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
 {
 #  if PROFILE_EFLAGS
@@ -489,7 +490,7 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
 }
 
 
-/* CALLED FROM GENERATED CODE */
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate just the carry flag from the supplied thunk parameters. */
 static UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
 {
@@ -523,7 +524,7 @@ static UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
 }
 
 
-/* CALLED FROM GENERATED CODE */
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* returns 1 or 0 */
 /*static*/ UInt calculate_condition ( UInt/*Condcode*/ cond, 
                                       UInt cc_op, UInt cc_src, UInt cc_dst )
@@ -614,6 +615,8 @@ Addr64 x86guest_findhelper ( Char* function_name )
       return (Addr64)(Addr32)(& storeF80le);
    if (vex_streq(function_name, "loadF80le"))
       return (Addr64)(Addr32)(& loadF80le);
+   if (vex_streq(function_name, "calculate_RCR"))
+      return (Addr64)(Addr32)(& calculate_RCR);
    vex_printf("\nx86 guest: can't find helper: %s\n", function_name);
    vpanic("x86guest_findhelper");
 }
@@ -857,6 +860,7 @@ static inline Bool host_is_little_endian ( void )
    return (*p == 0x10);
 }
 
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
 static UInt calculate_FXAM ( UInt tag, ULong dbl ) 
 {
    Bool   mantissaIsZero;
@@ -1355,6 +1359,64 @@ void vex_initialise_x87 ( /* MOD*/VexGuestX86State* vex_state )
 }
 
 
+/*----------------------------------------------*/
+/*--- Misc integer helpers                   ---*/
+/*----------------------------------------------*/
+
+/* CALLED FROM GENERATED CODE: CLEAN HELPER */
+/* Calculate both flags and value result for rotate right
+   through the carry bit.  Result in low 32 bits, 
+   new flags (OSZACP) in high 32 bits.
+*/
+static ULong calculate_RCR ( 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 >> CC_SHIFT_C) & 1;
+         of        = ((arg >> 31) ^ cf) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = arg & 1;
+            arg    = (arg >> 1) | (cf << 31);
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         break;
+      case 2:
+         while (tempCOUNT >= 17) tempCOUNT -= 17;
+         cf        = (eflags_in >> CC_SHIFT_C) & 1;
+         of        = ((arg >> 15) ^ cf) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = arg & 1;
+            arg    = ((arg >> 1) & 0x7FFF) | (cf << 15);
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         break;
+      case 1:
+         while (tempCOUNT >= 9) tempCOUNT -= 9;
+         cf        = (eflags_in >> CC_SHIFT_C) & 1;
+         of        = ((arg >> 7) ^ cf) & 1;
+         while (tempCOUNT > 0) {
+            tempcf = arg & 1;
+            arg    = ((arg >> 1) & 0x7F) | (cf << 7);
+            cf     = tempcf;
+            tempCOUNT--;
+         }
+         break;
+      default: 
+         vpanic("calculate_RCR: invalid size");
+   }
+
+   cf &= 1;
+   of &= 1;
+   eflags_in &= ~(CC_MASK_C | CC_MASK_O);
+   eflags_in |= (cf << CC_SHIFT_C) | (of << CC_SHIFT_O);
+
+   return (((ULong)eflags_in) << 32) | ((ULong)arg);
+}
+
 /*---------------------------------------------------------------*/
 /*--- end                                guest-x86/ghelpers.c ---*/
 /*---------------------------------------------------------------*/
index a8c439b8eb8abe05bfcf541d020afa8c0067d8a3..181cbd5a38258a57e2d4b271372eb235ef4def02 100644 (file)
@@ -2296,7 +2296,7 @@ UInt dis_Grp2 ( UChar  sorb,
    /* delta on entry points at the modrm byte. */
    UChar  dis_buf[50];
    Int    len;
-   Bool   isShift, isRotate;
+   Bool   isShift, isRotate, isRotateRC;
    IRType ty    = szToITy(sz);
    IRTemp dst0  = newTemp(ty);
    IRTemp dst1  = newTemp(ty);
@@ -2320,11 +2320,31 @@ UInt dis_Grp2 ( UChar  sorb,
    isRotate = False;
    switch (gregOfRM(modrm)) { case 0: case 1: isRotate = True; }
 
-   if (!isShift && !isRotate) {
+   isRotateRC = gregOfRM(modrm) == 3;
+
+   if (!isShift && !isRotate && !isRotateRC) {
       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 */
+      IRTemp   r64  = newTemp(Ity_I64);
+      IRExpr** args = LibVEX_Alloc(5 * sizeof(IRExpr*));
+      args[0] = widenUto32(mkexpr(dst0)); /* thing to rotate */
+      args[1] = widenUto32(shift_expr);  /* rotate amount */
+      args[2] = widenUto32(mk_calculate_eflags_all());
+      args[3] = mkU32(sz);
+      args[4] = NULL;
+      assign( r64, IRExpr_CCall("calculate_RCR", Ity_I64, args) );
+      /* new eflags in hi half r64; new value in lo half r64 */
+      assign( dst1, narrowTo(ty, unop(Iop_64to32, mkexpr(r64))) );
+      stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
+      stmt( IRStmt_Put( OFFB_CC_SRC, unop(Iop_64HIto32, mkexpr(r64)) ));
+      stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
+   }
+
    if (isShift) {
 
       IRTemp pre32     = newTemp(Ity_I32);