]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Major overhaul of x86 guest eflags handling, so as to make one
authorJulian Seward <jseward@acm.org>
Fri, 5 Nov 2004 19:49:09 +0000 (19:49 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 5 Nov 2004 19:49:09 +0000 (19:49 +0000)
specific word of the thunk (CC_RES) have all data dependencies on
result of the flag setting operation.  The delayed-flag mechanism is
thusly modified so as to prevent Memcheck from giving false positives.

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

VEX/head20041019/none/nl_main.c
VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/pub/libvex.h
VEX/pub/libvex_guest_x86.h

index 8b52c014c8ba6cb041cd6b3f8e547977822fa4c2..fd644a77adae526af1e3809c5fb88a42bbe74c36 100644 (file)
@@ -47,7 +47,7 @@ void SK_(post_clo_init)(void)
 {
 }
 
-IRBB* SK_(instrument)(IRBB* bb, VexGuestLayout* layout)
+IRBB* SK_(instrument)(IRBB* bb, VexGuestLayout* layout, IRType hWordTy)
 {
     return bb;
 }
index 896d6e40b07152d1140328415716f196e9fe8d8d..84782fe0e618edead01c0580b664bb2e8c34b096 100644 (file)
@@ -46,10 +46,10 @@ VexGuestLayout x86guest_layout;
 /*---------------------------------------------------------*/
 
 /* --- CLEAN HELPERS --- */
-extern UInt  calculate_eflags_all ( UInt cc_op, UInt cc_src, UInt cc_dst );
-extern UInt  calculate_eflags_c   ( UInt cc_op, UInt cc_src, UInt cc_dst );
+extern UInt  calculate_eflags_all ( UInt cc_op, UInt cc_res, UInt cc_aux );
+extern UInt  calculate_eflags_c   ( UInt cc_op, UInt cc_res, UInt cc_aux );
 extern UInt  calculate_condition  ( UInt/*Condcode*/ cond, 
-                                    UInt cc_op, UInt cc_src, UInt cc_dst );
+                                    UInt cc_op, UInt cc_res, UInt cc_aux );
 extern UInt  calculate_FXAM ( UInt tag, ULong dbl );
 extern ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
 
@@ -84,61 +84,85 @@ extern void  dirtyhelper_CPUID ( VexGuestX86State* );
 #define FC_MASK_C1   (1 << 9)
 #define FC_MASK_C0   (1 << 8)
 
-/* eflags thunk descriptors. */
+/* %EFLAGS thunk descriptors.  This encoding is slightly non-obvious,
+   for the benefit of Memcheck.  The intention is to make RES be the
+   actual operation result -- or, in the case of multiply longs, at
+   least have a complete data dependency on the real result.  That
+   means that the AUX field needs to carry -- in the case of {S,U}MULL
+   -- a value which allows the real result to be recovered from the
+   RES field.
+
+   Note, for cases in which some or all of the old flags are also an
+   input (INC, DEC, ROL, ROR) we could have chosen to xor in the old
+   flags into the RES field.  The effect would be that Memcheck then
+   considers the result of the operation to also be dependent on the
+   definedness of the old flags.  This seems a step too far -- if the
+   compiler creates conditional jumps/moves partially dependent on
+   flags it is unsure of the definedness of -- then it is generating
+   buggy code.  So we don't do this.
+
+   In short, we need to roll into the RES field all inputs to the
+   computation that we want Memcheck to think have a bearing on the
+   definedness of the result.  We then tell Memcheck that only the RES
+   field needs to have its definedness tracked, and the AUX and OP
+   fields can be ignored.  The upshot is that we need to put in the
+   AUX field whatever info is needed to actually compute the flags
+   given the potentially strange mixture of stuff in the RES field.  
+*/
 enum {
-    CC_OP_COPY, /* nothing to do -- ccs are in CC_SRC and up to date */
+    CC_OP_COPY,    /* RES = current flags, AUX = 0, do nothing */
 
-    CC_OP_ADDB, /* modify all flags, CC_DST = src1, CC_SRC = src2 */
+    CC_OP_ADDB,    /* RES = argL+argR, AUX = argR */
     CC_OP_ADDW,
-    CC_OP_ADDL, /* 3 */
+    CC_OP_ADDL,    /* 3 */
 
-    CC_OP_ADCB, /* modify all flags, CC_DST = src1, CC_SRC = src2 */
+    CC_OP_ADCB,    /* RES = argL+argR, AUX = argR */
     CC_OP_ADCW,
-    CC_OP_ADCL, /* 6 */
+    CC_OP_ADCL,    /* 6 */
 
-    CC_OP_SUBB, /* modify all flags, CC_DST = src1, CC_SRC = src2 */
+    CC_OP_SUBB,    /* RES = argL-argR, AUX = argR */
     CC_OP_SUBW,
-    CC_OP_SUBL, /* 9 */
+    CC_OP_SUBL,    /* 9 */
 
-    CC_OP_SBBB, /* modify all flags, CC_DST = src1, CC_SRC = src2 */
+    CC_OP_SBBB,    /* RES = argL-argR, AUX = argR */
     CC_OP_SBBW,
-    CC_OP_SBBL, /* 12 */
+    CC_OP_SBBL,    /* 12 */
 
-    CC_OP_LOGICB, /* modify all flags, CC_DST = res, CC_SRC not used */
+    CC_OP_LOGICB,  /* RES = and/or/xor(argL,argR), AUX = 0 */
     CC_OP_LOGICW,
-    CC_OP_LOGICL, /* 15 */
+    CC_OP_LOGICL,  /* 15 */
 
-    CC_OP_INCB, /* modify all flags except C, CC_DST = res, CC_SRC = old C */
+    CC_OP_INCB,    /* RES = arg+1, AUX = old C flag (0 or 1) */
     CC_OP_INCW,
-    CC_OP_INCL, /* 18 */
+    CC_OP_INCL,    /* 18 */
 
-    CC_OP_DECB, /* modify all flags except C, CC_DST = res, CC_SRC = old C  */
+    CC_OP_DECB,    /* RES = arg-1, AUX = old C flag (0 or 1) */
     CC_OP_DECW,
-    CC_OP_DECL, /* 21 */
+    CC_OP_DECL,    /* 21 */
 
-    CC_OP_SHLB, /* modify all flags, CC_DST = res, CC_SRC = res' */
-    CC_OP_SHLW, /* where res' is like res but shifted one bit less */
-    CC_OP_SHLL, /* 24 */
+    CC_OP_SHLB,    /* RES = res, AUX = res' */
+    CC_OP_SHLW,    /* where res' is like res but shifted one bit less */
+    CC_OP_SHLL,    /* 24 */
 
-    CC_OP_SARB, /* modify all flags, CC_DST = res, CC_SRC = res' */
-    CC_OP_SARW, /* where res' is like res but shifted one bit less */
-    CC_OP_SARL, /* 27 */
+    CC_OP_SARB,    /* RES = res, AUX = res' */
+    CC_OP_SARW,    /* where res' is like res but shifted one bit less */
+    CC_OP_SARL,    /* 27 */
 
-    CC_OP_ROLB, /* modify C and O only.  CC_DST = res, CC_SRC = old flags */
+    CC_OP_ROLB,    /* RES = res, AUX = old flags */
     CC_OP_ROLW,
-    CC_OP_ROLL, /* 30 */
+    CC_OP_ROLL,    /* 30 */
 
-    CC_OP_RORB, /* modify C and O only.  CC_DST = res, CC_SRC = old flags */
+    CC_OP_RORB,    /* RES = res, AUX = old flags */
     CC_OP_RORW,
-    CC_OP_RORL, /* 33 */
+    CC_OP_RORL,    /* 33 */
 
-    CC_OP_UMULB, /* modify all flags, CC_DST = one arg */
-    CC_OP_UMULW, /* CC_SRC = the other arg */
-    CC_OP_UMULL, /* 36 */
+    CC_OP_UMULB,   /* RES = hiHalf(result) ^ loHalf(result) */
+    CC_OP_UMULW,   /* AUX = loHalf(result) */
+    CC_OP_UMULL,   /* 36 */
 
-    CC_OP_SMULB, /* modify all flags, CC_DST = one arg */
-    CC_OP_SMULW, /* CC_SRC = the other arg */
-    CC_OP_SMULL, /* 39 */
+    CC_OP_SMULB,   /* RES = hiHalf(result) ^ loHalf(result) */
+    CC_OP_SMULW,   /* AUX = loHalf(result) */
+    CC_OP_SMULL,   /* 39 */
 
     CC_OP_NUMBER
 };
index d9608a1577e4fff9b45618dc14b3aec89a3130c3..33440432528c1ad58e09387672db252bfd5ed0bc 100644 (file)
@@ -87,14 +87,14 @@ inline static Int lshift ( Int x, Int n )
                        : (__data_bits==16 ? 0xFFFF             \
                                           : 0xFFFFFFFF);       \
    /* const */ UInt SIGN_MASK = 1 << (__data_bits - 1);                \
-   /* const */ UInt CC_DST = cc_dst_formal;                    \
-   /* const */ UInt CC_SRC = cc_src_formal;                    \
+   /* const */ UInt CC_RES = cc_res_formal;                    \
+   /* const */ UInt CC_AUX = cc_aux_formal;                    \
    /* Three bogus assignments, which hopefully gcc can    */   \
    /* optimise away, and which stop it complaining about  */   \
    /* unused variables.                                   */   \
    SIGN_MASK = SIGN_MASK;                                      \
    DATA_MASK = DATA_MASK;                                      \
-   CC_SRC = CC_SRC;
+   CC_AUX = CC_AUX;
 
 
 /*-------------------------------------------------------------*/
@@ -102,17 +102,17 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_ADD(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2, dst;                                                \
-   src1 = CC_SRC;                                              \
-   src2 = CC_DST;                                              \
-   dst  = src1 + src2;                                         \
-   cf = (DATA_UTYPE)dst < (DATA_UTYPE)src1;                    \
-   pf = parity_table[(UChar)dst];                              \
-   af = (dst ^ src1 ^ src2) & 0x10;                            \
-   zf = ((DATA_UTYPE)dst == 0) << 6;                           \
-   sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
-   of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst),              \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR, res;                                                \
+   argL = CC_RES - CC_AUX;                                     \
+   argR = CC_AUX;                                              \
+   res  = CC_RES;                                              \
+   cf = (DATA_UTYPE)res < (DATA_UTYPE)argL;                    \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = lshift((argL ^ argR ^ -1) & (argL ^ res),              \
                12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -122,17 +122,17 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_ADC(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2, dst;                                                \
-   src1 = CC_SRC;                                              \
-   src2 = CC_DST;                                              \
-   dst = src1 + src2 + 1;                                      \
-   cf = (DATA_UTYPE)dst <= (DATA_UTYPE)src1;                   \
-   pf = parity_table[(UChar)dst];                              \
-   af = (dst ^ src1 ^ src2) & 0x10;                            \
-   zf = ((DATA_UTYPE)dst == 0) << 6;                           \
-   sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
-   of = lshift((src1 ^ src2 ^ -1) & (src1 ^ dst),              \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR, res;                                                \
+   argL = CC_RES - CC_AUX - 1;                                 \
+   argR = CC_AUX;                                              \
+   res  = CC_RES;                                              \
+   cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL;                   \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = lshift((argL ^ argR ^ -1) & (argL ^ res),              \
                 12 - DATA_BITS) & CC_MASK_O;                   \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -142,17 +142,17 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_SUB(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2, dst;                                                \
-   src1 = CC_DST;                                              \
-   src2 = CC_SRC;                                              \
-   dst = src1 - src2;                                          \
-   cf = (DATA_UTYPE)src1 < (DATA_UTYPE)src2;                   \
-   pf = parity_table[(UChar)dst];                              \
-   af = (dst ^ src1 ^ src2) & 0x10;                            \
-   zf = ((DATA_UTYPE)dst == 0) << 6;                           \
-   sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
-   of = lshift((src1 ^ src2) & (src1 ^ dst),                   \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR, res;                                                \
+   argL = CC_RES + CC_AUX;                                     \
+   argR = CC_AUX;                                              \
+   res  = CC_RES;                                              \
+   cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR;                   \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = lshift((argL ^ argR) & (argL ^ res),                   \
                12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -162,17 +162,17 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_SBB(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2, dst;                                                \
-   src1 = CC_DST;                                              \
-   src2 = CC_SRC;                                              \
-   dst = (src1 - src2) - 1;                                    \
-   cf = (DATA_UTYPE)src1 <= (DATA_UTYPE)src2;                  \
-   pf = parity_table[(UChar)dst];                              \
-   af = (dst ^ src1 ^ src2) & 0x10;                            \
-   zf = ((DATA_UTYPE)dst == 0) << 6;                           \
-   sf = lshift(dst, 8 - DATA_BITS) & 0x80;                     \
-   of = lshift((src1 ^ src2) & (src1 ^ dst),                   \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR, res;                                                \
+   argL = CC_RES + CC_AUX + 1;                                 \
+   argR = CC_AUX;                                              \
+   res  = CC_RES;                                              \
+   cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR;                  \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = lshift((argL ^ argR) & (argL ^ res),                   \
                12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -182,12 +182,12 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_LOGIC(DATA_BITS,DATA_UTYPE)                    \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
+   Int cf, pf, af, zf, sf, of;                                 \
    cf = 0;                                                     \
-   pf = parity_table[(UChar)CC_DST];                           \
+   pf = parity_table[(UChar)CC_RES];                           \
    af = 0;                                                     \
-   zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
-   sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
+   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
    of = 0;                                                     \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -197,16 +197,16 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_INC(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2;                                             \
-   src1 = CC_DST - 1;                                          \
-   src2 = 1;                                                   \
-   cf = CC_SRC;                                                        \
-   pf = parity_table[(UChar)CC_DST];                           \
-   af = (CC_DST ^ src1 ^ src2) & 0x10;                         \
-   zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
-   sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
-   of = ((CC_DST & DATA_MASK) == SIGN_MASK) << 11;             \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR;                                             \
+   argL = CC_RES - 1;                                          \
+   argR = 1;                                                   \
+   cf = CC_AUX & CC_MASK_O;                                    \
+   pf = parity_table[(UChar)CC_RES];                           \
+   af = (CC_RES ^ argL ^ argR) & 0x10;                         \
+   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
+   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
+   of = ((CC_RES & DATA_MASK) == SIGN_MASK) << 11;             \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -215,16 +215,16 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_DEC(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   int src1, src2;                                             \
-   src1 = CC_DST + 1;                                          \
-   src2 = 1;                                                   \
-   cf = CC_SRC;                                                        \
-   pf = parity_table[(UChar)CC_DST];                           \
-   af = (CC_DST ^ src1 ^ src2) & 0x10;                         \
-   zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
-   sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
-   of = ((CC_DST & DATA_MASK)                                  \
+   Int cf, pf, af, zf, sf, of;                                 \
+   Int argL, argR;                                             \
+   argL = CC_RES + 1;                                          \
+   argR = 1;                                                   \
+   cf = CC_AUX & CC_MASK_O;                                    \
+   pf = parity_table[(UChar)CC_RES];                           \
+   af = (CC_RES ^ argL ^ argR) & 0x10;                         \
+   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
+   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
+   of = ((CC_RES & DATA_MASK)                                  \
         == ((UInt)SIGN_MASK - 1)) << 11;                       \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -234,14 +234,14 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_SHL(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   cf = (CC_SRC >> (DATA_BITS - 1)) & CC_MASK_C;               \
-   pf = parity_table[(UChar)CC_DST];                           \
+   Int cf, pf, af, zf, sf, of;                                 \
+   cf = (CC_AUX >> (DATA_BITS - 1)) & CC_MASK_C;               \
+   pf = parity_table[(UChar)CC_RES];                           \
    af = 0; /* undefined */                                     \
-   zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
-   sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
+   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_MASK_O;   \
+   of = lshift(CC_AUX ^ CC_RES, 12 - DATA_BITS) & CC_MASK_O;   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -250,14 +250,14 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_SAR(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                        \
-   int cf, pf, af, zf, sf, of;                                 \
-   cf = CC_SRC & 1;                                            \
-   pf = parity_table[(UChar)CC_DST];                           \
+   Int cf, pf, af, zf, sf, of;                                 \
+   cf = CC_AUX & 1;                                            \
+   pf = parity_table[(UChar)CC_RES];                           \
    af = 0; /* undefined */                                     \
-   zf = ((DATA_UTYPE)CC_DST == 0) << 6;                                \
-   sf = lshift(CC_DST, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
+   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_SRC ^ CC_DST, 12 - DATA_BITS) & CC_MASK_O;   \
+   of = lshift(CC_AUX ^ CC_RES, 12 - DATA_BITS) & CC_MASK_O;   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -268,11 +268,11 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_ROL(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int fl                                                      \
-      = (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)));                     \
+   Int fl                                                      \
+      = (CC_AUX & ~(CC_MASK_O | CC_MASK_C))                    \
+        | (CC_MASK_C & CC_RES)                                 \
+        | (CC_MASK_O & (lshift(CC_RES, 11-(DATA_BITS-1))       \
+                   ^ lshift(CC_RES, 11)));                     \
    return fl;                                                  \
 }
 
@@ -283,50 +283,44 @@ inline static Int lshift ( Int x, Int n )
 #define ACTIONS_ROR(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int fl                                                      \
-      = (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)));     \
+   Int fl                                                      \
+      = (CC_AUX & ~(CC_MASK_O | CC_MASK_C))                    \
+        | (CC_MASK_C & (CC_RES >> (DATA_BITS-1)))              \
+        | (CC_MASK_O & (lshift(CC_RES, 11-(DATA_BITS-1))       \
+                   ^ lshift(CC_RES, 11-(DATA_BITS-1)+1)));     \
    return fl;                                                  \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE,DATA_U2TYPE)         \
+#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE)                     \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   DATA_UTYPE  hi;                                             \
-   DATA_UTYPE  lo = ((DATA_UTYPE)CC_SRC) * ((DATA_UTYPE)CC_DST);\
-   DATA_U2TYPE rr = ((DATA_U2TYPE)((DATA_UTYPE)CC_SRC))                \
-                    * ((DATA_U2TYPE)((DATA_UTYPE)CC_DST));     \
-   hi = (DATA_UTYPE)(rr >>/*u*/ DATA_BITS);                    \
-   cf = (hi != 0);                                             \
-   pf = parity_table[(UChar)lo];                               \
+   Int cf, pf, af, zf, sf, of;                                 \
+   DATA_UTYPE resHi = DATA_MASK & (CC_RES ^ CC_AUX);           \
+   DATA_UTYPE resLo = DATA_MASK & CC_AUX;                      \
+   cf = (resHi != 0);                                          \
+   pf = parity_table[(UChar)resLo];                            \
    af = 0; /* undefined */                                     \
-   zf = (lo == 0) << 6;                                                \
-   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                      \
+   zf = (resLo == 0) << 6;                                     \
+   sf = lshift(resLo, 8 - DATA_BITS) & 0x80;                   \
    of = cf << 11;                                              \
    return cf | pf | af | zf | sf | of;                         \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE,DATA_S2TYPE)         \
+#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE)                     \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
-   int cf, pf, af, zf, sf, of;                                 \
-   DATA_STYPE  hi;                                             \
-   DATA_STYPE  lo = ((DATA_STYPE)CC_SRC) * ((DATA_STYPE)CC_DST);\
-   DATA_S2TYPE rr = ((DATA_S2TYPE)((DATA_STYPE)CC_SRC))                \
-                    * ((DATA_S2TYPE)((DATA_STYPE)CC_DST));     \
-   hi = (DATA_STYPE)(rr >>/*s*/ DATA_BITS);                    \
-   cf = (hi != (lo >>/*s*/ (DATA_BITS-1)));                    \
-   pf = parity_table[(UChar)lo];                               \
+   Int cf, pf, af, zf, sf, of;                                 \
+   DATA_STYPE resHi = DATA_MASK & (CC_RES ^ CC_AUX);           \
+   DATA_STYPE resLo = DATA_MASK & CC_AUX;                      \
+   cf = (resHi != (resLo >>/*s*/ (DATA_BITS-1)));              \
+   pf = parity_table[(UChar)resLo];                            \
    af = 0; /* undefined */                                     \
-   zf = (lo == 0) << 6;                                                \
-   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                      \
+   zf = (resLo == 0) << 6;                                     \
+   sf = lshift(resLo, 8 - DATA_BITS) & 0x80;                   \
    of = cf << 11;                                              \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -398,14 +392,14 @@ static void initCounts ( void )
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate all the 6 flags from the supplied thunk parameters. */
-UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
+UInt calculate_eflags_all ( UInt cc_op, UInt cc_res_formal, UInt cc_aux_formal )
 {
 #  if PROFILE_EFLAGS
    n_calc_all++;
 #  endif
    switch (cc_op) {
       case CC_OP_COPY:
-         return cc_src_formal
+         return cc_res_formal
                 & (CC_MASK_O | CC_MASK_S | CC_MASK_Z 
                    | CC_MASK_A | CC_MASK_C | CC_MASK_P);
 
@@ -453,18 +447,18 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
       case CC_OP_RORW:   ACTIONS_ROR( 16, UShort );
       case CC_OP_RORL:   ACTIONS_ROR( 32, UInt   );
 
-      case CC_OP_UMULB:  ACTIONS_UMUL(  8, UChar,  UShort );
-      case CC_OP_UMULW:  ACTIONS_UMUL( 16, UShort, UInt   );
-      case CC_OP_UMULL:  ACTIONS_UMUL( 32, UInt,   ULong  );
+      case CC_OP_UMULB:  ACTIONS_UMUL(  8, UChar  );
+      case CC_OP_UMULW:  ACTIONS_UMUL( 16, UShort );
+      case CC_OP_UMULL:  ACTIONS_UMUL( 32, UInt   );
 
-      case CC_OP_SMULB:  ACTIONS_SMUL(  8, Char,  Short );
-      case CC_OP_SMULW:  ACTIONS_SMUL( 16, Short, Int   );
-      case CC_OP_SMULL:  ACTIONS_SMUL( 32, Int,   Long  );
+      case CC_OP_SMULB:  ACTIONS_SMUL(  8, Char  );
+      case CC_OP_SMULW:  ACTIONS_SMUL( 16, Short );
+      case CC_OP_SMULL:  ACTIONS_SMUL( 32, Int   );
 
       default:
          /* shouldn't really make these calls from generated code */
          vex_printf("calculate_eflags_all( %d, 0x%x, 0x%x )\n",
-                    cc_op, cc_src_formal, cc_dst_formal );
+                    cc_op, cc_res_formal, cc_res_formal );
          vpanic("calculate_eflags_all");
    }
 }
@@ -472,10 +466,11 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_src_formal, UInt cc_dst_formal )
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate just the carry flag from the supplied thunk parameters. */
-UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
+UInt calculate_eflags_c ( UInt cc_op, UInt cc_res, UInt cc_aux )
 {
    /* Fast-case some common ones. */
    switch (cc_op) {
+#if 0
       case CC_OP_LOGICL: case CC_OP_LOGICW: case CC_OP_LOGICB:
          return 0;
       case CC_OP_DECL:
@@ -489,6 +484,7 @@ UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
       case CC_OP_SUBB:
          return ( ((UInt)(cc_src & 0xFF)) > ((UInt)(cc_dst & 0xFF)) ) 
                    ? CC_MASK_C : 0;
+#endif
       default: 
          break;
    }
@@ -500,16 +496,16 @@ UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
 
    n_calc_c++;
 #  endif
-   return calculate_eflags_all(cc_op,cc_src,cc_dst) & CC_MASK_C;
+   return calculate_eflags_all(cc_op,cc_res,cc_aux) & CC_MASK_C;
 }
 
 
 /* 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 )
+                                      UInt cc_op, UInt cc_res, UInt cc_aux )
 {
-   UInt eflags = calculate_eflags_all(cc_op, cc_src, cc_dst);
+   UInt eflags = calculate_eflags_all(cc_op, cc_res, cc_aux);
    UInt of,sf,zf,cf,pf;
    UInt inv = cond & 1;
 
@@ -575,7 +571,7 @@ UInt calculate_eflags_c ( UInt cc_op, UInt cc_src, UInt cc_dst )
       default:
          /* shouldn't really make these calls from generated code */
          vex_printf("calculate_condition( %d, %d, 0x%x, 0x%x )\n",
-                    cond, cc_op, cc_src, cc_dst );
+                    cond, cc_op, cc_res, cc_aux );
          vpanic("calculate_condition");
    }
 }
@@ -610,7 +606,7 @@ IRExpr* x86guest_spechelper ( Char* function_name,
    }
    vex_printf("\n");
 #  endif
-
+return NULL;
    if (vex_streq(function_name, "calculate_eflags_c")) {
       /* specialise calls to above "calculate_eflags_c" function */
       IRExpr *cc_op, *cc_src, *cc_dst;
@@ -1283,8 +1279,8 @@ void LibVEX_GuestX86_put_eflags ( UInt eflags_native,
           | CC_MASK_Z | CC_MASK_S | CC_MASK_O);
 
    vex_state->guest_CC_OP  = CC_OP_COPY;
-   vex_state->guest_CC_DST = 0;
-   vex_state->guest_CC_DST = eflags_native;
+   vex_state->guest_CC_AUX = 0;
+   vex_state->guest_CC_RES = eflags_native;
 }
 
 
@@ -1293,8 +1289,8 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state )
 {
    UInt eflags = calculate_eflags_all(
                     vex_state->guest_CC_OP,
-                    vex_state->guest_CC_SRC,
-                    vex_state->guest_CC_DST
+                    vex_state->guest_CC_RES,
+                    vex_state->guest_CC_AUX
                  );
    UInt dflag = vex_state->guest_DFLAG;
    vassert(dflag == 1 || dflag == 0xFFFFFFFF);
@@ -1321,8 +1317,8 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    vex_state->guest_EDI = 0;
 
    vex_state->guest_CC_OP  = CC_OP_COPY;
-   vex_state->guest_CC_SRC = 0;
-   vex_state->guest_CC_DST = 0;
+   vex_state->guest_CC_RES = 0;
+   vex_state->guest_CC_AUX = 0;
    vex_state->guest_DFLAG  = 1; /* forwards */
    vex_state->guest_IDFLAG = 0;
 
@@ -1479,8 +1475,12 @@ VexGuestLayout
 
           /* Describe any sections to be regarded by Memcheck as
              'always-defined'. */
-          .n_alwaysDefd = 14,
+          .n_alwaysDefd = 15,
+          /* flags thunk: OP and AUX are always defd; only RES isn't.
+             See detailed comment in gdefs.h on meaning of thunk
+             fields. */
           .alwaysDefd[0]  = ALWAYSDEFD(guest_CC_OP),
+          .alwaysDefd[14] = ALWAYSDEFD(guest_CC_AUX),
           .alwaysDefd[1]  = ALWAYSDEFD(guest_DFLAG),
           .alwaysDefd[2]  = ALWAYSDEFD(guest_IDFLAG),
           .alwaysDefd[3]  = ALWAYSDEFD(guest_EIP),
index e75a08d05d309f11749b765fbf53105da0e15479..616b1c98ebd6a79f5d23bde15f773ac2856b4030 100644 (file)
@@ -85,8 +85,8 @@ static IRBB* irbb;
 #define OFFB_EDX     offsetof(VexGuestX86State,guest_EDX)
 #define OFFB_EIP     offsetof(VexGuestX86State,guest_EIP)
 #define OFFB_CC_OP   offsetof(VexGuestX86State,guest_CC_OP)
-#define OFFB_CC_SRC  offsetof(VexGuestX86State,guest_CC_SRC)
-#define OFFB_CC_DST  offsetof(VexGuestX86State,guest_CC_DST)
+#define OFFB_CC_RES  offsetof(VexGuestX86State,guest_CC_RES)
+#define OFFB_CC_AUX  offsetof(VexGuestX86State,guest_CC_AUX)
 #define OFFB_DFLAG   offsetof(VexGuestX86State,guest_DFLAG)
 #define OFFB_IDFLAG  offsetof(VexGuestX86State,guest_IDFLAG)
 #define OFFB_FTOP    offsetof(VexGuestX86State,guest_FTOP)
@@ -552,6 +552,21 @@ static IROp mkSizedOp ( IRType ty, IROp op8 )
 {
    Int adj;
    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
+
+   switch (op8) {
+      case Iop_MullS8: 
+         return ty==Ity_I8 ? Iop_MullS8
+                : (ty==Ity_I16 ? Iop_MullS16 : Iop_MullS32);
+      case Iop_16HIto8: 
+         return ty==Ity_I8 ? Iop_16HIto8
+                : (ty==Ity_I16 ? Iop_32HIto16 : Iop_64HIto32);
+      case Iop_16to8: 
+         return ty==Ity_I8 ? Iop_16to8
+                : (ty==Ity_I16 ? Iop_32to16 : Iop_64to32);
+      default:
+         break;
+   }
+
    vassert(op8 == Iop_Add8 || op8 == Iop_Sub8 
            || op8 == Iop_Mul8 
            || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8
@@ -573,9 +588,18 @@ static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd )
    if (szSmall == 2 && szBig == 4) {
       return signd ? Iop_16Sto32 : Iop_16Uto32;
    }
-   vpanic("mkWidenOp(x86)");
+   vpanic("mkWidenOp(x86,guest)");
 }
 
+static IRType doubleLengthType ( IRType ty )
+{
+   switch (ty) {
+      case Ity_I8: return Ity_I16;
+      case Ity_I16: return Ity_I32;
+      case Ity_I32: return Ity_I64;
+      default: vpanic("doubleLengthType(x86,guest)");
+   }
+}
 
 /*------------------------------------------------------------*/
 /*--- Helpers for %eflags.                                 ---*/
@@ -584,13 +608,13 @@ static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd )
 /* -------------- Evaluating the flags-thunk. -------------- */
 
 /* Build IR to calculate all the eflags from stored
-   CC_OP/CC_SRC/CC_DST.  Returns an expression :: Ity_I32. */
+   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_I32. */
 static IRExpr* mk_calculate_eflags_all ( void )
 {
    IRExpr** args
       = mkIRExprVec_3( IRExpr_Get(OFFB_CC_OP,  Ity_I32),
-                       IRExpr_Get(OFFB_CC_SRC, Ity_I32),
-                       IRExpr_Get(OFFB_CC_DST, Ity_I32) );
+                       IRExpr_Get(OFFB_CC_RES, Ity_I32),
+                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
    return mkIRExprCCall(
              Ity_I32,
              0/*regparm*/, 
@@ -600,13 +624,13 @@ static IRExpr* mk_calculate_eflags_all ( void )
 }
 
 /* Build IR to calculate just the carry flag from stored
-   CC_OP/CC_SRC/CC_DST.  Returns an expression :: Ity_I32. */
+   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_I32. */
 static IRExpr* mk_calculate_eflags_c ( void )
 {
    IRExpr** args
       = mkIRExprVec_3( IRExpr_Get(OFFB_CC_OP,  Ity_I32),
-                       IRExpr_Get(OFFB_CC_SRC, Ity_I32),
-                       IRExpr_Get(OFFB_CC_DST, Ity_I32) );
+                       IRExpr_Get(OFFB_CC_RES, Ity_I32),
+                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
    return mkIRExprCCall(
              Ity_I32,
              0/*regparm*/, 
@@ -616,14 +640,14 @@ static IRExpr* mk_calculate_eflags_c ( void )
 }
 
 /* Build IR to calculate some particular condition from stored
-   CC_OP/CC_SRC/CC_DST.  Returns an expression :: Ity_Bit. */
+   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_Bit. */
 static IRExpr* mk_calculate_condition ( Condcode cond )
 {
    IRExpr** args
       = mkIRExprVec_4( mkU32(cond),
                        IRExpr_Get(OFFB_CC_OP,  Ity_I32),
-                       IRExpr_Get(OFFB_CC_SRC, Ity_I32),
-                       IRExpr_Get(OFFB_CC_DST, Ity_I32) );
+                       IRExpr_Get(OFFB_CC_RES, Ity_I32),
+                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
    return unop(Iop_32to1, 
                mkIRExprCCall(
                   Ity_I32,
@@ -639,8 +663,6 @@ static IRExpr* mk_calculate_condition ( Condcode cond )
 
 /* The machinery in this section builds the flag-thunk following a
    flag-setting operation.  Hence the various setFlags_* functions.
-   Note, in reality setFlags_ADD_SUB and setFlags_MUL are pretty much
-   the same -- they just store the two operands.  
 */
 
 static Bool isAddSub ( IROp op8 )
@@ -691,14 +713,12 @@ static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
 }
 
 
-/* This is for add/sub/adc/sbb, where (like multiply) we simply store
-   the two arguments.  Note, the args are reversed, so if op8
-   indicates subtract, then the value the program is trying to compute
-   is src1 - src2. */
+/* Set the flags thunk for add/sub operations..  The supplied op is
+   auto-sized up to the real op. */
 
-static void setFlags_ADD_SUB ( IROp    op8,
-                               IRTemp  src2,
-                               IRTemp  src1,
+static void setFlags_RES_AUX ( IROp    op8,
+                               IRTemp  res,
+                               IRTemp  aux,
                                IRType  ty )
 {
    Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
@@ -709,19 +729,19 @@ static void setFlags_ADD_SUB ( IROp    op8,
       case Iop_Add8: ccOp += CC_OP_ADDB;   break;
       case Iop_Sub8: ccOp += CC_OP_SUBB;   break;
       default:       ppIROp(op8);
-                     vpanic("setFlags_ADD_SUB(x86)");
+                     vpanic("setFlags_RES_AUX(x86)");
    }
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_SRC, widenUto32(mkexpr(src2))) );
-   stmt( IRStmt_Put( OFFB_CC_DST, widenUto32(mkexpr(src1))) );
+   stmt( IRStmt_Put( OFFB_CC_RES, widenUto32(mkexpr(res))) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, widenUto32(mkexpr(aux))) );
 }
 
 
 /* For and/or/xor, only the result is important.  However, put zero in
-   CC_SRC to keep memcheck happy. */
+   CC_AUX since we're paranoid. */
 
 static void setFlags_LOGIC ( IROp    op8,
-                             IRTemp  dst1,
+                             IRTemp  res,
                              IRType  ty )
 {
    Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
@@ -736,20 +756,20 @@ static void setFlags_LOGIC ( IROp    op8,
                      vpanic("setFlags_LOGIC(x86)");
    }
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_SRC, mkU32(0)) );
-   stmt( IRStmt_Put( OFFB_CC_DST, widenUto32(mkexpr(dst1))) );
+   stmt( IRStmt_Put( OFFB_CC_RES, widenUto32(mkexpr(res))) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0)) );
 }
 
 
-/* For all shift and rotate cases, store the result value and the
-   result except shifted or rotated one bit less ("undershifted",
-   hence US).  And then only when the guard is non-zero. */
+/* For shift operations, we put in the result and the undershifted
+   result.  Except if the shift amount is zero, the thunk is left
+   unchanged. */
 
-static void setFlags_DSTus_DST1 ( IROp    op32,
-                                  IRTemp  dstUS,
-                                  IRTemp  dst1,
-                                  IRType  ty,
-                                  IRTemp  guard )
+static void setFlags_RES_RESus ( IROp    op32,
+                                 IRTemp  res,
+                                 IRTemp  resUS,
+                                 IRType  ty,
+                                 IRTemp  guard )
 {
    Int ccOp = ty==Ity_I8 ? 2 : (ty==Ity_I16 ? 1 : 0);
 
@@ -761,64 +781,71 @@ static void setFlags_DSTus_DST1 ( IROp    op32,
       case Iop_Sar32: ccOp = CC_OP_SARL - ccOp; break;
       case Iop_Shl32: ccOp = CC_OP_SHLL - ccOp; break;
       default:        ppIROp(op32);
-                      vpanic("setFlags_DSTus_DST1(x86)");
+                      vpanic("setFlags_RES_RESus(x86)");
    }
 
-   /* CC_SRC = undershifted %d after, CC_DST = %d afterwards */
+   /* RES contains the result, AUX contains the undershifted value. */
    stmt( IRStmt_Put( OFFB_CC_OP,
                      IRExpr_Mux0X( mkexpr(guard),
                                    IRExpr_Get(OFFB_CC_OP,Ity_I32),
                                    mkU32(ccOp))) );
-   stmt( IRStmt_Put( OFFB_CC_SRC, 
+   stmt( IRStmt_Put( OFFB_CC_RES,
                      IRExpr_Mux0X( mkexpr(guard),
-                                   IRExpr_Get(OFFB_CC_SRC,Ity_I32),
-                                   widenUto32(mkexpr(dstUS)))) );
-   stmt( IRStmt_Put( OFFB_CC_DST,
+                                   IRExpr_Get(OFFB_CC_RES,Ity_I32),
+                                   widenUto32(mkexpr(res)))) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, 
                      IRExpr_Mux0X( mkexpr(guard),
-                                   IRExpr_Get(OFFB_CC_DST,Ity_I32),
-                                   widenUto32(mkexpr(dst1)))) );
+                                   IRExpr_Get(OFFB_CC_AUX,Ity_I32),
+                                   widenUto32(mkexpr(resUS)))) );
 }
 
 
-/* For the inc/dec case, we store the result value and the former
-   value of the carry flag, which unfortunately we have to compute. */
+/* For the inc/dec case, we store in RES the result value and in AUX
+   the former value of the carry flag, which unfortunately we have to
+   compute. */
 
-static void setFlags_INC_DEC ( Bool inc, IRTemp dst, IRType ty )
+static void setFlags_INC_DEC ( Bool inc, IRTemp res, IRType ty )
 {
-   Int ccOp  = inc ? CC_OP_INCB : CC_OP_DECB;
+   Int ccOp = inc ? CC_OP_INCB : CC_OP_DECB;
    
    ccOp += ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
 
    /* This has to come first, because calculating the C flag 
       may require reading all three OFFB_CC fields. */
-   stmt( IRStmt_Put( OFFB_CC_SRC, mk_calculate_eflags_c()) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, mk_calculate_eflags_c()) );
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_DST, mkexpr(dst)) );
+   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(res)) );
 }
 
 
-/* For multiplies, just remember the two operands and a 
-   description of what kind of multiply. */
+/* For multiplies, RES is the xor of the upper and lower halves of the
+   result, and AUX is the lower half.  See long comment in gdefs.h for
+   explanation of the weirdness involving Xor. */
 
 static
-void setFlags_MUL ( IRType ty, IRTemp src1, IRTemp src2, UInt base_op )
+void setFlags_MUL ( IRType ty, IRTemp resHi, IRTemp resLo, UInt base_op )
 {
    switch (ty) {
    case Ity_I8:
       stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(base_op+0) ) );
-      stmt( IRStmt_Put( OFFB_CC_SRC, unop(Iop_8Uto32,mkexpr(src1)) ) );
-      stmt( IRStmt_Put( OFFB_CC_DST, unop(Iop_8Uto32,mkexpr(src2)) ) );
+      stmt( IRStmt_Put( OFFB_CC_AUX, unop(Iop_8Uto32,mkexpr(resLo)) ) );
+      stmt( IRStmt_Put( OFFB_CC_RES, 
+                        unop(Iop_8Uto32,
+                             binop(Iop_Xor8, mkexpr(resHi), mkexpr(resLo))) ));
       break;
    case Ity_I16:
       stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(base_op+1) ) );
-      stmt( IRStmt_Put( OFFB_CC_SRC, unop(Iop_16Uto32,mkexpr(src1)) ) );
-      stmt( IRStmt_Put( OFFB_CC_DST, unop(Iop_16Uto32,mkexpr(src2)) ) );
+      stmt( IRStmt_Put( OFFB_CC_AUX, unop(Iop_16Uto32,mkexpr(resLo)) ) );
+      stmt( IRStmt_Put( OFFB_CC_RES, 
+                        unop(Iop_16Uto32,
+                             binop(Iop_Xor16, mkexpr(resHi), mkexpr(resLo))) ));
       break;
    case Ity_I32:
       stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(base_op+2) ) );
-      stmt( IRStmt_Put( OFFB_CC_SRC, mkexpr(src1) ) );
-      stmt( IRStmt_Put( OFFB_CC_DST, mkexpr(src2) ) );
+      stmt( IRStmt_Put( OFFB_CC_AUX, mkexpr(resLo) ) );
+      stmt( IRStmt_Put( OFFB_CC_RES,
+                        binop(Iop_Xor32, mkexpr(resHi), mkexpr(resLo)) ));
       break;
    default:
       vpanic("setFlags_MUL(x86)");
@@ -870,12 +897,12 @@ static Condcode positiveIse_Condcode ( Condcode  cond,
 
 /* -------------- Helpers for ADD/SUB with carry. -------------- */
 
-/* Given ta1, ta2 and tdst, compute tdst = ADC(ta1,ta2) and set flags
+/* Given ta1, ta2 and tres, compute tres = ADC(ta1,ta2) and set flags
    appropriately.  Depends critically on the relative ordering of
    CC_OP_ADD{B,W,L} vs CC_OP_ADC{B,W,L}.
 */
 static void helper_ADC ( Int sz,
-                        IRTemp tdst, IRTemp ta1, IRTemp ta2 )
+                        IRTemp tres, IRTemp ta1, IRTemp ta2 )
 {
    UInt    thunkOp;
    IRExpr* thunkExpr;
@@ -888,7 +915,7 @@ static void helper_ADC ( Int sz,
                        mk_calculate_eflags_c(),
                       mkU32(1)) );
 
-   assign(tdst, binop(plus,
+   assign(tres, binop(plus,
                       binop(plus,mkexpr(ta1),mkexpr(ta2)),
                       narrowTo(ty,mkexpr(oldc))));
 
@@ -904,17 +931,17 @@ static void helper_ADC ( Int sz,
                     binop(Iop_Mul32, mkexpr(oldc), mkU32(3)));
 
    stmt( IRStmt_Put( OFFB_CC_OP,  thunkExpr ) );
-   stmt( IRStmt_Put( OFFB_CC_SRC, mkexpr(ta2) ) );
-   stmt( IRStmt_Put( OFFB_CC_DST, mkexpr(ta1) ) );
+   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(tres) ) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkexpr(ta2) ) );
 }
 
 
-/* Given ta1, ta2 and tdst, compute tdst = SBB(ta1,ta2) and set flags
+/* Given ta1, ta2 and tres, compute tres = SBB(ta1,ta2) and set flags
    appropriately.  Depends critically on the relative ordering of
    CC_OP_SUB{B,W,L} vs CC_OP_SBB{B,W,L}.
 */
 static void helper_SBB ( Int sz,
-                        IRTemp tdst, IRTemp ta1, IRTemp ta2 )
+                        IRTemp tres, IRTemp ta1, IRTemp ta2 )
 {
    UInt    thunkOp;
    IRExpr* thunkExpr;
@@ -927,7 +954,7 @@ static void helper_SBB ( Int sz,
                        mk_calculate_eflags_c(),
                       mkU32(1)) );
 
-   assign(tdst, binop(minus,
+   assign(tres, binop(minus,
                       binop(minus,mkexpr(ta1),mkexpr(ta2)),
                       narrowTo(ty,mkexpr(oldc))));
 
@@ -943,8 +970,8 @@ static void helper_SBB ( Int sz,
                     binop(Iop_Mul32, mkexpr(oldc), mkU32(3)));
 
    stmt( IRStmt_Put( OFFB_CC_OP,  thunkExpr ) );
-   stmt( IRStmt_Put( OFFB_CC_SRC, mkexpr(ta2) ) );
-   stmt( IRStmt_Put( OFFB_CC_DST, mkexpr(ta1) ) );
+   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(tres) ) );
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkexpr(ta2) ) );
 }
 
 
@@ -1762,8 +1789,8 @@ void codegen_XOR_reg_with_itself ( Int size, Int ge_reg )
    putIReg(size, ge_reg, mkU(ty,0));
    /* Flags: C,A,O=0, Z=1, S=0, P=1 */
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_SRC, mkU32(CC_MASK_Z|CC_MASK_P) ));
-   stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_RES, mkU32(CC_MASK_Z|CC_MASK_P) ));
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
    DIP("xor%c %s, %s\n", nameISize(size),
                          nameIReg(size,ge_reg), nameIReg(size,ge_reg) );
 }
@@ -1844,7 +1871,7 @@ UInt dis_op2_E_G ( UChar       sorb,
       } else {
          assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
          if (keep)
@@ -1871,7 +1898,7 @@ UInt dis_op2_E_G ( UChar       sorb,
       } else {
          assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
          if (keep)
@@ -1952,7 +1979,7 @@ UInt dis_op2_G_E ( UChar       sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
          if (keep)
@@ -1981,7 +2008,7 @@ UInt dis_op2_G_E ( UChar       sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
          if (keep)
@@ -2100,7 +2127,7 @@ UInt dis_op_imm_A ( Int    size,
    assign(src,  mkU(ty,lit));
    assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
    if (isAddSub(op8))
-      setFlags_ADD_SUB(op8, src, dst0, ty);
+      setFlags_RES_AUX(op8, dst1, src, ty);
    else
       setFlags_LOGIC(op8, dst1, ty);
 
@@ -2278,7 +2305,7 @@ UInt dis_Grp1 ( UChar sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
       }
@@ -2303,7 +2330,7 @@ UInt dis_Grp1 ( UChar sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_ADD_SUB(op8, src, dst0, ty);
+            setFlags_RES_AUX(op8, dst1, src, ty);
          else
             setFlags_LOGIC(op8, dst1, ty);
       }
@@ -2381,8 +2408,8 @@ UInt dis_Grp2 ( UChar  sorb,
       /* 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) ));
+      stmt( IRStmt_Put( OFFB_CC_RES, unop(Iop_64HIto32, mkexpr(r64)) ));
+      stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
    }
 
    if (isShift) {
@@ -2430,7 +2457,7 @@ UInt dis_Grp2 ( UChar  sorb,
                           mkU8(31))) );
 
       /* Build the flags thunk. */
-      setFlags_DSTus_DST1(op32, res32ss, res32, ty, shift_amt);
+      setFlags_RES_RESus(op32, res32, res32ss, ty, shift_amt);
 
       /* Narrow the result back down. */
       assign( dst1, narrowTo(ty, mkexpr(res32)) );
@@ -2498,18 +2525,18 @@ UInt dis_Grp2 ( UChar  sorb,
 
       assign(oldFlags, mk_calculate_eflags_all());
 
-      /* CC_DST is the rotated value.  CC_SRC is flags before. */
+      /* CC_RES is the rotated value.  CC_AUX is flags before. */
       stmt( IRStmt_Put( OFFB_CC_OP,
                         IRExpr_Mux0X( mkexpr(rot_amt32),
                                       IRExpr_Get(OFFB_CC_OP,Ity_I32),
                                       mkU32(ccOp))) );
-      stmt( IRStmt_Put( OFFB_CC_DST
+      stmt( IRStmt_Put( OFFB_CC_RES
                         IRExpr_Mux0X( mkexpr(rot_amt32),
-                                      IRExpr_Get(OFFB_CC_DST,Ity_I32),
+                                      IRExpr_Get(OFFB_CC_RES,Ity_I32),
                                       widenUto32(mkexpr(dst1)))) );
-      stmt( IRStmt_Put( OFFB_CC_SRC
+      stmt( IRStmt_Put( OFFB_CC_AUX
                         IRExpr_Mux0X( mkexpr(rot_amt32),
-                                      IRExpr_Get(OFFB_CC_SRC,Ity_I32),
+                                      IRExpr_Get(OFFB_CC_AUX,Ity_I32),
                                       mkexpr(oldFlags))) );
    } /* if (isRotate) */
 
@@ -2669,30 +2696,42 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
    switch (ty) {
       case Ity_I32: {
          IRTemp res64   = newTemp(Ity_I64);
+         IRTemp resHi   = newTemp(Ity_I32);
+         IRTemp resLo   = newTemp(Ity_I32);
          IROp   mulOp   = syned ? Iop_MullS32 : Iop_MullU32;
          UInt   tBaseOp = syned ? CC_OP_SMULB : CC_OP_UMULB;
-         setFlags_MUL ( Ity_I32, t1, tmp, tBaseOp );
          assign( res64, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
-         putIReg(4, R_EDX, unop(Iop_64HIto32,mkexpr(res64)));
-         putIReg(4, R_EAX, unop(Iop_64to32,mkexpr(res64)));
+         assign( resHi, unop(Iop_64HIto32,mkexpr(res64)));
+         assign( resLo, unop(Iop_64to32,mkexpr(res64)));
+         setFlags_MUL ( Ity_I32, resHi, resLo, tBaseOp );
+         putIReg(4, R_EDX, mkexpr(resHi));
+         putIReg(4, R_EAX, mkexpr(resLo));
          break;
       }
       case Ity_I16: {
          IRTemp res32   = newTemp(Ity_I32);
+         IRTemp resHi   = newTemp(Ity_I16);
+         IRTemp resLo   = newTemp(Ity_I16);
          IROp   mulOp   = syned ? Iop_MullS16 : Iop_MullU16;
          UInt   tBaseOp = syned ? CC_OP_SMULB : CC_OP_UMULB;
-         setFlags_MUL ( Ity_I16, t1, tmp, tBaseOp );
          assign( res32, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
-         putIReg(2, R_EDX, unop(Iop_32HIto16,mkexpr(res32)));
-         putIReg(2, R_EAX, unop(Iop_32to16,mkexpr(res32)));
+         assign( resHi, unop(Iop_32HIto16,mkexpr(res32)));
+         assign( resLo, unop(Iop_32to16,mkexpr(res32)));
+         setFlags_MUL ( Ity_I16, resHi, resLo, tBaseOp );
+         putIReg(2, R_EDX, mkexpr(resHi));
+         putIReg(2, R_EAX, mkexpr(resLo));
          break;
       }
       case Ity_I8: {
          IRTemp res16   = newTemp(Ity_I16);
+         IRTemp resHi   = newTemp(Ity_I8);
+         IRTemp resLo   = newTemp(Ity_I8);
          IROp   mulOp   = syned ? Iop_MullS8 : Iop_MullU8;
          UInt   tBaseOp = syned ? CC_OP_SMULB : CC_OP_UMULB;
-         setFlags_MUL ( Ity_I8, t1, tmp, tBaseOp );
          assign( res16, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
+         assign( resHi, unop(Iop_16HIto8,mkexpr(res16)));
+         assign( resLo, unop(Iop_16to8,mkexpr(res16)));
+         setFlags_MUL ( Ity_I8, resHi, resLo, tBaseOp );
          putIReg(2, R_EAX, mkexpr(res16));
          break;
       }
@@ -2745,7 +2784,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta )
            assign(dst0, mkU(ty,0));
             assign(src,  getIReg(sz,eregOfRM(modrm)));
            assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src)));
-            setFlags_ADD_SUB(Iop_Sub8, src, dst0, ty);
+            setFlags_RES_AUX(Iop_Sub8, dst1, src, ty);
            putIReg(sz, eregOfRM(modrm), mkexpr(dst1));
             DIP("neg%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm)));
             break;
@@ -2805,7 +2844,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta )
            assign(dst0, mkU(ty,0));
             assign(src,  mkexpr(t1));
            assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src)));
-            setFlags_ADD_SUB(Iop_Sub8, src, dst0, ty);
+            setFlags_RES_AUX(Iop_Sub8, dst1, src, ty);
            storeLE( mkexpr(addr), mkexpr(dst1) );
             DIP("neg%c %s\n", nameISize(sz), dis_buf);
             break;
@@ -3087,6 +3126,7 @@ void dis_CMPS ( Int sz, IRTemp t_inc )
    IRType ty  = szToITy(sz);
    IRTemp tdv = newTemp(ty);      /* (EDI) */
    IRTemp tsv = newTemp(ty);      /* (ESI) */
+   IRTemp res = newTemp(ty);
    IRTemp td  = newTemp(Ity_I32); /*  EDI  */
    IRTemp ts  = newTemp(Ity_I32); /*  ESI  */
 
@@ -3104,7 +3144,8 @@ void dis_CMPS ( Int sz, IRTemp t_inc )
 
    //uInstr2(cb, SUB,  sz, TempReg, tdv,   TempReg, tsv); 
    //setFlagsFromUOpcode(cb, SUB);
-   setFlags_ADD_SUB ( Iop_Sub8, tdv, tsv, ty );
+   assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(tsv), mkexpr(tdv)) );
+   setFlags_RES_AUX ( Iop_Sub8, res, tdv, ty );
 
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, ts);
@@ -3123,6 +3164,7 @@ void dis_SCAS ( Int sz, IRTemp t_inc )
    IRTemp ta  = newTemp(ty);       /*  EAX  */
    IRTemp td  = newTemp(Ity_I32);  /*  EDI  */
    IRTemp tdv = newTemp(ty);       /* (EDI) */
+   IRTemp res = newTemp(ty);
 
    //uInstr2(cb, GET,  sz, ArchReg, R_EAX, TempReg, ta);
    assign( ta, getIReg(sz, R_EAX) );
@@ -3135,7 +3177,8 @@ void dis_SCAS ( Int sz, IRTemp t_inc )
 
    //uInstr2(cb, SUB,  sz, TempReg, tdv,   TempReg, ta);
    //setFlagsFromUOpcode(cb, SUB);
-   setFlags_ADD_SUB( Iop_Sub8, tdv, ta, ty );
+   assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(ta), mkexpr(tdv)) );
+   setFlags_RES_AUX ( Iop_Sub8, res, tdv, ty );
 
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
    //uInstr2(cb, PUT,   4, TempReg, td,    ArchReg, R_EDI);
@@ -3196,31 +3239,36 @@ UInt dis_mul_E_G ( UChar       sorb,
    IRType ty = szToITy(size);
    IRTemp te = newTemp(ty);
    IRTemp tg = newTemp(ty);
+   IRTemp resHi = newTemp(ty);
+   IRTemp resLo = newTemp(ty);
+   IRTemp res2L = newTemp(doubleLengthType(ty));
 
    vassert(syned);
 
+   assign( tg, getIReg(size, gregOfRM(rm)) );
    if (epartIsReg(rm)) {
-      assign( tg, getIReg(size, gregOfRM(rm)) );
       assign( te, getIReg(size, eregOfRM(rm)) );
-      setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
-      putIReg(size, gregOfRM(rm), 
-             binop(mkSizedOp(ty,Iop_Mul8),
-                   mkexpr(te), mkexpr(tg)));
+   } else {
+      IRTemp addr = disAMode( &alen, sorb, delta0, dis_buf );
+      assign( te, loadLE(ty,mkexpr(addr)) );
+   }
+
+   assign( res2L, binop( mkSizedOp(ty, syned ? Iop_MullS8 : Iop_MullU8),
+                         mkexpr(te), mkexpr(tg) ));
+   assign( resHi, unop( mkSizedOp(ty, Iop_16HIto8), mkexpr(res2L) ));
+   assign( resLo, unop( mkSizedOp(ty, Iop_16to8), mkexpr(res2L) ));
+
+   setFlags_MUL ( ty, resHi, resLo, syned ? CC_OP_SMULB : CC_OP_UMULB );
 
+   putIReg(size, gregOfRM(rm), mkexpr(resLo) );
+
+   if (epartIsReg(rm)) {
       DIP("%smul%c %s, %s\n", syned ? "i" : "",
                               nameISize(size), 
                               nameIReg(size,eregOfRM(rm)),
                               nameIReg(size,gregOfRM(rm)));
       return 1+delta0;
    } else {
-      IRTemp addr = disAMode( &alen, sorb, delta0, dis_buf );
-      assign( tg, getIReg(size, gregOfRM(rm)) );
-      assign( te, loadLE(ty,mkexpr(addr)) );
-      setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
-      putIReg(size, gregOfRM(rm), 
-             binop(mkSizedOp(ty,Iop_Mul8),
-                   mkexpr(te), mkexpr(tg)));
-
       DIP("%smul%c %s, %s\n", syned ? "i" : "",
                               nameISize(size), 
                               dis_buf, nameIReg(size,gregOfRM(rm)));
@@ -3242,6 +3290,9 @@ UInt dis_imul_I_E_G ( UChar       sorb,
    IRType ty = szToITy(size);
    IRTemp te = newTemp(ty);
    IRTemp tl = newTemp(ty);
+   IRTemp resHi = newTemp(ty);
+   IRTemp resLo = newTemp(ty);
+   IRTemp res2L = newTemp(doubleLengthType(ty));
 
    vassert(size == 1 || size == 2 || size == 4);
 
@@ -3260,16 +3311,21 @@ UInt dis_imul_I_E_G ( UChar       sorb,
    if (size == 2) d32 &= 0xFFFF;
 
    assign(tl, mkU(ty,d32));
-   setFlags_MUL ( ty, te, tl, CC_OP_SMULB );
-   putIReg(size, gregOfRM(rm), 
-           binop(mkSizedOp(ty,Iop_Mul8),
-                 mkexpr(te), mkexpr(tl)));
+
+   assign( res2L, binop( mkSizedOp(ty, Iop_MullS8),
+                         mkexpr(te), mkexpr(tl) ));
+   assign( resHi, unop( mkSizedOp(ty, Iop_16HIto8), mkexpr(res2L) ));
+   assign( resLo, unop( mkSizedOp(ty, Iop_16to8), mkexpr(res2L) ));
+
+   setFlags_MUL ( ty, resHi, resLo, CC_OP_SMULB );
+
+   putIReg(size, gregOfRM(rm), mkexpr(resLo));
 
    DIP("imul %d, %s, %s\n", d32, 
        ( epartIsReg(rm) ? nameIReg(size,eregOfRM(rm)) : dis_buf ),
        nameIReg(size,gregOfRM(rm)) );
    return delta;
-}   
+}
 
 
 /*------------------------------------------------------------*/
@@ -3539,8 +3595,8 @@ static void fp_do_ucomi_ST0_STi ( UInt i, Bool pop_after )
       documentation implies A and S are unchanged. 
    */
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
-   stmt( IRStmt_Put( OFFB_CC_SRC,
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_RES,
                      binop( Iop_And32,
                             binop(Iop_CmpF64, get_ST(0), get_ST(i)),
                             mkU32(0x45)
@@ -4901,8 +4957,8 @@ UInt dis_SHLRD_Gv_Ev ( UChar sorb,
                             binop(Iop_Sub8, mkexpr(tmpSH), mkU8(1) ),
                             mask))) );
 
-   setFlags_DSTus_DST1 ( left_shift ? Iop_Shl32 : Iop_Sar32,
-                         tmpSubSh, tmpRes, ty, tmpSH );
+   setFlags_RES_RESus ( left_shift ? Iop_Shl32 : Iop_Sar32,
+                        tmpRes, tmpSubSh, ty, tmpSH );
 
    /* Put result back. */
 
@@ -5036,9 +5092,9 @@ UInt dis_bt_G_E ( UChar sorb, Int sz, UInt delta, BtOp op )
    /* Side effect done; now get selected bit into Carry flag */
       /* Flags: C=selected bit, O,S,Z,A,P undefined, so are set to zero. */
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
    stmt( IRStmt_Put( 
-            OFFB_CC_SRC,
+            OFFB_CC_RES,
             binop(Iop_And32,
                   binop(Iop_Shr32, 
                         unop(Iop_8Uto32, mkexpr(t_fetched)),
@@ -5107,9 +5163,9 @@ UInt dis_bs_E_G ( UChar sorb, Int sz, UInt delta, Bool fwds )
    /* Flags: Z is 1 iff source value is zero.  All others 
       are undefined -- we force them to zero. */
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
    stmt( IRStmt_Put( 
-            OFFB_CC_SRC,
+            OFFB_CC_RES,
             IRExpr_Mux0X( mkexpr(src8),
                           /* src==0 */
                           mkU32(CC_MASK_Z),
@@ -5194,8 +5250,8 @@ void codegen_SAHF ( void )
    IRTemp oldflags   = newTemp(Ity_I32);
    assign( oldflags, mk_calculate_eflags_all() );
    stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
-   stmt( IRStmt_Put( OFFB_CC_SRC,
+   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_RES,
          binop(Iop_Or32,
                binop(Iop_And32, mkexpr(oldflags), mkU32(CC_MASK_O)),
                binop(Iop_And32, 
@@ -5238,6 +5294,7 @@ UInt dis_cmpxchg_G_E ( UChar       sorb,
    IRType ty    = szToITy(size);
    IRTemp acc   = newTemp(ty);
    IRTemp src   = newTemp(ty);
+   IRTemp res   = newTemp(ty);
    IRTemp dest  = newTemp(ty);
    IRTemp dest2 = newTemp(ty);
    IRTemp acc2  = newTemp(ty);
@@ -5261,7 +5318,8 @@ UInt dis_cmpxchg_G_E ( UChar       sorb,
 
    assign( src, getIReg(size, gregOfRM(rm)) );
    assign( acc, getIReg(size, R_EAX) );
-   setFlags_ADD_SUB(Iop_Sub8, dest, acc, ty);
+   assign( res, binop( mkSizedOp(ty,Iop_Sub8), mkexpr(acc), mkexpr(dest) ));
+   setFlags_RES_AUX(Iop_Sub8, res, dest, ty);
    assign( cond8, unop(Iop_1Uto8, mk_calculate_condition(CondZ)) );
    assign( dest2, IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(src)) );
    assign( acc2,  IRExpr_Mux0X(mkexpr(cond8), mkexpr(dest), mkexpr(acc)) );
@@ -5445,8 +5503,8 @@ UInt dis_xadd_G_E ( UChar sorb, Int sz, UInt delta0 )
       IRTemp addr = disAMode ( &len, sorb, delta0, dis_buf );
       assign( tmpd,  loadLE(ty, mkexpr(addr)) );
       assign( tmpt0, getIReg(sz, gregOfRM(rm)) );
-      setFlags_ADD_SUB( Iop_Add8, tmpt0, tmpd, ty );
       assign( tmpt1, binop(mkSizedOp(ty,Iop_Add8), mkexpr(tmpd), mkexpr(tmpt0)) );
+      setFlags_RES_AUX( Iop_Add8, tmpt1, tmpt0, ty );
       storeLE( mkexpr(addr), mkexpr(tmpt1) );
       putIReg(sz, gregOfRM(rm), mkexpr(tmpd));
       DIP("xadd%c %s, %s\n",
@@ -8242,8 +8300,8 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       /* t1 is the flag word.  Mask out everything except OSZACP and 
         set the flags thunk to CC_OP_COPY. */
       stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-      stmt( IRStmt_Put( OFFB_CC_DST, mkU32(0) ));
-      stmt( IRStmt_Put( OFFB_CC_SRC
+      stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
+      stmt( IRStmt_Put( OFFB_CC_RES
                        binop(Iop_And32,
                              mkexpr(t1), 
                              mkU32( CC_MASK_C | CC_MASK_P | CC_MASK_A 
index be34d91b901942987f8a43f37660a12aeb7da85a..0944ec1532ad0a6f54fdeb0771ce32d9346cae18 100644 (file)
@@ -98,7 +98,7 @@ extern void* LibVEX_Alloc ( Int nbytes );
 
 /* The max number of guest state chunks which we can describe as
    always defined (for the benefit of Memcheck). */
-#define VEXGLO_N_ALWAYSDEFD  14
+#define VEXGLO_N_ALWAYSDEFD  15
 
 typedef
    struct {
index ababaad35834fa93e9f88203299dc87568272270..43f98218fd9a401f135cdbea6a0e7ef18e5875d5 100644 (file)
@@ -83,8 +83,8 @@ typedef
       UInt  guest_EDI;
       /* 3-word thunk used to calculate O S Z A C P flags. */
       UInt  guest_CC_OP;
-      UInt  guest_CC_SRC;
-      UInt  guest_CC_DST;
+      UInt  guest_CC_RES;
+      UInt  guest_CC_AUX;
       /* The D flag is stored here, as either -1 or +1 */
       UInt  guest_DFLAG;
       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */