From f0a6f66d77ad2db3e648bf0601c2846b4a7381e0 Mon Sep 17 00:00:00 2001 From: Yan Date: Fri, 24 Mar 2017 17:55:24 -0400 Subject: [PATCH] Update MOV implementation (carry) (#105) * Update MOV implementation wrt carry * Remove intermediate flags dict * Fix register reference * Document MOV to conform with current standard --- manticore/core/cpu/arm.py | 23 ++++++++++------------- tests/test_armv7cpu.py | 10 ++++++++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/manticore/core/cpu/arm.py b/manticore/core/cpu/arm.py index 9e78b01..98899c2 100644 --- a/manticore/core/cpu/arm.py +++ b/manticore/core/cpu/arm.py @@ -471,21 +471,18 @@ class Armv7Cpu(Cpu): @instruction def MOV(cpu, dest, src): - '''TODO: MOV imm should technically set carry bit. - XXX: We now set carry bit when it's a shift operation - Note: If src operand is PC, temporarily release our logical PC - view and conform to the spec, which dictates PC = curr instr + 8 ''' - result, carry = src.read(withCarry=True) - dest.write(result) + Implement the MOV{S} instruction. - # Setting flags in two separate setFlags calls clears earlier flags, set - # it once - flags = {'N' : HighBit(result), - 'Z': (result == 0)} - if src.is_shifted(): - flags['C'] = carry - cpu.setFlags(**flags) + Note: If src operand is PC, temporarily release our logical PC + view and conform to the spec, which dictates PC = curr instr + 8 + + :param Armv7Operand dest: The destination operand; register. + :param Armv7Operand src: The source operand; register or immediate. + ''' + result, carry_out = src.read(withCarry=True) + dest.write(result) + cpu.setFlags(C=carry_out, N=HighBit(result), Z=(result == 0)) def _handleWriteback(cpu, src, dest, offset): # capstone bug doesn't set writeback correctly for postindex reg diff --git a/tests/test_armv7cpu.py b/tests/test_armv7cpu.py index bac3492..7250ead 100644 --- a/tests/test_armv7cpu.py +++ b/tests/test_armv7cpu.py @@ -234,11 +234,17 @@ class Armv7CpuInstructions(unittest.TestCase): @itest_custom("movs r0, 0xff000000") def test_movs_imm_modified_imm_max(self): - pre_c = self.rf.read('APSR_C') pre_v = self.rf.read('APSR_V') self.cpu.execute() self.assertEqual(self.rf.read('R0'), 0xff000000) - self._checkFlagsNZCV(1, 0, pre_c, pre_v) + self._checkFlagsNZCV(1, 0, 1, pre_v) + + @itest_custom("movs r0, 0x0e000000") + def test_movs_imm_modified_imm_sans_carry(self): + pre_v = self.rf.read('APSR_V') + self.cpu.execute() + self.assertEqual(self.rf.read('R0'), 0x0e000000) + self._checkFlagsNZCV(0, 0, 0, pre_v) @itest_custom("movs r0, r1") def test_movs_reg(self):