about summary refs log tree commit diff stats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--miasm2/expression/modint.py8
-rw-r--r--miasm2/expression/simplifications_common.py33
-rw-r--r--test/expression/simplifications.py19
3 files changed, 56 insertions, 4 deletions
diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py
index 8bad5ccb..76896eb9 100644
--- a/miasm2/expression/modint.py
+++ b/miasm2/expression/modint.py
@@ -44,9 +44,9 @@ class moduint(object):
     def __div__(self, y):
         if isinstance(y, moduint):
             cls = self.maxcast(y)
-            return cls(self.arg / y.arg)
+            return cls(int(float(self.arg) / y.arg))
         else:
-            return self.__class__(self.arg / y)
+            return self.__class__(int(float(self.arg) / y))
 
     def __int__(self):
         return int(self.arg)
@@ -67,9 +67,9 @@ class moduint(object):
     def __mod__(self, y):
         if isinstance(y, moduint):
             cls = self.maxcast(y)
-            return cls(self.arg % y.arg)
+            return cls(self.arg - (y.arg * int(float(self.arg)/y.arg)))
         else:
-            return self.__class__(self.arg % y)
+            return self.__class__(self.arg - (y * int(float(self.arg)/y)))
 
     def __mul__(self, y):
         if isinstance(y, moduint):
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)
 
 
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 60609df4..acef0904 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -18,8 +18,10 @@ f = ExprId('f', size=64)
 m = ExprMem(a)
 s = a[:8]
 
+i0 = ExprInt(uint32(0x0))
 i1 = ExprInt(uint32(0x1))
 i2 = ExprInt(uint32(0x2))
+icustom = ExprInt(uint32(0x12345678))
 cc = ExprCond(a, b, c)
 
 o = ExprCompose([(a[:8], 8, 16),
@@ -301,6 +303,23 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
     (expr_cmps(ExprInt32(-10), ExprInt32(-5)),
      ExprInt1(0)),
 
+    (ExprOp("<<<c_rez", i1, i0, i0),
+     i1),
+    (ExprOp("<<<c_rez", i1, i1, i0),
+     ExprInt32(2)),
+    (ExprOp("<<<c_rez", i1, i1, i1),
+     ExprInt32(3)),
+    (ExprOp(">>>c_rez", icustom, i0, i0),
+     icustom),
+    (ExprOp(">>>c_rez", icustom, i1, i0),
+     ExprInt32(0x91A2B3C)),
+    (ExprOp(">>>c_rez", icustom, i1, i1),
+     ExprInt32(0x891A2B3C)),
+    (ExprOp("idiv", ExprInt16(0x0123), ExprInt16(0xfffb))[:8],
+     ExprInt8(0xc6)),
+    (ExprOp("imod", ExprInt16(0x0123), ExprInt16(0xfffb))[:8],
+     ExprInt8(0x01)),
+
 ]
 
 for e, e_check in to_test[:]: