about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2014-10-06 13:34:26 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2014-10-06 13:34:26 +0200
commit35bde6dab646a60562ce0c17255bac34e0343660 (patch)
treea0a55a649a4809ba4c1085999cd7c14942e671cd
parentc50b122faf42d146c084525ac3c1b03cec4bda20 (diff)
downloadmiasm-35bde6dab646a60562ce0c17255bac34e0343660.tar.gz
miasm-35bde6dab646a60562ce0c17255bac34e0343660.zip
Arm: fix carry flag in sub operation; update reg tests
-rw-r--r--miasm2/arch/arm/sem.py23
-rw-r--r--miasm2/arch/x86/sem.py11
-rw-r--r--test/arch/arm/sem.py86
3 files changed, 75 insertions, 45 deletions
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 8f176947..72625eab 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -12,22 +12,13 @@ EXCEPT_PRIV_INSN = (1 << 17)
 
 
 def update_flag_zf(a):
-    return [ExprAff(zf, ExprCond(a, ExprInt_from(zf, 0), ExprInt_from(zf, 1)))]
+    return [ExprAff(zf, ExprCond(a, ExprInt1(0), ExprInt1(1)))]
 
 
 def update_flag_nf(a):
     return [ExprAff(nf, a.msb())]
 
 
-def update_flag_pf(a):
-    return [ExprAff(pf, ExprOp('parity', a))]
-
-
-def update_flag_af(a):
-    return [ExprAff(af, ExprCond(a & ExprInt_from(a, 0x10),
-                                 ExprInt_from(af, 1), ExprInt_from(af, 0)))]
-
-
 def update_flag_zn(a):
     e = []
     e += update_flag_zf(a)
@@ -61,14 +52,14 @@ def arith_flag(a, b, c):
 
 # checked: ok for adc add because b & c before +cf
 
-
-def update_flag_add_cf(a, b, c):
-    return ExprAff(cf,
-        ((((a ^ b) ^ c) ^ ((a ^ c) & (~(a ^ b)))).msb()) ^ ExprInt1(1))
+def update_flag_add_cf(op1, op2, res):
+    "Compute cf in @res = @op1 + @op2"
+    return ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb())
 
 
-def update_flag_add_of(a, b, c):
-    return ExprAff(of, (((a ^ c) & (~(a ^ b)))).msb())
+def update_flag_add_of(op1, op2, res):
+    "Compute of in @res = @op1 + @op2"
+    return ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb())
 
 
 # checked: ok for sbb add because b & c before +cf
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 781b3321..b192ee2c 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -123,13 +123,14 @@ def arith_flag(a, b, c):
 
 # checked: ok for adc add because b & c before +cf
 
+def update_flag_add_cf(op1, op2, res):
+    "Compute cf in @res = @op1 + @op2"
+    return ExprAff(cf, (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb())
 
-def update_flag_add_cf(a, b, c):
-    return ExprAff(cf, (((a ^ b) ^ c) ^ ((a ^ c) & (~(a ^ b)))).msb())
 
-
-def update_flag_add_of(a, b, c):
-    return ExprAff(of, (((a ^ c) & (~(a ^ b)))).msb())
+def update_flag_add_of(op1, op2, res):
+    "Compute of in @res = @op1 + @op2"
+    return ExprAff(of, (((op1 ^ res) & (~(op1 ^ op2)))).msb())
 
 
 # checked: ok for sbb add because b & c before +cf
diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py
index 7fcf9e85..a84a9499 100644
--- a/test/arch/arm/sem.py
+++ b/test/arch/arm/sem.py
@@ -109,9 +109,9 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADC                PC,    R4,   0x00000000 ',   {
                                  cf: 1, R4: 0xFFFFFFFF, PC: 0x55555555, }), {cf: 1,     R4: 0xFFFFFFFF, PC: 0x00000000, })
         self.assertEqual(compute('ADCS               R4,    R4,   0x80000000 ',   {cf: 0, R4: 0x80000000, }), {
-                         nf: 0, zf: 1, cf: 0, of: 1, R4: 0x00000000, })
+                         nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, })
         self.assertEqual(compute('ADCS               R4,    R4,   0xFF000000 ',   {cf: 1, R4: 0x00FFFFFE, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xFFFFFFFF, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFF, })
         self.assertEqual(compute('ADCS               PC,    R4,   0x00000000 ',   {
                                  cf: 0, R4: 0x00000000, PC: 0x55555555, }), {cf: 0,     R4: 0x00000000, PC: 0x00000000, })
         self.assertEqual(compute('ADCS               PC,    R4,   0xFF000000 ',   {
@@ -133,17 +133,17 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADC                R4,    R4,   R5    RRX   ',  {
                                  cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x80000080, R5: 0x00000101, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5          ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000000, }), {
-                         nf: 0, zf: 1, cf: 0, of: 0, R4: 0x00000000, R5: 0x00000000, })
+                         nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000000, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5    LSL 1 ',  {cf: 0, R4: 0x00000001, R5: 0x00000008, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x00000008, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5    LSR 2 ',  {cf: 1, R4: 0x00000000, R5: 0x80000041, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x20000011, R5: 0x80000041, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000011, R5: 0x80000041, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5    ASR 3 ',  {cf: 0, R4: 0x00000001, R5: 0x80000081, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5    ROR 4 ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
-                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000010, R5: 0x0000010F, })
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000010, R5: 0x0000010F, })
         self.assertEqual(compute('ADCS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
-                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0x80000080, R5: 0x00000101, })
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0x80000080, R5: 0x00000101, })
 
         # §A8.8.3:                 ADC{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
         self.assertEqual(compute('ADC                R4,    R6,   R4    LSL R5',  {
@@ -155,13 +155,13 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADC                R4,    R6,   R4    ROR R5',  {
                                  cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {cf: 1,     R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
         self.assertEqual(compute('ADCS               R4,    R6,   R4    LSL R5',  {cf: 0, R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
         self.assertEqual(compute('ADCS               R4,    R6,   R4    LSR R5',  {cf: 1, R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000012, R5: 0x80000004, R6: 0, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000012, R5: 0x80000004, R6: 0, })
         self.assertEqual(compute('ADCS               R4,    R6,   R4    ASR R5',  {cf: 0, R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
         self.assertEqual(compute('ADCS               R4,    R6,   R4    ROR R5',  {cf: 1, R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000010, R5: 0x00000F04, R6: 0, })
 
     def test_ADD(self):
         # §A8.8.{5,9}:             ADD{S}{<c>}{<q>} {<Rd>,} <Rn>, #<const>
@@ -176,9 +176,9 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADD                PC,    R4,   0x00000000 ',   {
                                  R4: 0xFFFFFFFF, PC: 0x55555555, }), {R4: 0xFFFFFFFF, PC: 0xFFFFFFFF, })
         self.assertEqual(compute('ADDS               R4,    R4,   0x80000000 ',   {R4: 0x80000000, }), {
-                         nf: 0, zf: 1, cf: 0, of: 1, R4: 0x00000000, })
+                         nf: 0, zf: 1, cf: 1, of: 1, R4: 0x00000000, })
         self.assertEqual(compute('ADDS               R4,    R4,   0xFF000000 ',   {R4: 0x00FFFFFE, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xFFFFFFFE, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xFFFFFFFE, })
         self.assertEqual(compute('ADDS               PC,    R4,   0x00000000 ',   {
                                  R4: 0x00000000, PC: 0x55555555, }), {R4: 0x00000000, PC: 0x00000000, })
         self.assertEqual(compute('ADDS               PC,    R4,   0xFF000000 ',   {
@@ -203,17 +203,17 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADD                R4,    R4,   R5    RRX   ',  {
                                  cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {cf: 1,     R4: 0x8000007F, R5: 0x00000101, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5          ',  {R4: 0xFFFFFFFF, R5: 0x00000001, }), {
-                         nf: 0, zf: 1, cf: 0, of: 0, R4: 0x00000000, R5: 0x00000001, })
+                         nf: 0, zf: 1, cf: 1, of: 0, R4: 0x00000000, R5: 0x00000001, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5    LSL 1 ',  {R4: 0x00000001, R5: 0x00000008, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x00000008, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x00000008, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5    LSR 2 ',  {R4: 0x00000000, R5: 0x80000041, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x20000010, R5: 0x80000041, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x20000010, R5: 0x80000041, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5    ASR 3 ',  {R4: 0x00000001, R5: 0x80000081, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF0000011, R5: 0x80000081, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF0000011, R5: 0x80000081, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x0000010F, }), {
-                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF000000F, R5: 0x0000010F, })
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF000000F, R5: 0x0000010F, })
         self.assertEqual(compute('ADDS               R4,    R4,   R5    RRX   ',  {cf: 1, R4: 0xFFFFFFFF, R5: 0x00000101, }), {
-                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0x8000007F, R5: 0x00000101, })
+                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0x8000007F, R5: 0x00000101, })
         # SP special part
         self.assertEqual(compute('ADD                R4,    SP,   R4    LSR 1 ',  {
                                  R4: 0x00000002, SP: 0x00000000, }), {R4: 0x00000001, SP: 0x00000000, })
@@ -228,13 +228,32 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('ADD                R4,    R6,   R4    ROR R5',  {
                                  R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
         self.assertEqual(compute('ADDS               R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: 0, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000010, R5: 0x00000004, R6: 0, })
         self.assertEqual(compute('ADDS               R4,    R6,   R4    LSR R5',  {R4: 0x00000110, R5: 0x80000004, R6: 0, }), {
-                         nf: 0, zf: 0, cf: 1, of: 0, R4: 0x00000011, R5: 0x80000004, R6: 0, })
+                         nf: 0, zf: 0, cf: 0, of: 0, R4: 0x00000011, R5: 0x80000004, R6: 0, })
         self.assertEqual(compute('ADDS               R4,    R6,   R4    ASR R5',  {R4: 0x80000010, R5: 0xF0000001, R6: 0, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xC0000008, R5: 0xF0000001, R6: 0, })
         self.assertEqual(compute('ADDS               R4,    R6,   R4    ROR R5',  {R4: 0x000000FF, R5: 0x00000F04, R6: 0, }), {
-                         nf: 1, zf: 0, cf: 1, of: 0, R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
+                         nf: 1, zf: 0, cf: 0, of: 0, R4: 0xF000000F, R5: 0x00000F04, R6: 0, })
+
+
+        # Test against qemu
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x00000002})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x00000001, R3: 0x80000000})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x80000000, R3: 0x80000000}),
+                         { nf: 0, zf: 1, cf: 1, of: 1, R2: 0x80000000, R3: 0x00000000})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0x7FFFFFFF, R3:0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 1, R2: 0x7FFFFFFF, R3:0xFFFFFFFE})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0, R3:0}),
+                         { nf: 0, zf: 1, cf: 0, of: 0, R2: 0, R3:0})
+        self.assertEqual(compute('ADDS               R3,    R2,   R3 ', {R2: 0xFFFFFFFF, R3:0xFFFFFFFF}),
+                         { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3:0xFFFFFFFE})
+
+
+
+
 
     def test_ADR(self):
         # §A8.8.12:                ADR{<c>}{<q>} <Rd>, <label>    <==>    ADD{<c>}{<q>} <Rd>, PC, #<const>
@@ -314,6 +333,25 @@ class TestARMSemantic(unittest.TestCase):
         # §A8.8.17:                ASR{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>      <==>    MOV{S}{<c>}{<q>} {<Rd>,} <Rn>, ASR <Rm>
         pass
 
+    def test_SUBS(self):
+        # Test against qemu
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x2, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x00000002, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x2}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x0, R3: 0xFFFFFFFF}),
+                         { nf: 0, zf: 0, cf: 0, of: 0, R2: 0x00000000, R3: 0x1})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0xFFFFFFFF, R3: 0x0}),
+                         { nf: 1, zf: 0, cf: 1, of: 0, R2: 0xFFFFFFFF, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x1, R3: 0x7FFFFFFF}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x00000001, R3: 0x80000002})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x7FFFFFFF, R3: 0x1}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x7FFFFFFF, R3: 0x7FFFFFFE})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000000, R3: 0x80000001}),
+                         { nf: 1, zf: 0, cf: 0, of: 0, R2: 0x80000000, R3: 0xFFFFFFFF})
+        self.assertEqual(compute('SUBS               R3,    R2,   R3 ', {R2: 0x80000001, R3: 0x80000000}),
+                         { nf: 0, zf: 0, cf: 1, of: 0, R2: 0x80000001, R3: 0x1})
+
 
 if __name__ == '__main__':
     testsuite = unittest.TestLoader().loadTestsFromTestCase(TestARMSemantic)