|
From: <sv...@va...> - 2012-11-20 17:32:56
|
carll 2012-11-20 17:32:48 +0000 (Tue, 20 Nov 2012)
New Revision: 2563
Log:
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.
Modified files:
trunk/priv/host_ppc_isel.c
Modified: trunk/priv/host_ppc_isel.c (+3 -2)
===================================================================
--- trunk/priv/host_ppc_isel.c 2012-11-20 15:24:24 +00:00 (rev 2562)
+++ trunk/priv/host_ppc_isel.c 2012-11-20 17:32:48 +00:00 (rev 2563)
@@ -1484,6 +1484,7 @@
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 @@
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;
}
|