From: Julian Seward Date: Tue, 3 May 2005 12:20:15 +0000 (+0000) Subject: x86 guest: generate Iop_Neg* in the x86->IR phase. Intent is to X-Git-Tag: svn/VALGRIND_3_0_1^2~175 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e48f61114308fee273742273e775da057048632d;p=thirdparty%2Fvalgrind.git x86 guest: generate Iop_Neg* in the x86->IR phase. Intent is to ensure that the non-shadow (real) computation done by the program will fail if Iop_Neg* is incorrectly handled somehow. Until this point, Iop_Neg* is only generated by memcheck and so it will not be obvious if it is mishandled. IOW, this commit enhances verifiability of the x86-IR-x86 pipeline. git-svn-id: svn://svn.valgrind.org/vex/trunk@1159 --- diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 4e668ced9b..6d41c537ef 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -848,7 +848,7 @@ static IROp mkSizedOp ( IRType ty, IROp op8 ) || op8 == Iop_Or8 || op8 == Iop_And8 || op8 == Iop_Xor8 || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8 || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8 - || op8 == Iop_Not8 ); + || op8 == Iop_Not8 || op8 == Iop_Neg8); adj = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2); return adj + op8; } @@ -2761,7 +2761,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta ) dst1 = newTemp(ty); assign(dst0, mkU(ty,0)); assign(src, getIReg(sz,eregOfRM(modrm))); - assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src))); + assign(dst1, unop(mkSizedOp(ty,Iop_Neg8), mkexpr(src))); 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))); @@ -2810,7 +2810,6 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta ) DIP("test%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); break; } - /* probably OK, but awaiting test case */ case 2: /* NOT */ storeLE( mkexpr(addr), unop(mkSizedOp(ty,Iop_Not8), mkexpr(t1))); DIP("not%c %s\n", nameISize(sz), dis_buf); @@ -2821,7 +2820,7 @@ UInt dis_Grp3 ( UChar sorb, Int sz, UInt delta ) dst1 = newTemp(ty); assign(dst0, mkU(ty,0)); assign(src, mkexpr(t1)); - assign(dst1, binop(mkSizedOp(ty,Iop_Sub8), mkexpr(dst0), mkexpr(src))); + assign(dst1, unop(mkSizedOp(ty,Iop_Neg8), mkexpr(src))); setFlags_DEP1_DEP2(Iop_Sub8, dst0, src, ty); storeLE( mkexpr(addr), mkexpr(dst1) ); DIP("neg%c %s\n", nameISize(sz), dis_buf); diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 645cacc282..4c60925784 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -200,8 +200,9 @@ extern void ppIRTemp ( IRTemp ); typedef enum { - /* Do not change this ordering. The IR generators - rely on (eg) Iop_Add64 == IopAdd8 + 3. */ + /* -- Do not change this ordering. The IR generators rely on + (eg) Iop_Add64 == IopAdd8 + 3. -- */ + Iop_INVALID=0x13000, Iop_Add8, Iop_Add16, Iop_Add32, Iop_Add64, Iop_Sub8, Iop_Sub16, Iop_Sub32, Iop_Sub64, @@ -218,6 +219,10 @@ typedef Iop_CmpNE8, Iop_CmpNE16, Iop_CmpNE32, Iop_CmpNE64, /* Tags for unary ops */ Iop_Not8, Iop_Not16, Iop_Not32, Iop_Not64, + Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64, + + /* -- Ordering not important after here. -- */ + /* Widening multiplies */ Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64, Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64, @@ -229,7 +234,6 @@ typedef zero. You must ensure they are never given a zero argument. */ - /* Ordering not important after here. */ Iop_CmpLT32S, Iop_CmpLT64S, Iop_CmpLE32S, Iop_CmpLE64S, Iop_CmpLT32U, Iop_CmpLT64U, @@ -237,7 +241,6 @@ typedef /* As a sop to Valgrind-Memcheck, the following are useful. */ Iop_CmpNEZ8, Iop_CmpNEZ16, Iop_CmpNEZ32, Iop_CmpNEZ64, - Iop_Neg8, Iop_Neg16, Iop_Neg32, Iop_Neg64, /* Division */ /* TODO: clarify semantics wrt rounding, negative values, whatever */