From: Julian Seward Date: Fri, 5 Nov 2004 19:49:09 +0000 (+0000) Subject: Major overhaul of x86 guest eflags handling, so as to make one X-Git-Tag: svn/VALGRIND_3_0_1^2~838 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4001342f62c805dbcb238f54f6dd623bf9b04405;p=thirdparty%2Fvalgrind.git Major overhaul of x86 guest eflags handling, so as to make one 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 --- diff --git a/VEX/head20041019/none/nl_main.c b/VEX/head20041019/none/nl_main.c index 8b52c014c8..fd644a77ad 100644 --- a/VEX/head20041019/none/nl_main.c +++ b/VEX/head20041019/none/nl_main.c @@ -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; } diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 896d6e40b0..84782fe0e6 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -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 }; diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index d9608a1577..3344043252 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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), diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index e75a08d05d..616b1c98eb 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -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 diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index be34d91b90..0944ec1532 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -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 { diff --git a/VEX/pub/libvex_guest_x86.h b/VEX/pub/libvex_guest_x86.h index ababaad358..43f98218fd 100644 --- a/VEX/pub/libvex_guest_x86.h +++ b/VEX/pub/libvex_guest_x86.h @@ -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. */