From: Julian Seward Date: Sat, 10 Jul 2004 22:43:54 +0000 (+0000) Subject: Yet more cases in x86toIR. X-Git-Tag: svn/VALGRIND_3_0_1^2~1263 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6f823f735304e2145f5a2dc740de09b9ec390d4;p=thirdparty%2Fvalgrind.git Yet more cases in x86toIR. git-svn-id: svn://svn.valgrind.org/vex/trunk@71 --- diff --git a/VEX/priv/guest-x86/x86toIR.c b/VEX/priv/guest-x86/x86toIR.c index 493868000c..ed00438cd4 100644 --- a/VEX/priv/guest-x86/x86toIR.c +++ b/VEX/priv/guest-x86/x86toIR.c @@ -9,6 +9,7 @@ /* TODO fix jmpkind fields XOR reg with itself + Clean up setFlagsARITH */ /* Translates x86 code to IR. */ @@ -199,14 +200,40 @@ static UInt getSDisp8 ( UInt delta ) account. Supplied value is 0 .. 7 and in the Intel instruction encoding. */ -static IRExpr* getIReg ( Int sz, UInt archreg ) +static IRType szToITy ( Int n ) +{ + switch (n) { + case 1: return Ity_I8; + case 2: return Ity_I16; + case 4: return Ity_I32; + default: vpanic("szToITy(x86)"); + } +} + +static Int integerGuestRegOffset ( Int sz, UInt archreg ) { - vassert(sz == 1 || sz == 2 || sz == 4); vassert(archreg < 8); vassert(!host_is_bigendian); - vassert(sz == 4); - return IRExpr_Get(OFFB_EAX + 4*archreg, Ity_I32); + + /* Correct for little-endian host only. */ + switch (sz) { + case 2: + case 4: return OFFB_EAX + 4*archreg; + case 1: if (archreg < 4) + return OFFB_EAX + 4*archreg + 0; + else + return OFFB_EAX + 4*(archreg-4) + 1; + default: vpanic("integerGuestRegOffset(x86,le)"); + } +} + +static IRExpr* getIReg ( Int sz, UInt archreg ) +{ + vassert(sz == 1 || sz == 2 || sz == 4); + vassert(archreg < 8); + return IRExpr_Get( integerGuestRegOffset(sz,archreg), + szToITy(sz) ); } /* Ditto, but write to a reg instead. */ @@ -217,7 +244,8 @@ static void putIReg ( Int sz, UInt archreg, IRExpr* e ) vassert(!host_is_bigendian); vassert(sz == 4); - stmt( IRStmt_Put(NULL, OFFB_EAX + 4*archreg, e) ); + + stmt( IRStmt_Put(NULL, integerGuestRegOffset(sz,archreg), e) ); } static void assign ( IRTemp dst, IRExpr* e ) @@ -280,14 +308,18 @@ static IROp mkSizedOp ( IRType ty, IROp op8 ) return adj + op8; } -static IRType szToITy ( Int n ) +static IROp mkWidenOp ( Int szSmall, Int szBig, Bool signd ) { - switch (n) { - case 1: return Ity_I8; - case 2: return Ity_I16; - case 4: return Ity_I32; - default: vpanic("szToITy(x86)"); + if (szSmall == 1 && szBig == 4) { + return signd ? Iop_8Sto32 : Iop_8Uto32; + } + if (szSmall == 1 && szBig == 2) { + return signd ? Iop_8Sto16 : Iop_8Uto16; + } + if (szSmall == 2 && szBig == 4) { + return signd ? Iop_16Sto32 : Iop_16Uto32; } + vpanic("mkWidenOp(x86)"); } @@ -311,6 +343,7 @@ static void setFlagsARITH ( IROp op8, ccOp = ty==Ity_I8 ? 0 : (ty==Ity_I16 ? 1 : 2); switch (op8) { + case Iop_Or8: case Iop_And8: case Iop_Xor8: ccOp += CC_OP_LOGICB; @@ -340,6 +373,13 @@ static void setFlagsARITH ( IROp op8, stmt( IRStmt_Put(guard, OFFB_CC_SRC, mkexpr(cc_src)) ); stmt( IRStmt_Put(guard, OFFB_CC_DST, mkexpr(cc_dst)) ); break; + case Iop_Shl8: + ccOp += CC_OP_SHLB; + /* CC_SRC = undershifted %d after, CC_DST = %d afterwards */ + stmt( IRStmt_Put(guard, OFFB_CC_OP, mkU32(ccOp)) ); + stmt( IRStmt_Put(guard, OFFB_CC_SRC, mkexpr(cc_src)) ); + stmt( IRStmt_Put(guard, OFFB_CC_DST, mkexpr(cc_dst)) ); + break; default: ppIROp(op8); vpanic("setFlagsARITH(x86)"); @@ -938,17 +978,17 @@ static Char nameISize ( Int size ) /*--- JMP helpers ---*/ /*------------------------------------------------------------*/ -void jmp_lit( Addr32 d32 ) +static void jmp_lit( Addr32 d32 ) { irbb->next = IRNext_UJump( IRConst_U32(d32) ); } -void jmp_treg( IRTemp t ) +static void jmp_treg( IRTemp t ) { irbb->next = IRNext_IJump( mkexpr(t) ); } -void jcc_01( Condcode cond, Addr32 d32_false, Addr32 d32_true ) +static void jcc_01( Condcode cond, Addr32 d32_false, Addr32 d32_true ) { Bool invert; Condcode condPos; @@ -1221,13 +1261,14 @@ IRExpr* disAMode ( Int* len, UChar sorb, UInt delta, UChar* buf ) DIS(buf, "%s%d(%s,%s,%d)", sorbTxt(sorb), d, nameIReg(4,base_r), nameIReg(4,index_r), 1< Ity_Bit, just select bit[0] */ }