diff options
-rw-r--r-- | VEX/priv/guest_arm_toIR.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/VEX/priv/guest_arm_toIR.c b/VEX/priv/guest_arm_toIR.c index 04d68f805..437c9ab6e 100644 --- a/VEX/priv/guest_arm_toIR.c +++ b/VEX/priv/guest_arm_toIR.c @@ -16162,6 +16162,33 @@ DisResult disInstr_THUMB_WRK ( } } + /* -------------- (T2) SUB{S}.W Rd, SP, #constT ------------------- */ + if (INSN0(15,11) == BITS5(1,1,1,1,0) + && INSN0(9,5) == BITS5(0,1,1,0,1) + && INSN0(3,0) == BITS4(1,1,0,1) + && INSN1(15,15) == 0) { + UInt rN = 13; // SP + UInt rD = INSN1(11,8); + UInt bS = INSN0(4,4); + Bool valid = !isBadRegT(rD); + if (valid) { + IRTemp argL = newTemp(Ity_I32); + IRTemp argR = newTemp(Ity_I32); + IRTemp res = newTemp(Ity_I32); + UInt imm12 = (INSN0(10,10) << 11) | (INSN1(14,12) << 8) | INSN1(7,0); + assign(argL, getIRegT(rN)); + assign(argR, mkU32(imm12)); + assign(res, binop(Iop_Sub32, mkexpr(argL), mkexpr(argR))); + putIRegT(rD, mkexpr(res), condT); + if (bS == 1) { + setFlags_D1_D2( ARMG_CC_OP_SUB, argL, argR, condT ); + } + DIP("sub%s.w r%u, sp, #%u\n", + bS == 1 ? "s" : "", rD, imm12); + goto decode_success; + } + } + /* -------------- (T1) ADC{S}.W Rd, Rn, #constT -------------- */ /* -------------- (T1) SBC{S}.W Rd, Rn, #constT -------------- */ if (INSN0(15,11) == BITS5(1,1,1,1,0) |