From: Julian Seward Date: Sat, 2 Jul 2005 01:29:32 +0000 (+0000) Subject: Fix backend bug: the immediate on PPC32AMode_IR is 16 bits signed, not X-Git-Tag: svn/VALGRIND_3_0_1^2~88 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fa771c72e677ce1432a4230f20f2b942fba43e4e;p=thirdparty%2Fvalgrind.git Fix backend bug: the immediate on PPC32AMode_IR is 16 bits signed, not unsigned. git-svn-id: svn://svn.valgrind.org/vex/trunk@1246 --- diff --git a/VEX/priv/host-ppc32/hdefs.c b/VEX/priv/host-ppc32/hdefs.c index a06c09a712..d465ecfd7e 100644 --- a/VEX/priv/host-ppc32/hdefs.c +++ b/VEX/priv/host-ppc32/hdefs.c @@ -320,9 +320,9 @@ PPC32CondTest invertCondTest ( PPC32CondTest ct ) /* --------- PPCAMode: memory address expressions. --------- */ -PPC32AMode* PPC32AMode_IR ( UInt idx, HReg base ) { +PPC32AMode* PPC32AMode_IR ( Int idx, HReg base ) { PPC32AMode* am = LibVEX_Alloc(sizeof(PPC32AMode)); - vassert(idx < 0x10000); + vassert(idx >= -0x8000 && idx < 0x8000); am->tag = Pam_IR; am->Pam.IR.base = base; am->Pam.IR.index = idx; @@ -353,7 +353,7 @@ void ppPPC32AMode ( PPC32AMode* am ) { if (am->Pam.IR.index == 0) vex_printf("0("); else - vex_printf("0x%x(", am->Pam.IR.index); + vex_printf("%d(", (Int)am->Pam.IR.index); ppHRegPPC32(am->Pam.IR.base); vex_printf(")"); return; diff --git a/VEX/priv/host-ppc32/hdefs.h b/VEX/priv/host-ppc32/hdefs.h index 0b123fd491..4c34385ba6 100644 --- a/VEX/priv/host-ppc32/hdefs.h +++ b/VEX/priv/host-ppc32/hdefs.h @@ -202,7 +202,7 @@ extern PPC32CondTest invertCondTest ( PPC32CondTest ); typedef enum { - Pam_IR, /* Immediate + Reg */ + Pam_IR, /* Immediate (signed 16-bit) + Reg */ Pam_RR /* Reg1 + Reg2 */ } PPC32AModeTag; @@ -213,7 +213,7 @@ typedef union { struct { HReg base; - UInt index; + Int index; } IR; struct { HReg base; @@ -223,7 +223,7 @@ typedef } PPC32AMode; -extern PPC32AMode* PPC32AMode_IR ( UInt, HReg ); +extern PPC32AMode* PPC32AMode_IR ( Int, HReg ); extern PPC32AMode* PPC32AMode_RR ( HReg, HReg ); extern PPC32AMode* dopyPPC32AMode ( PPC32AMode* ); diff --git a/VEX/priv/host-ppc32/isel.c b/VEX/priv/host-ppc32/isel.c index 81533858da..4a9e58bc03 100644 --- a/VEX/priv/host-ppc32/isel.c +++ b/VEX/priv/host-ppc32/isel.c @@ -1471,13 +1471,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) result. The expression may only be a 32-bit one. */ +static Bool fits16bits ( UInt u ) +{ + /* Is u the same as the sign-extend of its lower 16 bits? */ + Int i = u & 0xFFFF; + i <<= 16; + i >>= 16; + return u == (UInt)i; +} + static Bool sane_AMode ( PPC32AMode* am ) { switch (am->tag) { case Pam_IR: return (hregClass(am->Pam.IR.base) == HRcInt32 && hregIsVirtual(am->Pam.IR.base) - && (am->Pam.IR.index < 0x10000)); + && fits16bits(am->Pam.IR.index)); case Pam_RR: return (hregClass(am->Pam.RR.base) == HRcInt32 && hregIsVirtual(am->Pam.IR.base) @@ -1501,14 +1510,14 @@ static PPC32AMode* iselIntExpr_AMode_wrk ( ISelEnv* env, IRExpr* e ) IRType ty = typeOfIRExpr(env->type_env,e); vassert(ty == Ity_I32); - /* Add32(expr,i), where i<0x10000 */ + /* Add32(expr,i), where i == sign-extend of (i & 0xFFFF) */ if (e->tag == Iex_Binop && e->Iex.Binop.op == Iop_Add32 && e->Iex.Binop.arg2->tag == Iex_Const && e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U32 - && e->Iex.Binop.arg2->Iex.Const.con->Ico.U32 < 0x10000) { + && fits16bits(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32)) { return PPC32AMode_IR(e->Iex.Binop.arg2->Iex.Const.con->Ico.U32, - iselIntExpr_R(env, e->Iex.Binop.arg1)); + iselIntExpr_R(env, e->Iex.Binop.arg1)); } /* Add32(expr,expr) */