From: Julian Seward Date: Thu, 29 Jul 2004 22:26:03 +0000 (+0000) Subject: * Fix flag computation for neg instructions X-Git-Tag: svn/VALGRIND_3_0_1^2~1176 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f5121f3ce1f45330486291eebb7eb78d6da4d71;p=thirdparty%2Fvalgrind.git * Fix flag computation for neg instructions * Fix flag and result computation for 16/8-bit shl/shr/sar by amounts greater than the word size, which inconveniently is a well-defined (if useless) operation on x86. Sigh. Unfortunately the solution depends on IR shifts behaving as per x86, whereas it would be better to define IR shifts only to make sense for values in 0 .. 2^word_size-1. This needs to be fixed. * Implement another shrd case. shrdl doesn't work correctly according to the QEMU test suite. I don't know why. git-svn-id: svn://svn.valgrind.org/vex/trunk@158 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 97b29ee6bd..4659c6e0b4 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -2182,18 +2182,18 @@ UInt dis_Grp2 ( UChar sorb, /* shift_amt = shift_expr & mask */ assign(shift_amt, binop(Iop_And8, - shift_expr, mkU8(8*sz-1))); + shift_expr, mkU8(31 /* 8*sz-1 */))); /* dst1 = dst0 `shift` shift_amt */ assign(dst1, binop(mkSizedOp(ty,op8), mkexpr(dst0), mkexpr(shift_amt))); - /* subshift = dst0 `shift` (shift_amt - 1) */ + /* subshift = dst0 `shift` ((shift_amt - 1) & mask) */ assign(subshift, binop(mkSizedOp(ty,op8), mkexpr(dst0), binop(Iop_And8, binop(Iop_Sub8, mkexpr(shift_amt), mkU8(1)), - mkU8(8*sz-1)))); + mkU8(31 /* 8*sz-1 */)))); /* Build the flags thunk. */ setFlags_DSTus_DST1(op8, subshift, dst1, ty, shift_amt); @@ -2478,9 +2478,9 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta ) dst0 = newTemp(ty); src = newTemp(ty); dst1 = newTemp(ty); - assign(dst0, getIReg(sz,eregOfRM(modrm))); - assign(src, mkU(ty,0)); - assign(dst1, binop(mkSizedOp(ty,Iop_Sub8),mkexpr(src), mkexpr(dst0))); + assign(dst0, mkU(ty,0)); + assign(src, getIReg(sz,eregOfRM(modrm))); + assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src))); setFlags_SRC_DST1(Iop_Sub8, src, dst1, ty); putIReg(sz, eregOfRM(modrm), mkexpr(dst1)); DIP("neg%c %s\n", nameISize(sz), nameIReg(sz, eregOfRM(modrm))); @@ -2539,9 +2539,9 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta ) dst0 = newTemp(ty); src = newTemp(ty); dst1 = newTemp(ty); - assign(dst0, mkexpr(t1)); - assign(src, mkU(ty,0)); - assign(dst1, binop(mkSizedOp(ty,Iop_Sub8),mkexpr(src), mkexpr(dst0))); + assign(dst0, mkU(ty,0)); + assign(src, mkexpr(t1)); + assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src))); setFlags_SRC_DST1(Iop_Sub8, src, dst1, ty); storeLE( mkexpr(addr), mkexpr(dst1) ); DIP("neg%c %s\n", nameISize(sz), dis_buf); @@ -2583,7 +2583,6 @@ UInt dis_Grp4 ( UChar sorb, UInt delta ) modrm = getIByte(delta); if (epartIsReg(modrm)) { -//-- uInstr2(cb, GET, 1, ArchReg, eregOfRM(modrm), TempReg, t1); assign(t1, getIReg(1, eregOfRM(modrm))); switch (gregOfRM(modrm)) { case 0: /* INC */ @@ -7585,12 +7584,14 @@ static UInt disInstr ( UInt delta, Bool* isEnd ) mkU8(getIByte(d32)), True, /* literal */ dis_buf, False ); break; -//-- case 0xAD: /* SHRDv %cl,Gv,Ev */ -//-- modrm = getUChar(eip); -//-- eip = dis_SHLRD_Gv_Ev ( -//-- cb, sorb, eip, modrm, sz, ArchReg, R_CL, False ); -//-- break; -//-- + case 0xAD: /* SHRDv %cl,Gv,Ev */ + modrm = getIByte(delta); + delta = dis_SHLRD_Gv_Ev ( + sorb, delta, modrm, sz, + getIReg(1,R_ECX), False, /* not literal */ + "%cl", False ); + break; + //-- /* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */ //-- //-- case 0xC0: /* XADD Gb,Eb */