about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <devnull@localhost>2014-06-13 09:36:58 +0200
committerserpilliere <devnull@localhost>2014-06-13 09:36:58 +0200
commitb2f02006df9487905384cd7654e003dbf01419a0 (patch)
treeda1ded03ba7204368d6195a5fa1dd95e61a996e1
parent24b677448d875d408c1fff038bed27d2b223a3da (diff)
downloadmiasm-b2f02006df9487905384cd7654e003dbf01419a0.tar.gz
miasm-b2f02006df9487905384cd7654e003dbf01419a0.zip
Simplification: detect and handle == condition
Add corresponding regression tests
-rw-r--r--miasm2/expression/simplifications.py4
-rw-r--r--miasm2/expression/simplifications_common.py15
-rw-r--r--miasm2/expression/simplifications_cond.py30
-rw-r--r--test/expression/simplifications.py12
4 files changed, 38 insertions, 23 deletions
diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py
index d633cf3e..cbffb219 100644
--- a/miasm2/expression/simplifications.py
+++ b/miasm2/expression/simplifications.py
@@ -40,7 +40,9 @@ class ExpressionSimplifier(object):
                                      simplifications_cond.expr_simp_inf_unsigned_inversed],
                  m2_expr.ExprOp: [simplifications_cond.exec_inf_unsigned,
                                   simplifications_cond.exec_inf_signed,
-                                  simplifications_cond.expr_simp_inverse],
+                                  simplifications_cond.expr_simp_inverse,
+                                  simplifications_cond.exec_equal],
+                 m2_expr.ExprCond: [simplifications_cond.expr_simp_equal]
                  }
 
 
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index c907fe84..792a5a05 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -222,21 +222,6 @@ def simp_cst_propagation(e_s, e):
             2 ** args[1].arg >= args[0].args[1].arg):
             return ExprInt_from(args[0], 0)
 
-    # int == int => 0 or 1
-    if (op == '==' and
-        isinstance(args[0], ExprInt) and
-        isinstance(args[1], ExprInt)):
-        if args[0].arg == args[1].arg:
-            return ExprInt_from(args[0], 1)
-        else:
-            return ExprInt_from(args[0], 0)
-    #(A|int == 0)  => 0  with int != 0
-    if op == '==' and isinstance(args[1], ExprInt) and args[1].arg == 0:
-        if isinstance(args[0], ExprOp) and args[0].op == '|' and\
-                isinstance(args[0].args[1], ExprInt) and \
-                args[0].args[1].arg != 0:
-            return ExprInt_from(args[0], 0)
-
     # parity(int) => int
     if op == 'parity' and isinstance(args[0], ExprInt):
         return ExprInt1(parity(args[0].arg))
diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py
index ee23f6db..6688bc31 100644
--- a/miasm2/expression/simplifications_cond.py
+++ b/miasm2/expression/simplifications_cond.py
@@ -8,7 +8,7 @@
 # - Simplifications to catch known condition forms
 #
 # Conditions currently supported :
-# <u, <s
+# <u, <s, ==
 #
 # Authors : Fabrice DESCLAUX (CEA/DAM), Camille MOUGEY (CEA/DAM)
 #
@@ -54,6 +54,10 @@ def ExprOp_inf_unsigned(arg1, arg2):
     "Return an ExprOp standing for arg1 <s arg2"
     return __ExprOp_cond(TOK_INF_UNSIGNED, arg1, arg2)
 
+def ExprOp_equal(arg1, arg2):
+    "Return an ExprOp standing for arg1 == arg2"
+    return __ExprOp_cond(TOK_EQUAL, arg1, arg2)
+
 
 # Catching conditions forms
 
@@ -174,6 +178,17 @@ def expr_simp_inverse(expr_simp, e):
     else:
         return ExprOp_inf_unsigned(r[jok1], r[jok2])
 
+def expr_simp_equal(expr_simp, e):
+    """(x - y)?(0:1) == (x == y)"""
+
+    to_match = m2_expr.ExprCond(jok1 + jok2, m2_expr.ExprInt1(0), m2_expr.ExprInt1(1))
+    r = __MatchExprWrap(e,
+                        to_match,
+                        [jok1, jok2])
+    if r is False:
+        return e
+
+    return ExprOp_equal(r[jok1], expr_simp(-r[jok2]))
 
 # Compute conditions
 
@@ -206,6 +221,7 @@ def __comp_signed(arg1, arg2):
 
 def exec_inf_signed(expr_simp, e):
     "Compute x <s y"
+
     if e.op != TOK_INF_SIGNED:
         return e
 
@@ -215,3 +231,15 @@ def exec_inf_signed(expr_simp, e):
         return __comp_signed(arg1, arg2)
     else:
         return e
+
+def exec_equal(expr_simp, e):
+    "Compute x == y"
+
+    if e.op != TOK_EQUAL:
+        return e
+
+    arg1, arg2 = e.args
+    if isinstance(arg1, m2_expr.ExprInt) and isinstance(arg2, m2_expr.ExprInt):
+        return m2_expr.ExprInt1(1) if (arg1.arg == arg2.arg) else m2_expr.ExprInt1(0)
+    else:
+        return e
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index ac6b796d..6b437218 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -4,7 +4,7 @@
 from pdb import pm
 from miasm2.expression.expression import *
 from miasm2.expression.simplifications import expr_simp, ExpressionSimplifier
-from miasm2.expression.simplifications_cond import ExprOp_inf_signed, ExprOp_inf_unsigned
+from miasm2.expression.simplifications_cond import ExprOp_inf_signed, ExprOp_inf_unsigned, ExprOp_equal
 
 # Define example objects
 a = ExprId('a')
@@ -75,11 +75,6 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
             ExprInt32(0xFF123456)),
            (ExprOp("a>>", (ExprInt32(0xF1234567)), ExprInt32(28)),
             ExprInt32(0xFFFFFFFF)),
-           (ExprOp("==", ExprInt32(12), ExprInt32(10)), ExprInt32(0)),
-           (ExprOp("==", ExprInt32(12), ExprInt32(12)), ExprInt32(1)),
-           (ExprOp("==", a | ExprInt32(12), ExprInt32(0)), ExprInt32(0)),
-           (ExprOp("==", a | ExprInt32(12), ExprInt32(14)),
-            ExprOp("==", a | ExprInt32(12), ExprInt32(14))),
            (ExprOp("parity", ExprInt32(0xf)), ExprInt1(1)),
            (ExprOp("parity", ExprInt32(0xe)), ExprInt1(0)),
            (ExprInt32(0x4142)[:32], ExprInt32(0x4142)),
@@ -185,6 +180,11 @@ to_test = [
     (ExprOp_inf_signed(ExprInt32(-1), ExprInt32(3)), ExprInt1(1)),
     (ExprOp_inf_unsigned(a, b) ^ (a ^ b).msb(), ExprOp_inf_signed(a, b)),
     (ExprOp_inf_signed(a, b) ^ (a ^ b).msb(), ExprOp_inf_unsigned(a, b)),
+    (ExprOp_equal(ExprInt32(12), ExprInt32(10)), ExprInt1(0)),
+    (ExprOp_equal(ExprInt32(12), ExprInt32(12)), ExprInt1(1)),
+    (ExprOp_equal(ExprInt32(12), ExprInt32(-12)), ExprInt1(0)),
+    (ExprCond(a - b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, b)),
+    (ExprCond(a + b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, -b)),
 ]
 
 expr_simp_cond = ExpressionSimplifier()