about summary refs log tree commit diff stats
path: root/miasm2/expression/simplifications_common.py
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2015-11-13 17:25:37 +0100
committerAjax <commial@gmail.com>2015-11-16 09:22:29 +0100
commitc488c7780ada00daa5b1ca8a27a585abfacd2905 (patch)
tree962b1b37ae1450fdfb6ef7fc9075e024c4583d08 /miasm2/expression/simplifications_common.py
parent3eed941e88361f811496311014079c172e058a68 (diff)
downloadmiasm-c488c7780ada00daa5b1ca8a27a585abfacd2905.tar.gz
miasm-c488c7780ada00daa5b1ca8a27a585abfacd2905.zip
Simplifications: add cst_propagation for >>>/<<< c_rez
Diffstat (limited to 'miasm2/expression/simplifications_common.py')
-rw-r--r--miasm2/expression/simplifications_common.py33
1 files changed, 33 insertions, 0 deletions
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index fe69d0b9..a52debe6 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -327,6 +327,39 @@ def simp_cst_propagation(e_s, e):
                 new_args[i] = ExprOp(op, *arg), bound[i][0], bound[i][1]
             return ExprCompose(new_args)
 
+    # <<<c_rez, >>>c_rez
+    if op in [">>>c_rez", "<<<c_rez"]:
+        assert len(args) == 3
+        dest, rounds, cf = args
+        # Skipped if rounds is 0
+        if (isinstance(rounds, ExprInt) and
+            int(rounds.arg) == 0):
+            return dest
+        elif all(map(lambda x: isinstance(x, ExprInt), args)):
+            # The expression can be resolved
+            tmp = int(dest.arg)
+            cf = int(cf.arg)
+            size = dest.size
+            tmp_count = (int(rounds.arg) &
+                         (0x3f if size == 64 else 0x1f)) % (size + 1)
+            if op == ">>>c_rez":
+                while (tmp_count != 0):
+                    tmp_cf = tmp & 1;
+                    tmp = (tmp >> 1) + (cf << (size - 1))
+                    cf = tmp_cf
+                    tmp_count -= 1
+                    tmp &= int(dest.mask.arg)
+            elif op == "<<<c_rez":
+                while (tmp_count != 0):
+                    tmp_cf = (tmp >> (size - 1)) & 1
+                    tmp = (tmp << 1) + cf
+                    cf = tmp_cf
+                    tmp_count -= 1
+                    tmp &= int(dest.mask.arg)
+            else:
+                raise RuntimeError("Unknown operation: %s" % op)
+            return ExprInt(tmp, size=dest.size)
+
     return ExprOp(op, *args)