From: Carl Love Date: Tue, 20 Nov 2012 17:32:48 +0000 (+0000) Subject: VEX, ppc fix use of modified value in the Iop_32HLto64 implementation X-Git-Tag: svn/VALGRIND_3_9_0^2~211 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f62a49abf3a7eeb2f925a7252f3a3bc78493a5c;p=thirdparty%2Fvalgrind.git VEX, ppc fix use of modified value in the Iop_32HLto64 implementation The issue with the Iop_32HLto64, as explained by Julian: One of the "rules of the game" of instruction selection is that the register returned by any of the isel* functions may not be modified -- if it needs to be modified, first copy the value off to a different register. The rule exists because, in this case, e->Iex.Binop.arg2 might be an IRExpr_RdTmp, in which case iselWordExpr_R simply returns the register which holds the value of the relevant IR temporary. And so if r_Lo is modified then any subsequent uses of that IR temporary will get the wrong value. In this case, r_Lo is modified without first copying it. This patch fixes the issue by assigning the result of the AND operation to a temporary and then using the temporary result in the OR operation thus avoiding using a modified value. This patch is for bugzilla 309922. git-svn-id: svn://svn.valgrind.org/vex/trunk@2563 --- diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 7b369cdeff..7b3b2d7334 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -1484,6 +1484,7 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) if (e->Iex.Binop.op == Iop_32HLto64) { HReg r_Hi = iselWordExpr_R(env, e->Iex.Binop.arg1); HReg r_Lo = iselWordExpr_R(env, e->Iex.Binop.arg2); + HReg r_Tmp = newVRegI(env); HReg r_dst = newVRegI(env); HReg msk = newVRegI(env); vassert(mode64); @@ -1491,10 +1492,10 @@ static HReg iselWordExpr_R_wrk ( ISelEnv* env, IRExpr* e ) addInstr(env, PPCInstr_Shft(Pshft_SHL, False/*64bit shift*/, r_dst, r_Hi, PPCRH_Imm(False,32))); addInstr(env, PPCInstr_LI(msk, 0xFFFFFFFF, mode64)); - addInstr(env, PPCInstr_Alu( Palu_AND, r_Lo, r_Lo, + addInstr(env, PPCInstr_Alu( Palu_AND, r_Tmp, r_Lo, PPCRH_Reg(msk) )); addInstr(env, PPCInstr_Alu( Palu_OR, r_dst, r_dst, - PPCRH_Reg(r_Lo) )); + PPCRH_Reg(r_Tmp) )); return r_dst; }