about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <serpilliere@users.noreply.github.com>2015-01-26 09:46:00 +0100
committerserpilliere <serpilliere@users.noreply.github.com>2015-01-26 09:46:00 +0100
commitc59591a779ac644d1b50a720aea93cd8b36a2ddf (patch)
treea9d2bd8787514a8048e9c22f9874c03a184ffbe5
parentbd49d610cc67b7d36cd331700314fd36967fdcbb (diff)
parent03be04f520f448a4e3d1d2a9ff18eb0f77e7cc84 (diff)
downloadmiasm-c59591a779ac644d1b50a720aea93cd8b36a2ddf.tar.gz
miasm-c59591a779ac644d1b50a720aea93cd8b36a2ddf.zip
Merge pull request #47 from laanwj/2015_01_arm_sem_mull
arm: Add umull,umlal,smull,smlal to sem
-rw-r--r--miasm2/arch/arm/sem.py35
-rw-r--r--test/arch/arm/sem.py24
2 files changed, 59 insertions, 0 deletions
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/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)