From: Julian Seward Date: Thu, 21 Jul 2005 21:33:57 +0000 (+0000) Subject: Reinstate rlwnm and change ROTL32 back to what it looked like before I X-Git-Tag: svn/VALGRIND_3_0_1^2~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=139122cab5ac4ff33d57d4e0bbf8bd45a4d3a211;p=thirdparty%2Fvalgrind.git Reinstate rlwnm and change ROTL32 back to what it looked like before I messed it up :-) git-svn-id: svn://svn.valgrind.org/vex/trunk@1288 --- diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index f9df56696a..350666c361 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -649,24 +649,34 @@ static IRExpr* /* :: Ity_I8 */ getXER_SO ( void ) } // ROTL(src32, rot_amt5) -static IRExpr* ROTL32 ( IRExpr* src, Int rot_amt ) +static IRExpr* ROTL32 ( IRExpr* src, IRExpr* rot_amt ) { + IRExpr* masked; vassert(typeOfIRExpr(irbb->tyenv,src) == Ity_I32); - vassert(rot_amt >= 0 && rot_amt < 32); + vassert(typeOfIRExpr(irbb->tyenv,rot_amt) == Ity_I32); - if (rot_amt == 0) - return src; - - vassert(rot_amt > 0 && rot_amt < 32); + masked + = unop(Iop_32to8, binop(Iop_And32, rot_amt, mkU32(31))); // (src << rot_amt) | (src >> (32-rot_amt)) - return binop(Iop_Or32, - binop(Iop_Shl32, src, mkU8(rot_amt)), - binop(Iop_Shr32, src, mkU8(32-rot_amt))); + /* Note: the MuxOX is not merely an optimisation; it's needed + because otherwise the Shr32 is a shift by the word size when + masked denotes zero. For rotates by immediates, a lot of + this junk gets folded out. */ + return + IRExpr_Mux0X( + masked, + /* zero rotate. */ + src, + /* non-zero rotate */ + binop( Iop_Or32, + binop(Iop_Shl32, src, masked), + binop(Iop_Shr32, src, binop(Iop_Sub8, mkU8(32), masked)) + ) + ); } - /*------------------------------------------------------------*/ /*--- Helpers for condition codes. ---*/ /*------------------------------------------------------------*/ @@ -2181,7 +2191,6 @@ static Bool dis_int_rot ( UInt theInstr ) UChar flag_Rc = toUChar((theInstr >> 0) & 1); /* theInstr[0] */ UInt mask = MASK(31-MaskEnd, 31-MaskBegin); - IRTemp rot_amt = newTemp(Ity_I8); IRTemp Rs = newTemp(Ity_I32); IRTemp Ra = newTemp(Ity_I32); IRTemp Rb = newTemp(Ity_I32); @@ -2190,33 +2199,35 @@ static Bool dis_int_rot ( UInt theInstr ) assign( Rb, getIReg(Rb_addr) ); switch (opc1) { - case 0x14: // rlwimi (Rotate Left Word Immediate then Mask Insert, PPC32 p500) + case 0x14: + // rlwimi (Rotate Left Word Immediate then Mask Insert, PPC32 p500) DIP("rlwimi%s r%d,r%d,%d,%d,%d\n", flag_Rc ? "." : "", Ra_addr, Rs_addr, sh_imm, MaskBegin, MaskEnd); // Ra = (ROTL(Rs, Imm) & mask) | (Ra & ~mask); assign( Ra, binop(Iop_Or32, binop(Iop_And32, mkU32(mask), - ROTL32(mkexpr(Rs), sh_imm)), + ROTL32(mkexpr(Rs), mkU32(sh_imm))), binop(Iop_And32, getIReg(Ra_addr), mkU32(~mask))) ); break; - case 0x15: // rlwinm (Rotate Left Word Immediate then AND with Mask, PPC32 p501) + case 0x15: + // rlwinm (Rotate Left Word Immediate then AND with Mask, PPC32 p501) DIP("rlwinm%s r%d,r%d,%d,%d,%d\n", flag_Rc ? "." : "", Ra_addr, Rs_addr, sh_imm, MaskBegin, MaskEnd); // Ra = ROTL(Rs, Imm) & mask - assign( Ra, binop(Iop_And32, ROTL32(mkexpr(Rs), sh_imm), + assign( Ra, binop(Iop_And32, ROTL32(mkexpr(Rs), mkU32(sh_imm)), mkU32(mask)) ); break; -//zz case 0x17: // rlwnm (Rotate Left Word then AND with Mask, PPC32 p503 -//zz DIP("rlwnm%s r%d,r%d,r%d,%d,%d\n", flag_Rc ? "." : "", -//zz Ra_addr, Rs_addr, Rb_addr, MaskBegin, MaskEnd); -//zz // Ra = ROTL(Rs, Rb[0-4]) & mask -//zz assign( rot_amt, -//zz unop(Iop_32to8, binop(Iop_And32, mkexpr(Rb), mkU32(0x1F))) ); -//zz assign( Ra, binop(Iop_And32, -//zz ROTL32(mkexpr(Rs), mkexpr(rot_amt)), mkU32(mask)) ); -//zz break; + case 0x17: + // rlwnm (Rotate Left Word then AND with Mask, PPC32 p503 + DIP("rlwnm%s r%d,r%d,r%d,%d,%d\n", flag_Rc ? "." : "", + Ra_addr, Rs_addr, Rb_addr, MaskBegin, MaskEnd); + // Ra = ROTL(Rs, Rb[0-4]) & mask + // note, ROTL32 does the masking, so we don't do it here + assign( Ra, binop(Iop_And32, ROTL32(mkexpr(Rs), mkexpr(Rb)), + mkU32(mask)) ); + break; default: vex_printf("dis_int_rot(PPC32)(opc1)\n");