Skip to content

Commit

Permalink
WIP: Support lsr.w on ARMv7 THUMB (#1363)
Browse files Browse the repository at this point in the history
* Support lsr.w on ARMv7 THUMB

`lsr.w R0, R0, R2` is processed in `_SR` in the `if rest and
rest[0].type == 'register'` branch despite being THUMB.

* Blacken
  • Loading branch information
nkaretnikov authored and Eric Hennenfent committed Jul 22, 2019
1 parent aa728d8 commit fedf9e9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
25 changes: 16 additions & 9 deletions manticore/native/cpu/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,16 @@ def read(self, nbits=None, with_carry=False):
value += self.cpu.instruction.size
if self.is_shifted():
shift = self.op.shift
value, carry = self.cpu._shift(value, shift.type, shift.value, carry)
# XXX: This is unnecessary repetition.
if shift.type in range(cs.arm.ARM_SFT_ASR_REG, cs.arm.ARM_SFT_RRX_REG + 1):
if self.cpu.mode == cs.CS_MODE_THUMB:
amount = shift.value.read()
else:
src_reg = self.cpu.instruction.reg_name(shift.value).upper()
amount = self.cpu.regfile.read(src_reg)
else:
amount = shift.value
value, carry = self.cpu._shift(value, shift.type, amount, carry)
if self.op.subtracted:
value = -value
if with_carry:
Expand Down Expand Up @@ -580,12 +589,7 @@ def _shift(cpu, value, _type, amount, carry):
amount = 1

elif _type in range(cs.arm.ARM_SFT_ASR_REG, cs.arm.ARM_SFT_RRX_REG + 1):
if cpu.mode == cs.CS_MODE_THUMB:
src = amount.read()
else:
src_reg = cpu.instruction.reg_name(amount).upper()
src = cpu.regfile.read(src_reg)
amount = Operators.EXTRACT(src, 0, 8)
amount = Operators.EXTRACT(amount, 0, 8)

if amount == 0:
return value, carry
Expand Down Expand Up @@ -1494,12 +1498,15 @@ def _SR(cpu, insn_id, dest, op, *rest):
carry = cpu.regfile.read("APSR_C")
if rest and rest[0].type == "register":
# FIXME we should make Operand.op private (and not accessible)
result, carry = cpu._shift(op.read(), srtype, rest[0].op.reg, carry)
src_reg = cpu.instruction.reg_name(rest[0].op.reg).upper()
amount = cpu.regfile.read(src_reg)
result, carry = cpu._shift(op.read(), srtype, amount, carry)
elif rest and rest[0].type == "immediate":
amount = rest[0].read()
result, carry = cpu._shift(op.read(), srtype, amount, carry)
elif cpu.mode == cs.CS_MODE_THUMB:
result, carry = cpu._shift(dest.read(), srtype, op, carry)
amount = op.read()
result, carry = cpu._shift(dest.read(), srtype, amount, carry)
else:
result, carry = op.read(with_carry=True)
dest.write(result)
Expand Down
5 changes: 5 additions & 0 deletions tests/native/test_armv7cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,11 @@ def test_thumb_lsrs(self):
def test_lsrw_thumb(self):
self.assertEqual(self.cpu.R5, 16 >> 3)

@itest_setregs("R0=11", "R2=2")
@itest_thumb("lsr.w R0, R0, R2")
def test_lsrw_thumb_reg(self):
self.assertEqual(self.cpu.R0, 11 >> 2)

@itest_setregs("R5=0", "R6=16")
@itest_thumb("asr.w R5, R6, #3")
def test_asrw_thumb(self):
Expand Down

0 comments on commit fedf9e9

Please sign in to comment.