]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86 guest: majorly rehash eflags thunk scheme for a second time. See
authorJulian Seward <jseward@acm.org>
Mon, 8 Nov 2004 13:14:06 +0000 (13:14 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 8 Nov 2004 13:14:06 +0000 (13:14 +0000)
detailed comment in priv/guest-x86/gdefs.h.  In short we move to a
4-word thunk so as to be able to present Memcheck with the data
dependencies we want, and at the same time allow iropt to easily
optimise away most of the helper calls that evaluate the thunk.
Hopefully this is the last change.

Comment in priv/guest-x86/gdefs.h also explains properly the
relationship between the thunk arrangements and how we expect Memcheck
to behave with respect to definedness of flags.

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

VEX/head20041019/coregrind/vg_translate.c
VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/pub/libvex_guest_x86.h

index 7178fb62d7d1a835cb7e6b8950e3f5211e2458fd..1cc0c3fbc6d386cf3a37833f0eaf57816d80a610 100644 (file)
@@ -1661,8 +1661,8 @@ Bool VG_(translate) ( ThreadId tid, Addr orig_addr,
    if (redir != orig_addr && VG_(clo_verbosity) >= 2) {
       Char name1[64] = "";
       Char name2[64] = "";
-      VG_(get_fnname_if_entry)(orig_addr, name1, 64);
-      VG_(get_fnname_if_entry)(redir, name2, 64);
+      VG_(get_fnname_w_offset)(orig_addr, name1, 64);
+      VG_(get_fnname_w_offset)(redir, name2, 64);
       VG_(message)(Vg_UserMsg, 
                    "TRANSLATE: %p (%s) redirected to %p (%s)",
                    orig_addr, name1,
@@ -1702,7 +1702,7 @@ Bool VG_(translate) ( ThreadId tid, Addr orig_addr,
    /* If doing any code printing, print a basic block start marker */
    if (VG_(clo_trace_codegen)) {
       Char fnname[64] = "";
-      VG_(get_fnname_if_entry)(orig_addr, fnname, 64);
+      VG_(get_fnname_w_offset)(orig_addr, fnname, 64);
       VG_(printf)(
               "==== BB %d %s(%p) approx BBs exec'd %llu ====\n",
               VG_(get_bbs_translated)(), fnname, orig_addr, 
index 84782fe0e618edead01c0580b664bb2e8c34b096..893849628e2eeae7ac26fdf803381f2972008ed1 100644 (file)
@@ -46,16 +46,27 @@ VexGuestLayout x86guest_layout;
 /*---------------------------------------------------------*/
 
 /* --- CLEAN HELPERS --- */
-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_eflags_all ( UInt cc_op, 
+                                    UInt cc_dep1, UInt cc_dep2, UInt cc_ndep );
+
+extern UInt  calculate_eflags_c   ( UInt cc_op, 
+                                    UInt cc_dep1, UInt cc_dep2, UInt cc_ndep );
+
 extern UInt  calculate_condition  ( UInt/*Condcode*/ cond, 
-                                    UInt cc_op, UInt cc_res, UInt cc_aux );
+                                    UInt cc_op, 
+                                    UInt cc_dep1, UInt cc_dep2, UInt cc_ndep );
+
 extern UInt  calculate_FXAM ( UInt tag, ULong dbl );
+
 extern ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
 
 /* --- DIRTY HELPERS --- */
+
 extern ULong loadF80le  ( UInt );
+
 extern void  storeF80le ( UInt, ULong );
+
 extern void  dirtyhelper_CPUID ( VexGuestX86State* );
 
 
@@ -84,84 +95,177 @@ extern void  dirtyhelper_CPUID ( VexGuestX86State* );
 #define FC_MASK_C1   (1 << 9)
 #define FC_MASK_C0   (1 << 8)
 
-/* %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.  
+/* %EFLAGS thunk descriptors.  A four-word thunk is used to record
+   details of the most recent flag-setting operation, so the flags can
+   be computed later if needed.  It is possible to do this a little
+   more efficiently using a 3-word thunk, but that makes it impossible
+   to describe the flag data dependencies sufficiently accurately for
+   Memcheck.  Hence 4 words are used, with minimal loss of efficiency.
+
+   The four words are:
+
+      CC_OP, which describes the operation.
+
+      CC_DEP1 and CC_DEP2.  These are arguments to the operation.
+         We want Memcheck to believe that the resulting flags are
+         data-dependent on both CC_DEP1 and CC_DEP2, hence the 
+         name DEP.
+
+      CC_NDEP.  This is a 3rd argument to the operation which is
+         sometimes needed.  We arrange things so that Memcheck does
+         not believe the resulting flags are data-dependent on CC_NDEP
+         ("not dependent").
+
+   To make Memcheck believe that (the definedness of) the encoded
+   flags depends only on (the definedness of) CC_DEP1 and CC_DEP2
+   requires two things:
+
+   (1) In the guest state layout info (x86guest_layout), CC_OP and
+       CC_NDEP are marked as always defined.
+
+   (2) When passing the thunk components to an evaluation function
+       (calculate_condition, calculate_eflags, calculate_eflags_c) the
+       IRCallee's mcx_mask must be set so as to exclude from
+       consideration all passed args except CC_DEP1 and CC_DEP2.
+
+   Strictly speaking only (2) is necessary for correctness.  However,
+   (1) helps efficiency in that since (2) means we never ask about the
+   definedness of CC_OP or CC_NDEP, we may as well not even bother to
+   track their definedness.
+
+   When building the thunk, it is always necessary to write words into
+   CC_DEP1 and CC_DEP2, even if those args are not used given the
+   CC_OP field (eg, CC_DEP2 is not used if CC_OP is CC_LOGIC1/2/4).
+   This is important because otherwise Memcheck could give false
+   positives as it does not understand the relationship between the
+   CC_OP field and CC_DEP1 and CC_DEP2, and so believes that the 
+   definedness of the stored flags always depends on both CC_DEP1 and
+   CC_DEP2.
+
+   However, it is only necessary to set CC_NDEP when the CC_OP value
+   requires it, because Memcheck ignores CC_NDEP, and the evaluation
+   functions do understand the CC_OP fields and will only examine
+   CC_NDEP for suitable values of CC_OP.
+
+   A summary of the field usages is:
+
+   Operation          DEP1               DEP2               NDEP
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+   add/sub/mul        first arg          second arg         unused
+
+   adc/sbb            first arg          (second arg)
+                                         XOR old_carry      old_carry
+
+   and/or/xor         result             zero               unused
+
+   inc/dec            result             zero               old_carry
+
+   shl/shr/sar        result             subshifted-        unused
+                                         result
+
+   rol/ror            result             zero               old_flags
+
+   copy               old_flags          zero               unused.
+
+
+   Therefore Memcheck will believe the following:
+
+   * add/sub/mul -- definedness of result flags depends on definedness
+     of both args.
+
+   * adc/sbb -- definedness of result flags depends on definedness of
+     both args and definedness of the old C flag.  Because only two
+     DEP fields are available, the old C flag is XOR'd into the second
+     arg so that Memcheck sees the data dependency on it.  That means
+     the NDEP field must contain a second copy of the old C flag
+     so that the evaluation functions can correctly recover the second
+     arg.
+
+   * and/or/xor are straightforward -- definedness of result flags
+     depends on definedness of result value.
+
+   * inc/dec -- definedness of result flags depends only on
+     definedness of result.  This isn't really true -- it also depends
+     on the old C flag.  However, we don't want Memcheck to see that,
+     and so the old C flag must be passed in NDEP and not in DEP2.
+     It's inconceivable that a compiler would generate code that puts
+     the C flag in an undefined state, then does an inc/dec, which
+     leaves C unchanged, and then makes a conditional jump/move based
+     on C.  So our fiction seems a good approximation.
+
+   * shl/shr/sar -- straightforward, again, definedness of result
+     flags depends on definedness of result value.  The subshifted
+     value (value shifted one less) is also needed, but its
+     definedness is the same as the definedness of the shifted value.
+
+   * rol/ror -- these only set O and C, and leave A Z C P alone.
+     However it seems prudent (as per inc/dec) to say the definedness
+     of all resulting flags depends on the definedness of the result,
+     hence the old flags must go in as NDEP and not DEP2.
+
+   * rcl/rcr are too difficult to do in-line, and so are done by a
+     helper function.  They are not part of this scheme.  The helper
+     function takes the value to be rotated, the rotate amount and the
+     old flags, and returns the new flags and the rotated value.
+     Since the helper's mcx_mask does not have any set bits, Memcheck
+     will lazily propagate undefinedness from any of the 3 args into 
+     both results (flags and actual value).
 */
 enum {
-    CC_OP_COPY,    /* RES = current flags, AUX = 0, do nothing */
+    CC_OP_COPY,    /* DEP1 = current flags, DEP2 = 0, NDEP = unused */
+                   /* just copy DEP1 to output */
 
-    CC_OP_ADDB,    /* RES = argL+argR, AUX = argR */
-    CC_OP_ADDW,
+    CC_OP_ADDB,    /* 1 */
+    CC_OP_ADDW,    /* 2 DEP1 = argL, DEP2 = argR, NDEP = unused */
     CC_OP_ADDL,    /* 3 */
 
-    CC_OP_ADCB,    /* RES = argL+argR, AUX = argR */
-    CC_OP_ADCW,
-    CC_OP_ADCL,    /* 6 */
+    CC_OP_SUBB,    /* 4 */
+    CC_OP_SUBW,    /* 5 DEP1 = argL, DEP2 = argR, NDEP = unused */
+    CC_OP_SUBL,    /* 6 */
 
-    CC_OP_SUBB,    /* RES = argL-argR, AUX = argR */
-    CC_OP_SUBW,
-    CC_OP_SUBL,    /* 9 */
+    CC_OP_ADCB,    /* 7 */
+    CC_OP_ADCW,    /* 8 DEP1 = argL, DEP2 = argR ^ oldCarry, NDEP = oldCarry */
+    CC_OP_ADCL,    /* 9 */
 
-    CC_OP_SBBB,    /* RES = argL-argR, AUX = argR */
-    CC_OP_SBBW,
+    CC_OP_SBBB,    /* 10 */
+    CC_OP_SBBW,    /* 11 DEP1 = argL, DEP2 = argR ^ oldCarry, NDEP = oldCarry */
     CC_OP_SBBL,    /* 12 */
 
-    CC_OP_LOGICB,  /* RES = and/or/xor(argL,argR), AUX = 0 */
-    CC_OP_LOGICW,
+    CC_OP_LOGICB,  /* 13 */
+    CC_OP_LOGICW,  /* 14 DEP1 = result, DEP2 = 0, NDEP = unused */
     CC_OP_LOGICL,  /* 15 */
 
-    CC_OP_INCB,    /* RES = arg+1, AUX = old C flag (0 or 1) */
-    CC_OP_INCW,
+    CC_OP_INCB,    /* 16 */
+    CC_OP_INCW,    /* 17 DEP1 = result, DEP2 = 0, NDEP = oldCarry (0 or 1) */
     CC_OP_INCL,    /* 18 */
 
-    CC_OP_DECB,    /* RES = arg-1, AUX = old C flag (0 or 1) */
-    CC_OP_DECW,
+    CC_OP_DECB,    /* 19 */
+    CC_OP_DECW,    /* 20 DEP1 = result, DEP2 = 0, NDEP = oldCarry (0 or 1) */
     CC_OP_DECL,    /* 21 */
 
-    CC_OP_SHLB,    /* RES = res, AUX = res' */
-    CC_OP_SHLW,    /* where res' is like res but shifted one bit less */
+    CC_OP_SHLB,    /* 22 DEP1 = res, DEP2 = res', NDEP = unused */
+    CC_OP_SHLW,    /* 23 where res' is like res but shifted one bit less */
     CC_OP_SHLL,    /* 24 */
 
-    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_SHRB,    /* 25 DEP1 = res, DEP2 = res', NDEP = unused */
+    CC_OP_SHRW,    /* 26 where res' is like res but shifted one bit less */
+    CC_OP_SHRL,    /* 27 */
 
-    CC_OP_ROLB,    /* RES = res, AUX = old flags */
-    CC_OP_ROLW,
+    CC_OP_ROLB,    /* 28 */
+    CC_OP_ROLW,    /* 29 DEP1 = res, DEP2 = 0, NDEP = old flags */
     CC_OP_ROLL,    /* 30 */
 
-    CC_OP_RORB,    /* RES = res, AUX = old flags */
-    CC_OP_RORW,
+    CC_OP_RORB,    /* 31 */
+    CC_OP_RORW,    /* 32 DEP1 = res, DEP2 = 0, NDEP = old flags */
     CC_OP_RORL,    /* 33 */
 
-    CC_OP_UMULB,   /* RES = hiHalf(result) ^ loHalf(result) */
-    CC_OP_UMULW,   /* AUX = loHalf(result) */
+    CC_OP_UMULB,   /* 34 */
+    CC_OP_UMULW,   /* 35 DEP1 = argL, DEP2 = argR, NDEP = unused */
     CC_OP_UMULL,   /* 36 */
 
-    CC_OP_SMULB,   /* RES = hiHalf(result) ^ loHalf(result) */
-    CC_OP_SMULW,   /* AUX = loHalf(result) */
+    CC_OP_SMULB,   /* 37 */
+    CC_OP_SMULW,   /* 38 DEP1 = argL, DEP2 = argR, NDEP = unused */
     CC_OP_SMULL,   /* 39 */
 
     CC_OP_NUMBER
index 2126a7ca6cc26a1a5bd54a11b2e691d9c594d97f..84f52bf52a0932a6804e21b92d1d4ba7ef43d930 100644 (file)
@@ -87,14 +87,16 @@ inline static Int lshift ( Int x, Int n )
                        : (__data_bits==16 ? 0xFFFF             \
                                           : 0xFFFFFFFF);       \
    /* const */ UInt SIGN_MASK = 1 << (__data_bits - 1);                \
-   /* const */ UInt CC_RES = cc_res_formal;                    \
-   /* const */ UInt CC_AUX = cc_aux_formal;                    \
-   /* Three bogus assignments, which hopefully gcc can    */   \
+   /* const */ UInt CC_DEP1 = cc_dep1_formal;                  \
+   /* const */ UInt CC_DEP2 = cc_dep2_formal;                  \
+   /* const */ UInt CC_NDEP = cc_ndep_formal;                  \
+   /* Four 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_AUX = CC_AUX;
+   CC_DEP2 = CC_DEP2;                                          \
+   CC_NDEP = CC_NDEP;
 
 
 /*-------------------------------------------------------------*/
@@ -104,9 +106,9 @@ inline static Int lshift ( Int x, Int n )
    PREAMBLE(DATA_BITS);                                                \
    Int cf, pf, af, zf, sf, of;                                 \
    Int argL, argR, res;                                                \
-   argL = CC_RES - CC_AUX;                                     \
-   argR = CC_AUX;                                              \
-   res  = CC_RES;                                              \
+   argL = CC_DEP1;                                             \
+   argR = CC_DEP2;                                             \
+   res  = argL + argR;                                         \
    cf = (DATA_UTYPE)res < (DATA_UTYPE)argL;                    \
    pf = parity_table[(UChar)res];                              \
    af = (res ^ argL ^ argR) & 0x10;                            \
@@ -119,41 +121,45 @@ inline static Int lshift ( Int x, Int n )
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE)                      \
+#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    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;                   \
+   argL = CC_DEP1;                                             \
+   argR = CC_DEP2;                                             \
+   res  = argL - argR;                                         \
+   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 ^ -1) & (argL ^ res),              \
-                12 - DATA_BITS) & CC_MASK_O;                   \
+   of = lshift((argL ^ argR) & (argL ^ res),                   \
+               12 - DATA_BITS) & CC_MASK_O;                    \
    return cf | pf | af | zf | sf | of;                         \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_SUB(DATA_BITS,DATA_UTYPE)                      \
+#define ACTIONS_ADC(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    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;                   \
+   Int argL, argR, oldC, res;                                  \
+   oldC = CC_NDEP & CC_MASK_C;                                 \
+   argL = CC_DEP1;                                             \
+   argR = CC_DEP2 ^ oldC;                                      \
+   res  = (argL + argR) + oldC;                                        \
+   if (oldC)                                                   \
+      cf = (DATA_UTYPE)res <= (DATA_UTYPE)argL;                        \
+   else                                                                \
+      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) & (argL ^ res),                   \
-               12 - DATA_BITS) & CC_MASK_O;                    \
+   of = lshift((argL ^ argR ^ -1) & (argL ^ res),              \
+                12 - DATA_BITS) & CC_MASK_O;                   \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -163,11 +169,15 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    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;                  \
+   Int argL, argR, oldC, res;                                  \
+   oldC = CC_NDEP & CC_MASK_C;                                 \
+   argL = CC_DEP1;                                             \
+   argR = CC_DEP2 ^ oldC;                                      \
+   res  = (argL - argR) - oldC;                                        \
+   if (oldC)                                                   \
+      cf = (DATA_UTYPE)argL <= (DATA_UTYPE)argR;               \
+   else                                                                \
+      cf = (DATA_UTYPE)argL < (DATA_UTYPE)argR;                        \
    pf = parity_table[(UChar)res];                              \
    af = (res ^ argL ^ argR) & 0x10;                            \
    zf = ((DATA_UTYPE)res == 0) << 6;                           \
@@ -184,10 +194,10 @@ inline static Int lshift ( Int x, Int n )
    PREAMBLE(DATA_BITS);                                                \
    Int cf, pf, af, zf, sf, of;                                 \
    cf = 0;                                                     \
-   pf = parity_table[(UChar)CC_RES];                           \
+   pf = parity_table[(UChar)CC_DEP1];                          \
    af = 0;                                                     \
-   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
-   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;                       \
+   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;                 \
    of = 0;                                                     \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -198,15 +208,16 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    Int cf, pf, af, zf, sf, of;                                 \
-   Int argL, argR;                                             \
-   argL = CC_RES - 1;                                          \
+   Int argL, argR, res;                                                \
+   res  = CC_DEP1;                                             \
+   argL = res - 1;                                             \
    argR = 1;                                                   \
-   cf = CC_AUX & CC_MASK_C;                                    \
-   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;             \
+   cf = CC_NDEP & CC_MASK_C;                                   \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = ((res & DATA_MASK) == SIGN_MASK) << 11;                        \
    return cf | pf | af | zf | sf | of;                         \
 }
 
@@ -216,15 +227,16 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    Int cf, pf, af, zf, sf, of;                                 \
-   Int argL, argR;                                             \
-   argL = CC_RES + 1;                                          \
+   Int argL, argR, res;                                                \
+   res  = CC_DEP1;                                             \
+   argL = res + 1;                                             \
    argR = 1;                                                   \
-   cf = CC_AUX & CC_MASK_C;                                    \
-   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)                                  \
+   cf = CC_NDEP & CC_MASK_C;                                   \
+   pf = parity_table[(UChar)res];                              \
+   af = (res ^ argL ^ argR) & 0x10;                            \
+   zf = ((DATA_UTYPE)res == 0) << 6;                           \
+   sf = lshift(res, 8 - DATA_BITS) & 0x80;                     \
+   of = ((res & DATA_MASK)                                     \
         == ((UInt)SIGN_MASK - 1)) << 11;                       \
    return cf | pf | af | zf | sf | of;                         \
 }
@@ -235,105 +247,105 @@ inline static Int lshift ( Int x, Int n )
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    Int cf, pf, af, zf, sf, of;                                 \
-   cf = (CC_AUX >> (DATA_BITS - 1)) & CC_MASK_C;               \
-   pf = parity_table[(UChar)CC_RES];                           \
+   cf = (CC_DEP2 >> (DATA_BITS - 1)) & CC_MASK_C;              \
+   pf = parity_table[(UChar)CC_DEP1];                          \
    af = 0; /* undefined */                                     \
-   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
-   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;                       \
+   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;                 \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_AUX ^ CC_RES, 12 - DATA_BITS) & CC_MASK_O;   \
+   of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) & CC_MASK_O; \
    return cf | pf | af | zf | sf | of;                         \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_SAR(DATA_BITS,DATA_UTYPE)                      \
+#define ACTIONS_SHR(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                        \
    Int cf, pf, af, zf, sf, of;                                 \
-   cf = CC_AUX & 1;                                            \
-   pf = parity_table[(UChar)CC_RES];                           \
+   cf = CC_DEP2 & 1;                                           \
+   pf = parity_table[(UChar)CC_DEP1];                          \
    af = 0; /* undefined */                                     \
-   zf = ((DATA_UTYPE)CC_RES == 0) << 6;                                \
-   sf = lshift(CC_RES, 8 - DATA_BITS) & 0x80;                  \
+   zf = ((DATA_UTYPE)CC_DEP1 == 0) << 6;                       \
+   sf = lshift(CC_DEP1, 8 - DATA_BITS) & 0x80;                 \
    /* of is defined if shift count == 1 */                     \
-   of = lshift(CC_AUX ^ CC_RES, 12 - DATA_BITS) & CC_MASK_O;   \
+   of = lshift(CC_DEP2 ^ CC_DEP1, 12 - DATA_BITS) & CC_MASK_O; \
    return cf | pf | af | zf | sf | of;                         \
 }
 
 /*-------------------------------------------------------------*/
 
 /* ROL: cf' = lsb(result).  of' = msb(result) ^ lsb(result). */
-/* DST = result, SRC = old flags */
+/* DEP1 = result, NDEP = old flags */
 #define ACTIONS_ROL(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    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)));                     \
+      = (CC_NDEP & ~(CC_MASK_O | CC_MASK_C))                   \
+        | (CC_MASK_C & CC_DEP1)                                        \
+        | (CC_MASK_O & (lshift(CC_DEP1, 11-(DATA_BITS-1))      \
+                   ^ lshift(CC_DEP1, 11)));                    \
    return fl;                                                  \
 }
 
 /*-------------------------------------------------------------*/
 
 /* ROR: cf' = msb(result).  of' = msb(result) ^ msb-1(result). */
-/* DST = result, SRC = old flags */
+/* DEP1 = result, NDEP = old flags */
 #define ACTIONS_ROR(DATA_BITS,DATA_UTYPE)                      \
 {                                                              \
    PREAMBLE(DATA_BITS);                                                \
    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)));     \
+      = (CC_NDEP & ~(CC_MASK_O | CC_MASK_C))                   \
+        | (CC_MASK_C & (CC_DEP1 >> (DATA_BITS-1)))             \
+        | (CC_MASK_O & (lshift(CC_DEP1, 11-(DATA_BITS-1))      \
+                   ^ lshift(CC_DEP1, 11-(DATA_BITS-1)+1)));    \
    return fl;                                                  \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE)                     \
-{                                                              \
-   PREAMBLE(DATA_BITS);                                                \
-   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 = (resLo == 0) << 6;                                     \
-   sf = lshift(resLo, 8 - DATA_BITS) & 0x80;                   \
-   of = cf << 11;                                              \
-   return cf | pf | af | zf | sf | of;                         \
+#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE,DATA_U2TYPE)          \
+{                                                               \
+   PREAMBLE(DATA_BITS);                                         \
+   Int cf, pf, af, zf, sf, of;                                  \
+   DATA_UTYPE  hi;                                              \
+   DATA_UTYPE  lo = ((DATA_UTYPE)CC_DEP1)                       \
+                    * ((DATA_UTYPE)CC_DEP2);                    \
+   DATA_U2TYPE rr = ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP1))        \
+                    * ((DATA_U2TYPE)((DATA_UTYPE)CC_DEP2));     \
+   hi = (DATA_UTYPE)(rr >>/*u*/ DATA_BITS);                     \
+   cf = (hi != 0);                                              \
+   pf = parity_table[(UChar)lo];                                \
+   af = 0; /* undefined */                                      \
+   zf = (lo == 0) << 6;                                         \
+   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                       \
+   of = cf << 11;                                               \
+   return cf | pf | af | zf | sf | of;                          \
 }
 
 /*-------------------------------------------------------------*/
 
-#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE)                     \
-{                                                              \
-   PREAMBLE(DATA_BITS);                                                \
-   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 = (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)          \
+{                                                               \
+   PREAMBLE(DATA_BITS);                                         \
+   Int cf, pf, af, zf, sf, of;                                  \
+   DATA_STYPE  hi;                                              \
+   DATA_STYPE  lo = ((DATA_STYPE)CC_DEP1)                       \
+                    * ((DATA_STYPE)CC_DEP2);                    \
+   DATA_S2TYPE rr = ((DATA_S2TYPE)((DATA_STYPE)CC_DEP1))        \
+                    * ((DATA_S2TYPE)((DATA_STYPE)CC_DEP2));     \
+   hi = (DATA_STYPE)(rr >>/*s*/ DATA_BITS);                     \
+   cf = (hi != (lo >>/*s*/ (DATA_BITS-1)));                     \
+   pf = parity_table[(UChar)lo];                                \
+   af = 0; /* undefined */                                      \
+   zf = (lo == 0) << 6;                                         \
+   sf = lshift(lo, 8 - DATA_BITS) & 0x80;                       \
+   of = cf << 11;                                               \
+   return cf | pf | af | zf | sf | of;                          \
 }
 
 
-
-#define CC_SHIFT_C 0
-#define CC_SHIFT_P 2
-#define CC_SHIFT_A 4
-#define CC_SHIFT_Z 6
-#define CC_SHIFT_S 7
-#define CC_SHIFT_O 11
-
 #if PROFILE_EFLAGS
 
 static UInt tabc[CC_OP_NUMBER];
@@ -392,14 +404,17 @@ 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_res_formal, UInt cc_aux_formal )
+UInt calculate_eflags_all ( UInt cc_op, 
+                            UInt cc_dep1_formal, 
+                            UInt cc_dep2_formal,
+                            UInt cc_ndep_formal )
 {
 #  if PROFILE_EFLAGS
    n_calc_all++;
 #  endif
    switch (cc_op) {
       case CC_OP_COPY:
-         return cc_res_formal
+         return cc_dep1_formal
                 & (CC_MASK_O | CC_MASK_S | CC_MASK_Z 
                    | CC_MASK_A | CC_MASK_C | CC_MASK_P);
 
@@ -435,9 +450,9 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_res_formal, UInt cc_aux_formal )
       case CC_OP_SHLW:   ACTIONS_SHL( 16, UShort );
       case CC_OP_SHLL:   ACTIONS_SHL( 32, UInt   );
 
-      case CC_OP_SARB:   ACTIONS_SAR(  8, UChar  );
-      case CC_OP_SARW:   ACTIONS_SAR( 16, UShort );
-      case CC_OP_SARL:   ACTIONS_SAR( 32, UInt   );
+      case CC_OP_SHRB:   ACTIONS_SHR(  8, UChar  );
+      case CC_OP_SHRW:   ACTIONS_SHR( 16, UShort );
+      case CC_OP_SHRL:   ACTIONS_SHR( 32, UInt   );
 
       case CC_OP_ROLB:   ACTIONS_ROL(  8, UChar  );
       case CC_OP_ROLW:   ACTIONS_ROL( 16, UShort );
@@ -447,18 +462,18 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_res_formal, UInt cc_aux_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  );
-      case CC_OP_UMULW:  ACTIONS_UMUL( 16, UShort );
-      case CC_OP_UMULL:  ACTIONS_UMUL( 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_SMULB:  ACTIONS_SMUL(  8, Char  );
-      case CC_OP_SMULW:  ACTIONS_SMUL( 16, Short );
-      case CC_OP_SMULL:  ACTIONS_SMUL( 32, Int   );
+      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  );
 
       default:
          /* shouldn't really make these calls from generated code */
-         vex_printf("calculate_eflags_all( %d, 0x%x, 0x%x )\n",
-                    cc_op, cc_res_formal, cc_res_formal );
+         vex_printf("calculate_eflags_all( %d, 0x%x, 0x%x, 0x%x )\n",
+                    cc_op, cc_dep1_formal, cc_dep2_formal, cc_ndep_formal );
          vpanic("calculate_eflags_all");
    }
 }
@@ -466,7 +481,10 @@ UInt calculate_eflags_all ( UInt cc_op, UInt cc_res_formal, UInt cc_aux_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_res, UInt cc_aux )
+UInt calculate_eflags_c ( UInt cc_op, 
+                          UInt cc_dep1, 
+                          UInt cc_dep2,
+                          UInt cc_ndep )
 {
    /* Fast-case some common ones. */
    switch (cc_op) {
@@ -496,16 +514,19 @@ UInt calculate_eflags_c ( UInt cc_op, UInt cc_res, UInt cc_aux )
 
    n_calc_c++;
 #  endif
-   return calculate_eflags_all(cc_op,cc_res,cc_aux) & CC_MASK_C;
+   return calculate_eflags_all(cc_op,cc_dep1,cc_dep2,cc_ndep) & 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_res, UInt cc_aux )
+                                      UInt cc_op, 
+                                      UInt cc_dep1, 
+                                      UInt cc_dep2,
+                                      UInt cc_ndep )
 {
-   UInt eflags = calculate_eflags_all(cc_op, cc_res, cc_aux);
+   UInt eflags = calculate_eflags_all(cc_op, cc_dep1, cc_dep2, cc_ndep);
    UInt of,sf,zf,cf,pf;
    UInt inv = cond & 1;
 
@@ -570,8 +591,8 @@ UInt calculate_eflags_c ( UInt cc_op, UInt cc_res, UInt cc_aux )
 
       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_res, cc_aux );
+         vex_printf("calculate_condition( %d, %d, 0x%x, 0x%x, 0x%x )\n",
+                    cond, cc_op, cc_dep1, cc_dep2, cc_ndep );
          vpanic("calculate_condition");
    }
 }
@@ -1278,9 +1299,10 @@ void LibVEX_GuestX86_put_eflags ( UInt eflags_native,
       &= (CC_MASK_C | CC_MASK_P | CC_MASK_A 
           | CC_MASK_Z | CC_MASK_S | CC_MASK_O);
 
-   vex_state->guest_CC_OP  = CC_OP_COPY;
-   vex_state->guest_CC_AUX = 0;
-   vex_state->guest_CC_RES = eflags_native;
+   vex_state->guest_CC_OP   = CC_OP_COPY;
+   vex_state->guest_CC_DEP1 = eflags_native;
+   vex_state->guest_CC_DEP2 = 0;
+   vex_state->guest_CC_NDEP = 0; /* unnecessary paranoia */
 }
 
 
@@ -1289,8 +1311,9 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state )
 {
    UInt eflags = calculate_eflags_all(
                     vex_state->guest_CC_OP,
-                    vex_state->guest_CC_RES,
-                    vex_state->guest_CC_AUX
+                    vex_state->guest_CC_DEP1,
+                    vex_state->guest_CC_DEP2,
+                    vex_state->guest_CC_NDEP
                  );
    UInt dflag = vex_state->guest_DFLAG;
    vassert(dflag == 1 || dflag == 0xFFFFFFFF);
@@ -1316,11 +1339,12 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    vex_state->guest_ESI = 0;
    vex_state->guest_EDI = 0;
 
-   vex_state->guest_CC_OP  = CC_OP_COPY;
-   vex_state->guest_CC_RES = 0;
-   vex_state->guest_CC_AUX = 0;
-   vex_state->guest_DFLAG  = 1; /* forwards */
-   vex_state->guest_IDFLAG = 0;
+   vex_state->guest_CC_OP   = CC_OP_COPY;
+   vex_state->guest_CC_DEP1 = 0;
+   vex_state->guest_CC_DEP2 = 0;
+   vex_state->guest_CC_NDEP = 0;
+   vex_state->guest_DFLAG   = 1; /* forwards */
+   vex_state->guest_IDFLAG  = 0;
 
    vex_state->guest_EIP = 0;
 
@@ -1476,11 +1500,11 @@ VexGuestLayout
           /* Describe any sections to be regarded by Memcheck as
              'always-defined'. */
           .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. */
+          /* flags thunk: OP and NDEP are always defd, whereas DEP1
+             and DEP2 have to be tracked.  See detailed comment in
+             gdefs.h on meaning of thunk fields. */
           .alwaysDefd[0]  = ALWAYSDEFD(guest_CC_OP),
-          .alwaysDefd[1]  = ALWAYSDEFD(guest_CC_AUX),
+          .alwaysDefd[1]  = ALWAYSDEFD(guest_CC_NDEP),
 
           .alwaysDefd[2]  = ALWAYSDEFD(guest_DFLAG),
           .alwaysDefd[3]  = ALWAYSDEFD(guest_IDFLAG),
index f28d5865c23644ef9d8136a4e45e2326154f069d..1bbf41804f32dfa00d85cfffeed51e680bd48584 100644 (file)
@@ -77,21 +77,24 @@ static IRBB* irbb;
 /*--- Offsets of various parts of the x86 guest state.     ---*/
 /*------------------------------------------------------------*/
 
-#define OFFB_FPREGS  offsetof(VexGuestX86State,guest_FPREG[0])
-#define OFFB_FPTAGS  offsetof(VexGuestX86State,guest_FPTAG[0])
-#define OFFB_EAX     offsetof(VexGuestX86State,guest_EAX)
-#define OFFB_EBX     offsetof(VexGuestX86State,guest_EBX)
-#define OFFB_ECX     offsetof(VexGuestX86State,guest_ECX)
-#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_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)
-#define OFFB_FC3210  offsetof(VexGuestX86State,guest_FC3210)
-#define OFFB_FPUCW   offsetof(VexGuestX86State,guest_FPUCW)
+#define OFFB_FPREGS   offsetof(VexGuestX86State,guest_FPREG[0])
+#define OFFB_FPTAGS   offsetof(VexGuestX86State,guest_FPTAG[0])
+#define OFFB_EAX      offsetof(VexGuestX86State,guest_EAX)
+#define OFFB_EBX      offsetof(VexGuestX86State,guest_EBX)
+#define OFFB_ECX      offsetof(VexGuestX86State,guest_ECX)
+#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_DEP1  offsetof(VexGuestX86State,guest_CC_DEP1)
+#define OFFB_CC_DEP2  offsetof(VexGuestX86State,guest_CC_DEP2)
+#define OFFB_CC_NDEP  offsetof(VexGuestX86State,guest_CC_NDEP)
+
+#define OFFB_DFLAG    offsetof(VexGuestX86State,guest_DFLAG)
+#define OFFB_IDFLAG   offsetof(VexGuestX86State,guest_IDFLAG)
+#define OFFB_FTOP     offsetof(VexGuestX86State,guest_FTOP)
+#define OFFB_FC3210   offsetof(VexGuestX86State,guest_FC3210)
+#define OFFB_FPUCW    offsetof(VexGuestX86State,guest_FPUCW)
 
 
 /*------------------------------------------------------------*/
@@ -552,21 +555,6 @@ 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
@@ -591,15 +579,6 @@ static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd )
    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.                                 ---*/
@@ -608,13 +587,15 @@ static IRType doubleLengthType ( IRType ty )
 /* -------------- Evaluating the flags-thunk. -------------- */
 
 /* Build IR to calculate all the eflags from stored
-   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_I32. */
+   CC_OP/CC_DEP1/CC_DEP2/CC_NDEP.  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_RES, Ity_I32),
-                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
+      = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP,   Ity_I32),
+                       IRExpr_Get(OFFB_CC_DEP1, Ity_I32),
+                       IRExpr_Get(OFFB_CC_DEP2, Ity_I32),
+                       IRExpr_Get(OFFB_CC_NDEP, Ity_I32) );
    IRExpr* call
       = mkIRExprCCall(
            Ity_I32,
@@ -622,21 +603,23 @@ static IRExpr* mk_calculate_eflags_all ( void )
            "calculate_eflags_all", &calculate_eflags_all,
            args
         );
-   /* Exclude OP and AUX from definedness checking.  We're only
-      interested in RES. */
-   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<2);
+   /* Exclude OP and NDEP from definedness checking.  We're only
+      interested in DEP1 and DEP2. */
+   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
    return call;
 }
 
 /* Build IR to calculate some particular condition from stored
-   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_Bit. */
+   CC_OP/CC_DEP1/CC_DEP2/CC_NDEP.  Returns an expression ::
+   Ity_Bit. */
 static IRExpr* mk_calculate_condition ( Condcode cond )
 {
    IRExpr** args
-      = mkIRExprVec_4( mkU32(cond),
+      = mkIRExprVec_5( mkU32(cond),
                        IRExpr_Get(OFFB_CC_OP,  Ity_I32),
-                       IRExpr_Get(OFFB_CC_RES, Ity_I32),
-                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
+                       IRExpr_Get(OFFB_CC_DEP1, Ity_I32),
+                       IRExpr_Get(OFFB_CC_DEP2, Ity_I32),
+                       IRExpr_Get(OFFB_CC_NDEP, Ity_I32) );
    IRExpr* call
       = mkIRExprCCall(
            Ity_I32,
@@ -644,20 +627,21 @@ static IRExpr* mk_calculate_condition ( Condcode cond )
            "calculate_condition", &calculate_condition,
            args
         );
-   /* Exclude the requested condition, OP and AUX from definedness
-      checking.  We're only interested in RES. */
-   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1 << 3);
+   /* Exclude the requested condition, OP and NDEP from definedness
+      checking.  We're only interested in DEP1 and DEP2. */
+   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
    return unop(Iop_32to1, call);
 }
 
 /* Build IR to calculate just the carry flag from stored
-   CC_OP/CC_RES/CC_AUX.  Returns an expression :: Ity_I32. */
+   CC_OP/CC_DEP1/CC_DEP2/CC_NDEP.  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_RES, Ity_I32),
-                       IRExpr_Get(OFFB_CC_AUX, Ity_I32) );
+      = mkIRExprVec_4( IRExpr_Get(OFFB_CC_OP,   Ity_I32),
+                       IRExpr_Get(OFFB_CC_DEP1, Ity_I32),
+                       IRExpr_Get(OFFB_CC_DEP2, Ity_I32),
+                       IRExpr_Get(OFFB_CC_NDEP, Ity_I32) );
    IRExpr* call
       = mkIRExprCCall(
            Ity_I32,
@@ -665,9 +649,9 @@ static IRExpr* mk_calculate_eflags_c ( void )
            "calculate_eflags_c", &calculate_eflags_c,
            args
         );
-   /* Exclude OP and AUX from definedness checking.  We're only
-      interested in RES. */
-   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<2);
+   /* Exclude OP and NDEP from definedness checking.  We're only
+      interested in DEP1 and DEP2. */
+   call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
    return call;
 }
 
@@ -683,6 +667,11 @@ static Bool isAddSub ( IROp op8 )
    return op8 == Iop_Add8 || op8 == Iop_Sub8;
 }
 
+static Bool isLogic ( IROp op8 )
+{
+   return op8 == Iop_And8 || op8 == Iop_Or8 || op8 == Iop_Xor8;
+}
+
 /* U-widen 8/16/32 bit int expr to 32. */
 static IRExpr* widenUto32 ( IRExpr* e )
 {
@@ -726,13 +715,11 @@ static IRExpr* narrowTo ( IRType dst_ty, IRExpr* e )
 }
 
 
-/* Set the flags thunk for add/sub operations..  The supplied op is
+/* Set the flags thunk OP, DEP1 and DEP2 fields.  The supplied op is
    auto-sized up to the real op. */
 
-static void setFlags_RES_AUX ( IROp    op8,
-                               IRTemp  res,
-                               IRTemp  aux,
-                               IRType  ty )
+static 
+void setFlags_DEP1_DEP2 ( IROp op8, IRTemp dep1, IRTemp dep2, IRType ty )
 {
    Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
 
@@ -742,20 +729,18 @@ static void setFlags_RES_AUX ( IROp    op8,
       case Iop_Add8: ccOp += CC_OP_ADDB;   break;
       case Iop_Sub8: ccOp += CC_OP_SUBB;   break;
       default:       ppIROp(op8);
-                     vpanic("setFlags_RES_AUX(x86)");
+                     vpanic("setFlags_DEP1_DEP2(x86)");
    }
-   stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_RES, widenUto32(mkexpr(res))) );
-   stmt( IRStmt_Put( OFFB_CC_AUX, widenUto32(mkexpr(aux))) );
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );
+   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );
+   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(dep2))) );
 }
 
 
-/* For and/or/xor, only the result is important.  However, put zero in
-   CC_AUX since we're paranoid. */
+/* Set the OP and DEP1 fields only, and write zero to DEP2. */
 
-static void setFlags_LOGIC ( IROp    op8,
-                             IRTemp  res,
-                             IRType  ty )
+static 
+void setFlags_DEP1 ( IROp op8, IRTemp dep1, IRType ty )
 {
    Int ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2);
 
@@ -766,11 +751,11 @@ static void setFlags_LOGIC ( IROp    op8,
       case Iop_And8:
       case Iop_Xor8: ccOp += CC_OP_LOGICB; break;
       default:       ppIROp(op8);
-                     vpanic("setFlags_LOGIC(x86)");
+                     vpanic("setFlags_DEP1(x86)");
    }
-   stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_RES, widenUto32(mkexpr(res))) );
-   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0)) );
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );
+   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(dep1))) );
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)) );
 }
 
 
@@ -778,42 +763,44 @@ static void setFlags_LOGIC ( IROp    op8,
    result.  Except if the shift amount is zero, the thunk is left
    unchanged. */
 
-static void setFlags_RES_RESus ( IROp    op32,
-                                 IRTemp  res,
-                                 IRTemp  resUS,
-                                 IRType  ty,
-                                 IRTemp  guard )
+static void setFlags_DEP1_DEP2_shift ( IROp    op32,
+                                       IRTemp  res,
+                                       IRTemp  resUS,
+                                       IRType  ty,
+                                       IRTemp  guard )
 {
    Int ccOp = ty==Ity_I8 ? 2 : (ty==Ity_I16 ? 1 : 0);
 
    vassert(ty == Ity_I8 || ty == Ity_I16 || ty == Ity_I32);
    vassert(guard);
 
+   /* Both kinds of right shifts are handled by the same thunk
+      operation. */
    switch (op32) {
       case Iop_Shr32:
-      case Iop_Sar32: ccOp = CC_OP_SARL - ccOp; break;
+      case Iop_Sar32: ccOp = CC_OP_SHRL - ccOp; break;
       case Iop_Shl32: ccOp = CC_OP_SHLL - ccOp; break;
       default:        ppIROp(op32);
-                      vpanic("setFlags_RES_RESus(x86)");
+                      vpanic("setFlags_DEP1_DEP2_shift(x86)");
    }
 
-   /* RES contains the result, AUX contains the undershifted value. */
+   /* DEP1 contains the result, DEP2 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_RES,
+   stmt( IRStmt_Put( OFFB_CC_DEP1,
                      IRExpr_Mux0X( mkexpr(guard),
-                                   IRExpr_Get(OFFB_CC_RES,Ity_I32),
+                                   IRExpr_Get(OFFB_CC_DEP1,Ity_I32),
                                    widenUto32(mkexpr(res)))) );
-   stmt( IRStmt_Put( OFFB_CC_AUX
+   stmt( IRStmt_Put( OFFB_CC_DEP2
                      IRExpr_Mux0X( mkexpr(guard),
-                                   IRExpr_Get(OFFB_CC_AUX,Ity_I32),
+                                   IRExpr_Get(OFFB_CC_DEP2,Ity_I32),
                                    widenUto32(mkexpr(resUS)))) );
 }
 
 
-/* For the inc/dec case, we store in RES the result value and in AUX
+/* For the inc/dec case, we store in DEP1 the result value and in NDEP
    the former value of the carry flag, which unfortunately we have to
    compute. */
 
@@ -825,44 +812,35 @@ static void setFlags_INC_DEC ( Bool inc, IRTemp res, IRType ty )
    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_AUX, mk_calculate_eflags_c()) );
-   stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(ccOp)) );
-   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(res)) );
+      may require reading all four thunk fields. */
+   stmt( IRStmt_Put( OFFB_CC_NDEP, mk_calculate_eflags_c()) );
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(ccOp)) );
+   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(res)) );
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0)) );
 }
 
 
-/* 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. */
+/* Multiplies are pretty much like add and sub: DEP1 and DEP2 hold the
+   two arguments. */
 
 static
-void setFlags_MUL ( IRType ty, IRTemp resHi, IRTemp resLo, UInt base_op )
+void setFlags_MUL ( IRType ty, IRTemp arg1, IRTemp arg2, UInt base_op )
 {
    switch (ty) {
-   case Ity_I8:
-      stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(base_op+0) ) );
-      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_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_AUX, mkexpr(resLo) ) );
-      stmt( IRStmt_Put( OFFB_CC_RES,
-                        binop(Iop_Xor32, mkexpr(resHi), mkexpr(resLo)) ));
-      break;
-   default:
-      vpanic("setFlags_MUL(x86)");
+      case Ity_I8:
+         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+0) ) );
+         break;
+      case Ity_I16:
+         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+1) ) );
+         break;
+      case Ity_I32:
+         stmt( IRStmt_Put( OFFB_CC_OP, mkU32(base_op+2) ) );
+         break;
+      default:
+         vpanic("setFlags_MUL(x86)");
    }
+   stmt( IRStmt_Put( OFFB_CC_DEP1, widenUto32(mkexpr(arg1)) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, widenUto32(mkexpr(arg2)) ));
 }
 
 
@@ -911,80 +889,70 @@ static Condcode positiveIse_Condcode ( Condcode  cond,
 /* -------------- Helpers for ADD/SUB with carry. -------------- */
 
 /* 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}.
+   appropriately.
 */
 static void helper_ADC ( Int sz,
                         IRTemp tres, IRTemp ta1, IRTemp ta2 )
 {
    UInt    thunkOp;
-   IRExpr* thunkExpr;
-   IRType ty   = szToITy(sz);
-   IRTemp oldc = newTemp(Ity_I32);
-   IROp   plus = mkSizedOp(ty,Iop_Add8);
+   IRType  ty    = szToITy(sz);
+   IRTemp  oldc  = newTemp(Ity_I32);
+   IRTemp  oldcn = newTemp(ty);
+   IROp    plus  = mkSizedOp(ty, Iop_Add8);
+   IROp    xor   = mkSizedOp(ty, Iop_Xor8);
+
+   vassert(sz == 1 || sz == 2 || sz == 4);
+   thunkOp = sz==4 ? CC_OP_ADCL : (sz==2 ? CC_OP_ADCW : CC_OP_ADCB);
 
    /* oldc = old carry flag, 0 or 1 */
-   assign( oldc, binop(Iop_And32,
-                       mk_calculate_eflags_c(),
-                      mkU32(1)) );
+   assign( oldc,  binop(Iop_And32,
+                        mk_calculate_eflags_c(),
+                       mkU32(1)) );
 
-   assign(tres, binop(plus,
-                      binop(plus,mkexpr(ta1),mkexpr(ta2)),
-                      narrowTo(ty,mkexpr(oldc))));
+   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );
 
-   vassert(sz == 1 || sz == 2 || sz == 4);
-   thunkOp = sz==4 ? CC_OP_ADDL : (sz==2 ? CC_OP_ADDW : CC_OP_ADDB);
-
-   /* This dynamically calculates the thunk op number.  
-      3 * the old carry flag is added, so (eg) it gives
-      CC_OP_ADDL if old carry was zero, and CC_OP_ADCL if
-      old carry was one. */
-   thunkExpr = binop(Iop_Add32, 
-                     mkU32(thunkOp),
-                    binop(Iop_Mul32, mkexpr(oldc), mkU32(3)));
-
-   stmt( IRStmt_Put( OFFB_CC_OP,  thunkExpr ) );
-   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(tres) ) );
-   stmt( IRStmt_Put( OFFB_CC_AUX, mkexpr(ta2) ) );
+   assign( tres, binop(plus,
+                       binop(plus,mkexpr(ta1),mkexpr(ta2)),
+                       mkexpr(oldcn)) );
+
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(thunkOp) ) );
+   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(ta1) ) );
+   stmt( IRStmt_Put( OFFB_CC_DEP2, binop(xor, mkexpr(ta2), mkexpr(oldcn)) ) );
+   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );
 }
 
 
 /* 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}.
+   appropriately.
 */
 static void helper_SBB ( Int sz,
                         IRTemp tres, IRTemp ta1, IRTemp ta2 )
 {
    UInt    thunkOp;
-   IRExpr* thunkExpr;
-   IRType ty    = szToITy(sz);
-   IRTemp oldc  = newTemp(Ity_I32);
-   IROp   minus = mkSizedOp(ty,Iop_Sub8);
+   IRType  ty    = szToITy(sz);
+   IRTemp  oldc  = newTemp(Ity_I32);
+   IRTemp  oldcn = newTemp(ty);
+   IROp    minus = mkSizedOp(ty, Iop_Sub8);
+   IROp    xor   = mkSizedOp(ty, Iop_Xor8);
+
+   vassert(sz == 1 || sz == 2 || sz == 4);
+   thunkOp = sz==4 ? CC_OP_SBBL : (sz==2 ? CC_OP_SBBW : CC_OP_SBBB);
 
    /* oldc = old carry flag, 0 or 1 */
    assign( oldc, binop(Iop_And32,
                        mk_calculate_eflags_c(),
                       mkU32(1)) );
 
-   assign(tres, binop(minus,
-                      binop(minus,mkexpr(ta1),mkexpr(ta2)),
-                      narrowTo(ty,mkexpr(oldc))));
+   assign( oldcn, narrowTo(ty, mkexpr(oldc)) );
 
-   vassert(sz == 1 || sz == 2 || sz == 4);
-   thunkOp = sz==4 ? CC_OP_SUBL : (sz==2 ? CC_OP_SUBW : CC_OP_SUBB);
-
-   /* This dynamically calculates the thunk op number.  
-      3 * the old carry flag is added, so (eg) it gives
-      CC_OP_SUBL if old carry was zero, and CC_OP_SBBL if
-      old carry was one. */
-   thunkExpr = binop(Iop_Add32, 
-                     mkU32(thunkOp),
-                    binop(Iop_Mul32, mkexpr(oldc), mkU32(3)));
-
-   stmt( IRStmt_Put( OFFB_CC_OP,  thunkExpr ) );
-   stmt( IRStmt_Put( OFFB_CC_RES, mkexpr(tres) ) );
-   stmt( IRStmt_Put( OFFB_CC_AUX, mkexpr(ta2) ) );
+   assign( tres, binop(minus,
+                       binop(minus,mkexpr(ta1),mkexpr(ta2)),
+                       mkexpr(oldcn)) );
+
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(thunkOp) ) );
+   stmt( IRStmt_Put( OFFB_CC_DEP1, mkexpr(ta1) ) );
+   stmt( IRStmt_Put( OFFB_CC_DEP2, binop(xor, mkexpr(ta2), mkexpr(oldcn)) ) );
+   stmt( IRStmt_Put( OFFB_CC_NDEP, mkexpr(oldc) ) );
 }
 
 
@@ -1801,9 +1769,9 @@ void codegen_XOR_reg_with_itself ( Int size, Int ge_reg )
    /* reg := 0 */
    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_RES, mkU32(CC_MASK_Z|CC_MASK_P) ));
-   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP1, mkU32(CC_MASK_Z|CC_MASK_P) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
    DIP("xor%c %s, %s\n", nameISize(size),
                          nameIReg(size,ge_reg), nameIReg(size,ge_reg) );
 }
@@ -1884,9 +1852,9 @@ UInt dis_op2_E_G ( UChar       sorb,
       } else {
          assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
          if (keep)
             putIReg(size, gregOfRM(rm), mkexpr(dst1));
       }
@@ -1911,9 +1879,9 @@ UInt dis_op2_E_G ( UChar       sorb,
       } else {
          assign( dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)) );
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
          if (keep)
             putIReg(size, gregOfRM(rm), mkexpr(dst1));
       }
@@ -1992,9 +1960,9 @@ UInt dis_op2_G_E ( UChar       sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
          if (keep)
             putIReg(size, eregOfRM(rm), mkexpr(dst1));
       }
@@ -2021,9 +1989,9 @@ UInt dis_op2_G_E ( UChar       sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
          if (keep)
             storeLE(mkexpr(addr), mkexpr(dst1));
       }
@@ -2140,9 +2108,12 @@ 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_RES_AUX(op8, dst1, src, ty);
+      setFlags_DEP1_DEP2(op8, dst0, src, ty);
    else
-      setFlags_LOGIC(op8, dst1, ty);
+   if (isLogic(op8))
+      setFlags_DEP1(op8, dst1, ty);
+   else
+      vpanic("dis_op_imm_A(x86,guest)");
 
    if (keep)
       putIReg(size, R_EAX, mkexpr(dst1));
@@ -2318,9 +2289,9 @@ UInt dis_Grp1 ( UChar sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
       }
 
       if (gregOfRM(modrm) < 7)
@@ -2343,9 +2314,9 @@ UInt dis_Grp1 ( UChar sorb,
       } else {
          assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(src)));
         if (isAddSub(op8))
-            setFlags_RES_AUX(op8, dst1, src, ty);
+            setFlags_DEP1_DEP2(op8, dst0, src, ty);
          else
-            setFlags_LOGIC(op8, dst1, ty);
+            setFlags_DEP1(op8, dst1, ty);
       }
 
       if (gregOfRM(modrm) < 7)
@@ -2420,9 +2391,9 @@ 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_RES, unop(Iop_64HIto32, mkexpr(r64)) ));
-      stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
+      stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+      stmt( IRStmt_Put( OFFB_CC_DEP1, unop(Iop_64HIto32, mkexpr(r64)) ));
+      stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
    }
 
    if (isShift) {
@@ -2470,7 +2441,7 @@ UInt dis_Grp2 ( UChar  sorb,
                           mkU8(31))) );
 
       /* Build the flags thunk. */
-      setFlags_RES_RESus(op32, res32, res32ss, ty, shift_amt);
+      setFlags_DEP1_DEP2_shift(op32, res32, res32ss, ty, shift_amt);
 
       /* Narrow the result back down. */
       assign( dst1, narrowTo(ty, mkexpr(res32)) );
@@ -2538,18 +2509,22 @@ UInt dis_Grp2 ( UChar  sorb,
 
       assign(oldFlags, mk_calculate_eflags_all());
 
-      /* CC_RES is the rotated value.  CC_AUX is flags before. */
+      /* CC_DEP1 is the rotated value.  CC_NDEP 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_RES
+      stmt( IRStmt_Put( OFFB_CC_DEP1
                         IRExpr_Mux0X( mkexpr(rot_amt32),
-                                      IRExpr_Get(OFFB_CC_RES,Ity_I32),
+                                      IRExpr_Get(OFFB_CC_DEP1,Ity_I32),
                                       widenUto32(mkexpr(dst1)))) );
-      stmt( IRStmt_Put( OFFB_CC_AUX, 
+      stmt( IRStmt_Put( OFFB_CC_DEP2, 
+                        IRExpr_Mux0X( mkexpr(rot_amt32),
+                                      IRExpr_Get(OFFB_CC_DEP2,Ity_I32),
+                                      mkU32(0))) );
+      stmt( IRStmt_Put( OFFB_CC_NDEP, 
                         IRExpr_Mux0X( mkexpr(rot_amt32),
-                                      IRExpr_Get(OFFB_CC_AUX,Ity_I32),
+                                      IRExpr_Get(OFFB_CC_NDEP,Ity_I32),
                                       mkexpr(oldFlags))) );
    } /* if (isRotate) */
 
@@ -2713,10 +2688,10 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
          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)) );
          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;
@@ -2727,10 +2702,10 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
          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)) );
          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;
@@ -2741,10 +2716,10 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
          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;
       }
@@ -2777,7 +2752,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta )
            assign(dst1, binop(mkSizedOp(ty,Iop_And8),
                               getIReg(sz,eregOfRM(modrm)),
                                mkU(ty,d32)));
-           setFlags_LOGIC( Iop_And8, dst1, ty );
+           setFlags_DEP1( Iop_And8, dst1, ty );
             DIP("test%c $0x%x, %s\n", nameISize(sz), d32, 
                                       nameIReg(sz, eregOfRM(modrm)));
             break;
@@ -2797,7 +2772,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_RES_AUX(Iop_Sub8, dst1, src, ty);
+            setFlags_DEP1_DEP2(Iop_Sub8, dst0, src, ty);
            putIReg(sz, eregOfRM(modrm), mkexpr(dst1));
             DIP("neg%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm)));
             break;
@@ -2841,7 +2816,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta )
            dst1 = newTemp(ty);
            assign(dst1, binop(mkSizedOp(ty,Iop_And8),
                               mkexpr(t1), mkU(ty,d32)));
-           setFlags_LOGIC( Iop_And8, dst1, ty );
+           setFlags_DEP1( Iop_And8, dst1, ty );
             DIP("test%c $0x%x, %s\n", nameISize(sz), d32, dis_buf);
             break;
          }
@@ -2857,7 +2832,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_RES_AUX(Iop_Sub8, dst1, src, ty);
+            setFlags_DEP1_DEP2(Iop_Sub8, dst0, src, ty);
            storeLE( mkexpr(addr), mkexpr(dst1) );
             DIP("neg%c %s\n", nameISize(sz), dis_buf);
             break;
@@ -3139,7 +3114,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 res = newTemp(ty);
    IRTemp td  = newTemp(Ity_I32); /*  EDI  */
    IRTemp ts  = newTemp(Ity_I32); /*  ESI  */
 
@@ -3157,8 +3132,8 @@ void dis_CMPS ( Int sz, IRTemp t_inc )
 
    //uInstr2(cb, SUB,  sz, TempReg, tdv,   TempReg, tsv); 
    //setFlagsFromUOpcode(cb, SUB);
-   assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(tsv), mkexpr(tdv)) );
-   setFlags_RES_AUX ( Iop_Sub8, res, tdv, ty );
+   //assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(tsv), mkexpr(tdv)) );
+   setFlags_DEP1_DEP2 ( Iop_Sub8, tsv, tdv, ty );
 
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, ts);
@@ -3177,7 +3152,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);
+   //IRTemp res = newTemp(ty);
 
    //uInstr2(cb, GET,  sz, ArchReg, R_EAX, TempReg, ta);
    assign( ta, getIReg(sz, R_EAX) );
@@ -3190,8 +3165,8 @@ void dis_SCAS ( Int sz, IRTemp t_inc )
 
    //uInstr2(cb, SUB,  sz, TempReg, tdv,   TempReg, ta);
    //setFlagsFromUOpcode(cb, SUB);
-   assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(ta), mkexpr(tdv)) );
-   setFlags_RES_AUX ( Iop_Sub8, res, tdv, ty );
+   //assign( res, binop(mkSizedOp(ty, Iop_Sub8), mkexpr(ta), mkexpr(tdv)) );
+   setFlags_DEP1_DEP2 ( Iop_Sub8, ta, tdv, ty );
 
    //uInstr2(cb, ADD,   4, TempReg, t_inc, TempReg, td);
    //uInstr2(cb, PUT,   4, TempReg, td,    ArchReg, R_EDI);
@@ -3239,12 +3214,11 @@ void dis_REP_op ( Condcode cond,
 /*--- Arithmetic, etc.                                     ---*/
 /*------------------------------------------------------------*/
 
-/* (I)MUL E, G.  Supplied eip points to the modR/M byte. */
+/* IMUL E, G.  Supplied eip points to the modR/M byte. */
 static
 UInt dis_mul_E_G ( UChar       sorb,
                    Int         size, 
-                   UInt        delta0,
-                   Bool        syned )
+                   UInt        delta0 )
 {
    Int    alen;
    UChar  dis_buf[50];
@@ -3252,11 +3226,7 @@ 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)) {
@@ -3266,25 +3236,20 @@ UInt dis_mul_E_G ( UChar       sorb,
       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, te, tg, CC_OP_SMULB );
 
-   setFlags_MUL ( ty, resHi, resLo, syned ? CC_OP_SMULB : CC_OP_UMULB );
+   assign( resLo, binop( mkSizedOp(ty, Iop_Mul8), mkexpr(te), mkexpr(tg) ) );
 
    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)));
+      DIP("imul%c %s, %s\n", nameISize(size), 
+                             nameIReg(size,eregOfRM(rm)),
+                             nameIReg(size,gregOfRM(rm)));
       return 1+delta0;
    } else {
-      DIP("%smul%c %s, %s\n", syned ? "i" : "",
-                              nameISize(size), 
-                              dis_buf, nameIReg(size,gregOfRM(rm)));
+      DIP("imul%c %s, %s\n", nameISize(size), 
+                             dis_buf, nameIReg(size,gregOfRM(rm)));
       return alen+delta0;
    }
 }
@@ -3303,9 +3268,7 @@ 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);
 
@@ -3325,12 +3288,9 @@ UInt dis_imul_I_E_G ( UChar       sorb,
 
    assign(tl, mkU(ty,d32));
 
-   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) ));
+   assign( resLo, binop( mkSizedOp(ty, Iop_Mul8), mkexpr(te), mkexpr(tl) ));
 
-   setFlags_MUL ( ty, resHi, resLo, CC_OP_SMULB );
+   setFlags_MUL ( ty, te, tl, CC_OP_SMULB );
 
    putIReg(size, gregOfRM(rm), mkexpr(resLo));
 
@@ -3607,9 +3567,9 @@ static void fp_do_ucomi_ST0_STi ( UInt i, Bool pop_after )
       Z,P,C,O correctly, but forces A and S to zero, whereas the Intel
       documentation implies A and S are unchanged. 
    */
-   stmt( IRStmt_Put( OFFB_CC_OP,  mkU32(CC_OP_COPY) ));
-   stmt( IRStmt_Put( OFFB_CC_AUX, mkU32(0) ));
-   stmt( IRStmt_Put( OFFB_CC_RES,
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP1,
                      binop( Iop_And32,
                             binop(Iop_CmpF64, get_ST(0), get_ST(i)),
                             mkU32(0x45)
@@ -4970,8 +4930,8 @@ UInt dis_SHLRD_Gv_Ev ( UChar sorb,
                             binop(Iop_Sub8, mkexpr(tmpSH), mkU8(1) ),
                             mask))) );
 
-   setFlags_RES_RESus ( left_shift ? Iop_Shl32 : Iop_Sar32,
-                        tmpRes, tmpSubSh, ty, tmpSH );
+   setFlags_DEP1_DEP2_shift ( left_shift ? Iop_Shl32 : Iop_Sar32,
+                              tmpRes, tmpSubSh, ty, tmpSH );
 
    /* Put result back. */
 
@@ -5103,11 +5063,11 @@ 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_AUX, mkU32(0) ));
+   /* 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_DEP2, mkU32(0) ));
    stmt( IRStmt_Put( 
-            OFFB_CC_RES,
+            OFFB_CC_DEP1,
             binop(Iop_And32,
                   binop(Iop_Shr32, 
                         unop(Iop_8Uto32, mkexpr(t_fetched)),
@@ -5175,10 +5135,10 @@ 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_AUX, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
    stmt( IRStmt_Put( 
-            OFFB_CC_RES,
+            OFFB_CC_DEP1,
             IRExpr_Mux0X( mkexpr(src8),
                           /* src==0 */
                           mkU32(CC_MASK_Z),
@@ -5259,12 +5219,12 @@ void codegen_SAHF ( void )
       (calculate_flags_all() & CC_MASK_O)  -- retain the old O flag
       | (%AH & (CC_MASK_S|CC_MASK_Z|CC_MASK_A|CC_MASK_P|CC_MASK_C)
    */
-   UInt   mask_SZACP = CC_MASK_S|CC_MASK_Z|CC_MASK_A|CC_MASK_P|CC_MASK_C;
+   UInt   mask_SZACP = CC_MASK_S|CC_MASK_Z|CC_MASK_A|CC_MASK_C|CC_MASK_P;
    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_AUX, mkU32(0) ));
-   stmt( IRStmt_Put( OFFB_CC_RES,
+   stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+   stmt( IRStmt_Put( OFFB_CC_DEP1,
          binop(Iop_Or32,
                binop(Iop_And32, mkexpr(oldflags), mkU32(CC_MASK_O)),
                binop(Iop_And32, 
@@ -5307,7 +5267,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 res   = newTemp(ty);
    IRTemp dest  = newTemp(ty);
    IRTemp dest2 = newTemp(ty);
    IRTemp acc2  = newTemp(ty);
@@ -5331,8 +5291,8 @@ UInt dis_cmpxchg_G_E ( UChar       sorb,
 
    assign( src, getIReg(size, gregOfRM(rm)) );
    assign( acc, getIReg(size, R_EAX) );
-   assign( res, binop( mkSizedOp(ty,Iop_Sub8), mkexpr(acc), mkexpr(dest) ));
-   setFlags_RES_AUX(Iop_Sub8, res, dest, ty);
+   //assign( res, binop( mkSizedOp(ty,Iop_Sub8), mkexpr(acc), mkexpr(dest) ));
+   setFlags_DEP1_DEP2(Iop_Sub8, acc, 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)) );
@@ -5517,7 +5477,7 @@ UInt dis_xadd_G_E ( UChar sorb, Int sz, UInt delta0 )
       assign( tmpd,  loadLE(ty, mkexpr(addr)) );
       assign( tmpt0, getIReg(sz, gregOfRM(rm)) );
       assign( tmpt1, binop(mkSizedOp(ty,Iop_Add8), mkexpr(tmpd), mkexpr(tmpt0)) );
-      setFlags_RES_AUX( Iop_Add8, tmpt1, tmpt0, ty );
+      setFlags_DEP1_DEP2( Iop_Add8, tmpd, tmpt0, ty );
       storeLE( mkexpr(addr), mkexpr(tmpt1) );
       putIReg(sz, gregOfRM(rm), mkexpr(tmpd));
       DIP("xadd%c %s, %s\n",
@@ -8312,9 +8272,9 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       putIReg(4, R_ESP, binop(Iop_Add32, mkexpr(t2), mkU32(sz)));
       /* 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_AUX, mkU32(0) ));
-      stmt( IRStmt_Put( OFFB_CC_RES
+      stmt( IRStmt_Put( OFFB_CC_OP,   mkU32(CC_OP_COPY) ));
+      stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) ));
+      stmt( IRStmt_Put( OFFB_CC_DEP1
                        binop(Iop_And32,
                              mkexpr(t1), 
                              mkU32( CC_MASK_C | CC_MASK_P | CC_MASK_A 
@@ -9175,7 +9135,7 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
       /* =-=-=-=-=-=-=-=-=- MUL/IMUL =-=-=-=-=-=-=-=-=-= */
 
       case 0xAF: /* IMUL Ev, Gv */
-         delta = dis_mul_E_G ( sorb, sz, delta, True );
+         delta = dis_mul_E_G ( sorb, sz, delta );
          break;
 
       /* =-=-=-=-=-=-=-=-=- Jcond d32 -=-=-=-=-=-=-=-=-= */
index 43f98218fd9a401f135cdbea6a0e7ef18e5875d5..a80eebfc5c0e588905ce3a892002c590fd8f3bdb 100644 (file)
@@ -81,11 +81,12 @@ typedef
       UInt  guest_EBP;
       UInt  guest_ESI;
       UInt  guest_EDI;
-      /* 3-word thunk used to calculate O S Z A C P flags. */
+      /* 4-word thunk used to calculate O S Z A C P flags. */
       UInt  guest_CC_OP;
-      UInt  guest_CC_RES;
-      UInt  guest_CC_AUX;
-      /* The D flag is stored here, as either -1 or +1 */
+      UInt  guest_CC_DEP1;
+      UInt  guest_CC_DEP2;
+      UInt  guest_CC_NDEP;
+      /* The D flag is stored here, encoded as either -1 or +1 */
       UInt  guest_DFLAG;
       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
       UInt  guest_IDFLAG;
@@ -105,7 +106,7 @@ typedef
       UShort guest_GS;
       UShort guest_SS;
       /* Padding to make it have an 8-aligned size */
-      /* UInt   padding; */
+      UInt   padding;
    }
    VexGuestX86State;