From 0491f76cfbf6e26543a8d416a5f4e23557c7b11c Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 26 Dec 2006 02:31:01 +0000 Subject: [PATCH] Merge r1670/1 (ppc64 fe rld/rlw improvements) git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_2_BRANCH@1699 --- VEX/priv/guest-ppc/toIR.c | 52 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c index 9b9e5a7838..f57aa153e5 100644 --- a/VEX/priv/guest-ppc/toIR.c +++ b/VEX/priv/guest-ppc/toIR.c @@ -3288,6 +3288,7 @@ static Bool dis_int_rot ( UInt theInstr ) vassert(sh_imm < 32); if (mode64) { + IRTemp rTmp = newTemp(Ity_I64); mask64 = MASK64(31-MaskEnd, 31-MaskBeg); DIP("rlwinm%s r%u,r%u,%d,%d,%d\n", flag_rC ? ".":"", rA_addr, rS_addr, sh_imm, MaskBeg, MaskEnd); @@ -3295,8 +3296,10 @@ static Bool dis_int_rot ( UInt theInstr ) // rA = ((tmp32 || tmp32) & mask64) r = ROTL( unop(Iop_64to32, mkexpr(rS) ), mkU8(sh_imm) ); r = unop(Iop_32Uto64, r); - assign( rot, binop(Iop_Or64, r, - binop(Iop_Shl64, r, mkU8(32))) ); + assign( rTmp, r ); + r = NULL; + assign( rot, binop(Iop_Or64, mkexpr(rTmp), + binop(Iop_Shl64, mkexpr(rTmp), mkU8(32))) ); assign( rA, binop(Iop_And64, mkexpr(rot), mkU64(mask64)) ); } else { @@ -3311,7 +3314,7 @@ static Bool dis_int_rot ( UInt theInstr ) /* Special-case the ,32-n,n,31 form as that is just n-bit unsigned shift right, PPC32 p501 */ DIP("srwi%s r%u,r%u,%d\n", flag_rC ? ".":"", - rA_addr, rS_addr, sh_imm); + rA_addr, rS_addr, MaskBeg); assign( rA, binop(Iop_Shr32, mkexpr(rS), mkU8(MaskBeg)) ); } else { @@ -3356,7 +3359,6 @@ static Bool dis_int_rot ( UInt theInstr ) break; } - /* 64bit Integer Rotates */ case 0x1E: { msk_imm = ((msk_imm & 1) << 5) | (msk_imm >> 1); @@ -3402,24 +3404,38 @@ static Bool dis_int_rot ( UInt theInstr ) */ case 0x0: // rldicl (Rotl DWord Imm, Clear Left, PPC64 p558) - DIP("rldicl%s r%u,r%u,%u,%u\n", flag_rC ? ".":"", - rA_addr, rS_addr, sh_imm, msk_imm); - r = ROTL(mkexpr(rS), mkU8(sh_imm)); - mask64 = MASK64(0, 63-msk_imm); - assign( rA, binop(Iop_And64, r, mkU64(mask64)) ); + if (mode64 + && sh_imm + msk_imm == 64 && msk_imm >= 1 && msk_imm <= 63) { + /* special-case the ,64-n,n form as that is just + unsigned shift-right by n */ + DIP("srdi%s r%u,r%u,%u\n", + flag_rC ? ".":"", rA_addr, rS_addr, msk_imm); + assign( rA, binop(Iop_Shr64, mkexpr(rS), mkU8(msk_imm)) ); + } else { + DIP("rldicl%s r%u,r%u,%u,%u\n", flag_rC ? ".":"", + rA_addr, rS_addr, sh_imm, msk_imm); + r = ROTL(mkexpr(rS), mkU8(sh_imm)); + mask64 = MASK64(0, 63-msk_imm); + assign( rA, binop(Iop_And64, r, mkU64(mask64)) ); + } break; - /* later: deal with special case: - (msk_imm + sh_imm == 63) => SHR(63 - sh_imm) */ case 0x1: // rldicr (Rotl DWord Imm, Clear Right, PPC64 p559) - DIP("rldicr%s r%u,r%u,%u,%u\n", flag_rC ? ".":"", - rA_addr, rS_addr, sh_imm, msk_imm); - r = ROTL(mkexpr(rS), mkU8(sh_imm)); - mask64 = MASK64(63-msk_imm, 63); - assign( rA, binop(Iop_And64, r, mkU64(mask64)) ); + if (mode64 + && sh_imm + msk_imm == 63 && sh_imm >= 1 && sh_imm <= 63) { + /* special-case the ,n,63-n form as that is just + shift-left by n */ + DIP("sldi%s r%u,r%u,%u\n", + flag_rC ? ".":"", rA_addr, rS_addr, sh_imm); + assign( rA, binop(Iop_Shl64, mkexpr(rS), mkU8(sh_imm)) ); + } else { + DIP("rldicr%s r%u,r%u,%u,%u\n", flag_rC ? ".":"", + rA_addr, rS_addr, sh_imm, msk_imm); + r = ROTL(mkexpr(rS), mkU8(sh_imm)); + mask64 = MASK64(63-msk_imm, 63); + assign( rA, binop(Iop_And64, r, mkU64(mask64)) ); + } break; - /* later: deal with special case: - (msk_imm == sh_imm) => SHL(sh_imm) */ case 0x3: { // rldimi (Rotl DWord Imm, Mask Insert, PPC64 p560) IRTemp rA_orig = newTemp(ty); -- 2.47.2