From: Julian Seward Date: Sun, 26 Sep 2010 00:48:41 +0000 (+0000) Subject: Support REV and REV16 in Thumb mode, both short and long encodings. X-Git-Tag: svn/VALGRIND_3_6_1^2~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6cc33a7bcba309e15059778a78d7445bf8a04e6a;p=thirdparty%2Fvalgrind.git Support REV and REV16 in Thumb mode, both short and long encodings. git-svn-id: svn://svn.valgrind.org/vex/trunk@2046 --- diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c index b2c8b42b29..27fface4aa 100644 --- a/VEX/priv/guest_arm_toIR.c +++ b/VEX/priv/guest_arm_toIR.c @@ -2709,6 +2709,44 @@ static IRTemp gen_BITREV ( IRTemp x0 ) } +/* Generate IR to do rearrange bytes 3:2:1:0 in a word in to the order + 0:1:2:3 (aka byte-swap). */ +static IRTemp gen_REV ( IRTemp arg ) +{ + IRTemp res = newTemp(Ity_I32); + assign(res, + binop(Iop_Or32, + binop(Iop_Shl32, mkexpr(arg), mkU8(24)), + binop(Iop_Or32, + binop(Iop_And32, binop(Iop_Shl32, mkexpr(arg), mkU8(8)), + mkU32(0x00FF0000)), + binop(Iop_Or32, + binop(Iop_And32, binop(Iop_Shr32, mkexpr(arg), mkU8(8)), + mkU32(0x0000FF00)), + binop(Iop_And32, binop(Iop_Shr32, mkexpr(arg), mkU8(24)), + mkU32(0x000000FF) ) + )))); + return res; +} + + +/* Generate IR to do rearrange bytes 3:2:1:0 in a word in to the order + 2:3:0:1 (swap within lo and hi halves). */ +static IRTemp gen_REV16 ( IRTemp arg ) +{ + IRTemp res = newTemp(Ity_I32); + assign(res, + binop(Iop_Or32, + binop(Iop_And32, + binop(Iop_Shl32, mkexpr(arg), mkU8(8)), + mkU32(0xFF00FF00)), + binop(Iop_And32, + binop(Iop_Shr32, mkexpr(arg), mkU8(8)), + mkU32(0x00FF00FF)))); + return res; +} + + /*------------------------------------------------------------*/ /*--- Advanced SIMD (NEON) instructions ---*/ /*------------------------------------------------------------*/ @@ -13728,31 +13766,8 @@ DisResult disInstr_ARM_WRK ( if (rM != 15 && rD != 15) { IRTemp rMt = newTemp(Ity_I32); assign(rMt, getIRegA(rM)); - IRExpr* res; - if (isREV) { - res - = binop(Iop_Or32, - binop(Iop_Shl32, mkexpr(rMt), mkU8(24)), - binop(Iop_Or32, - binop(Iop_And32, binop(Iop_Shl32, mkexpr(rMt), mkU8(8)), - mkU32(0x00FF0000)), - binop(Iop_Or32, - binop(Iop_And32, binop(Iop_Shr32, mkexpr(rMt), mkU8(8)), - mkU32(0x0000FF00)), - binop(Iop_And32, binop(Iop_Shr32, mkexpr(rMt), mkU8(24)), - mkU32(0x000000FF) ) - ))); - } else { - res - = binop(Iop_Or32, - binop(Iop_And32, - binop(Iop_Shl32, mkexpr(rMt), mkU8(8)), - mkU32(0xFF00FF00)), - binop(Iop_And32, - binop(Iop_Shr32, mkexpr(rMt), mkU8(8)), - mkU32(0x00FF00FF))); - } - putIRegA(rD, res, condT, Ijk_Boring); + IRTemp res = isREV ? gen_REV(rMt) : gen_REV16(rMt); + putIRegA(rD, mkexpr(res), condT, Ijk_Boring); DIP("rev%s%s r%u, r%u\n", isREV ? "" : "16", nCC(INSN_COND), rD, rM); goto decode_success; @@ -14567,6 +14582,21 @@ DisResult disInstr_THUMB_WRK ( goto decode_success; } + case 0x2E8: // REV + case 0x2E9: { // REV16 + /* ---------------- REV Rd, Rm ---------------- */ + /* ---------------- REV16 Rd, Rm ---------------- */ + UInt rM = INSN0(5,3); + UInt rD = INSN0(2,0); + Bool isREV = INSN0(15,6) == 0x2E8; + IRTemp arg = newTemp(Ity_I32); + assign(arg, getIRegT(rM)); + IRTemp res = isREV ? gen_REV(arg) : gen_REV16(arg); + putIRegT(rD, mkexpr(res), condT); + DIP("rev%s r%u, r%u\n", isREV ? "" : "16", rD, rM); + goto decode_success; + } + default: break; /* examine the next shortest prefix */ @@ -17409,6 +17439,26 @@ DisResult disInstr_THUMB_WRK ( } } + /* ------------------- (T2) REV ------------------- */ + /* ------------------- (T2) REV16 ------------------- */ + if (INSN0(15,4) == 0xFA9 + && INSN1(15,12) == BITS4(1,1,1,1) + && ( INSN1(7,4) == BITS4(1,0,0,0) // REV + || INSN1(7,4) == BITS4(1,0,0,1))) { // REV16 + UInt rM1 = INSN0(3,0); + UInt rD = INSN1(11,8); + UInt rM2 = INSN1(3,0); + Bool isREV = INSN1(7,4) == BITS4(1,0,0,0); + if (!isBadRegT(rD) && !isBadRegT(rM1) && rM1 == rM2) { + IRTemp arg = newTemp(Ity_I32); + assign(arg, getIRegT(rM1)); + IRTemp res = isREV ? gen_REV(arg) : gen_REV16(arg); + putIRegT(rD, mkexpr(res), condT); + DIP("rev%s r%u, r%u\n", isREV ? "" : "16", rD, rM1); + goto decode_success; + } + } + /* -------------- (T1) MSR apsr, reg -------------- */ if (INSN0(15,4) == 0xF38 && INSN1(15,12) == BITS4(1,0,0,0) && INSN1(9,0) == 0x000) {