about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2015-11-12 15:32:35 +0100
committerAjax <commial@gmail.com>2015-11-12 15:32:35 +0100
commitf0d72245c9a295958a972340c3e895596d682d8e (patch)
tree90256c14b02f29dc88f17634aa85e9d0322852aa
parent9da46e3992429b1d8aff1d725abbf81759e1c5f8 (diff)
downloadmiasm-f0d72245c9a295958a972340c3e895596d682d8e.tar.gz
miasm-f0d72245c9a295958a972340c3e895596d682d8e.zip
x86/sem: handle count == 0 in `shrd`
-rw-r--r--miasm2/arch/x86/sem.py29
1 files changed, 12 insertions, 17 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 30f1daee..60fb0a81 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -468,15 +468,23 @@ def rcr(ir, instr, a, b):
     return e, []
 
 
-def _shift_tpl(op, ir, instr, a, b, c=None):
-    """Template for generate shifter with operation `op`
+def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None):
+    """Template for generate shifter with operation @op
     A temporary basic block is generated to handle 0-shift
     @op: operation to execute
     @c (optional): if set, instruction has a bit provider
+    @op_inv (optional): opposite operation of @op. Must be provided if @c
     """
+    if c is not None:
+        shifter = get_shift(a, c)
+    else:
+        shifter = get_shift(a, b)
 
-    shifter = get_shift(a, b)
     res = m2_expr.ExprOp(op, a, shifter)
+    if c is not None:
+        shifter_inv = m2_expr.ExprInt_from(a, a.size) - c.zeroExtend(a.size)
+        res |= m2_expr.ExprOp(op_inv, b,
+                              shifter_inv)
 
     lbl_do = m2_expr.ExprId(ir.gen_label(), instr.mode)
     lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), instr.mode)
@@ -533,20 +541,7 @@ def shrd_cl(ir, instr, a, b):
 
 
 def shrd(ir, instr, a, b, c):
-    e = []
-    shifter = get_shift(a, c)
-
-    d = (a >> shifter) | (b << (m2_expr.ExprInt_from(a, a.size) - shifter))
-    new_cf = (a >> (shifter - m2_expr.ExprInt_from(a, 1)))[:1]
-    e.append(m2_expr.ExprAff(cf, m2_expr.ExprCond(shifter,
-                                  new_cf,
-                                  cf)
-                     )
-             )
-    e.append(m2_expr.ExprAff(of, a.msb()))
-    e += update_flag_znp(d)
-    e.append(m2_expr.ExprAff(a, d))
-    return e, []
+    return _shift_tpl(">>", ir, instr, a, b, c, "<<")
 
 
 def sal(ir, instr, a, b):