diff options
| -rw-r--r-- | miasm2/arch/arm/arch.py | 2 | ||||
| -rw-r--r-- | miasm2/arch/arm/sem.py | 35 | ||||
| -rw-r--r-- | test/arch/arm/arch.py | 2 | ||||
| -rw-r--r-- | test/arch/arm/sem.py | 24 |
4 files changed, 63 insertions, 0 deletions
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py index f0e32834..f6b2e1cf 100644 --- a/miasm2/arch/arm/arch.py +++ b/miasm2/arch/arm/arch.py @@ -1449,6 +1449,8 @@ armop("mul", [bs('000000'), bs('0'), scc, rd, bs('0000'), rs, bs('1001'), rm], [rd, rm, rs]) armop("umull", [bs('000010'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs]) +armop("umlal", [bs('000010'), + bs('1'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs]) armop("smull", [bs('000011'), bs('0'), scc, rd, rdl, rs, bs('1001'), rm], [rdl, rd, rm, rs]) armop("smlal", [bs('000011'), bs('1'), scc, rd, diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py index 1ef0b624..06f6bddf 100644 --- a/miasm2/arch/arm/sem.py +++ b/miasm2/arch/arm/sem.py @@ -470,6 +470,37 @@ def muls(ir, instr, a, b, c = None): e.append(ExprAff(ir.IRDst, r)) return e +def umull(ir, instr, a, b, c, d): + e = [] + r = c.zeroExtend(64) * d.zeroExtend(64) + e.append(ExprAff(a, r[0:32])) + e.append(ExprAff(b, r[32:64])) + # r15/IRDst not allowed as output + return e + +def umlal(ir, instr, a, b, c, d): + e = [] + r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)]) + e.append(ExprAff(a, r[0:32])) + e.append(ExprAff(b, r[32:64])) + # r15/IRDst not allowed as output + return e + +def smull(ir, instr, a, b, c, d): + e = [] + r = c.signExtend(64) * d.signExtend(64) + e.append(ExprAff(a, r[0:32])) + e.append(ExprAff(b, r[32:64])) + # r15/IRDst not allowed as output + return e + +def smlal(ir, instr, a, b, c, d): + e = [] + r = c.signExtend(64) * d.signExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)]) + e.append(ExprAff(a, r[0:32])) + e.append(ExprAff(b, r[32:64])) + # r15/IRDst not allowed as output + return e def b(ir, instr, a): e = [] @@ -1012,6 +1043,10 @@ mnemo_condm0 = {'add': add, 'neg': neg, 'mul': mul, + 'umull': umull, + 'umlal': umlal, + 'smull': smull, + 'smlal': smlal, 'mla': mla, 'ldr': ldr, 'ldrd': ldrd, diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py index 5e3feb1d..19b1236e 100644 --- a/test/arch/arm/arch.py +++ b/test/arch/arm/arch.py @@ -191,6 +191,8 @@ reg_tests_arm = [ ("0002F5B0 UMULL R2, R3, R3, R2", "932283E0"), + ("0002F5B4 UMLAL R3, R4, R5, LR", + "953EA4E0"), ("C045D260 SMULL R3, R2, LR, R2", "9E32C2E0"), ("C03E6440 SMLAL R2, R0, R1, R0", diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py index f00ea662..51c42fd1 100644 --- a/test/arch/arm/sem.py +++ b/test/arch/arm/sem.py @@ -463,6 +463,30 @@ class TestARMSemantic(unittest.TestCase): self.assertEqual(compute('TST R2, R3', {R2: 0x80000000L, R3: 0x80000001L}), {zf: 0x0, R2: 0x80000000L, nf: 0x1, R3: 0x80000001L}) self.assertEqual(compute('TST R2, R3', {R2: 0x80000001L, R3: 0x80000000L}), {zf: 0x0, R2: 0x80000001L, nf: 0x1, R3: 0x80000000L}) + def test_UMULL(self): + self.assertEqual(compute('UMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L}) + self.assertEqual(compute('UMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}) + self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0x09a0cd05L, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('UMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0x00000001L, R4: 0xffffffffL, R5: 0x00000002L}) + + def test_UMLAL(self): + self.assertEqual(compute('UMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}) + self.assertEqual(compute('UMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}) + self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd06L, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('UMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x2L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0x09a0cd08L, R4: 0x12345678L, R5: 0x87654321L}) + + def test_SMULL(self): + self.assertEqual(compute('SMULL R1, R2, R4, R5', {R4: 0x0L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x0L, R5: 0x0L}) + self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L}) + self.assertEqual(compute('SMULL R0, R1, R2, R3', {R2: 0xffff0000L, R3: 0xffff0000L}), {R0: 0x0L, R1: 0x1L, R2: 0xffff0000L, R3: 0xffff0000L}) + self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d78L, R3: 0xf76c768dL, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('SMULL R2, R3, R4, R5', {R4: 0xffffffffL, R5: 0x00000002L}), {R2: 0xfffffffeL, R3: 0xffffffffL, R4: 0xffffffffL, R5: 0x00000002L}) + + def test_SMLAL(self): + self.assertEqual(compute('SMLAL R1, R2, R4, R5', {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}), {R1: 0x0L, R2: 0x0L, R4: 0x1L, R5: 0x0L}) + self.assertEqual(compute('SMLAL R0, R1, R2, R3', {R0: 0x0L, R1: 0x0L, R2: 0x1L, R3: 0x80808080L}), {R0: 0x80808080L, R1: 0xffffffffL, R2: 0x1L, R3: 0x80808080L}) + self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x0L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c768eL, R4: 0x12345678L, R5: 0x87654321L}) + self.assertEqual(compute('SMLAL R2, R3, R4, R5', {R2: 0xffffffffL, R3: 0x00000002L, R4: 0x12345678L, R5: 0x87654321L}), {R2: 0x70b88d77L, R3: 0xf76c7690L, R4: 0x12345678L, R5: 0x87654321L}) if __name__ == '__main__': testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic) |