about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2015-07-23 08:37:59 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-07-23 08:37:59 +0200
commite9be7c7628cd47acfa3793956c667c575a8d073e (patch)
treef9bad9cca1fa99bc82decaaa2429417dfd595a8b
parent97463558ea31744a24e3330ab3227e2098878d03 (diff)
downloadmiasm-e9be7c7628cd47acfa3793956c667c575a8d073e.tar.gz
miasm-e9be7c7628cd47acfa3793956c667c575a8d073e.zip
Expr/Simplifications: add shift/slice reduction
-rw-r--r--miasm2/expression/simplifications_common.py15
1 files changed, 15 insertions, 0 deletions
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index 82f2cf75..d89b7518 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -477,6 +477,21 @@ def simp_slice(e_s, e):
         args = [e_s.expr_simp_wrapper(a[e.start:e.stop]) for a in e.arg.args]
         e = ExprOp(e.arg.op, *args)
 
+    # (a >> int)[x:y] => a[x+int:y+int] with int+y <= a.size
+    # (a << int)[x:y] => a[x-int:y-int] with x-int >= 0
+    elif (isinstance(e.arg, ExprOp) and e.arg.op in [">>", "<<"] and
+          isinstance(e.arg.args[1], ExprInt)):
+        arg, shift = e.arg.args
+        shift = int(shift.arg)
+        if e.arg.op == ">>":
+            if shift + e.stop <= arg.size:
+                return arg[e.start + shift:e.stop + shift]
+        elif e.arg.op == "<<":
+            if e.start - shift >= 0:
+                return arg[e.start - shift:e.stop - shift]
+        else:
+            raise ValueError('Bad case')
+
     return e