about summary refs log tree commit diff stats
path: root/miasm2/arch/x86/sem.py
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-02-09 10:03:43 +0100
committerAjax <commial@gmail.com>2018-02-09 17:36:31 +0100
commitdeda8791ecbaa3cd541667b04d44759b91a14372 (patch)
treea0b685836cfce93f9cdff6203b08d3291f0a79d6 /miasm2/arch/x86/sem.py
parent60a82ffba739af32ffadd56b16e755a5ea410009 (diff)
downloadmiasm-deda8791ecbaa3cd541667b04d44759b91a14372.tar.gz
miasm-deda8791ecbaa3cd541667b04d44759b91a14372.zip
Unify the way PMIN / PMAX works
Diffstat (limited to '')
-rw-r--r--miasm2/arch/x86/sem.py78
1 files changed, 17 insertions, 61 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index a30bcdc9..0bb534e5 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3403,10 +3403,17 @@ def _keep_mul_high(expr, signed=False):
         arg2 = expr.args[1].zeroExtend(expr.size * 2)
     return m2_expr.ExprOp("*", arg1, arg2)[expr.size:]
 
-def _signed_min(expr):
-    assert expr.is_op("min") and len(expr.args) == 2
+# Op, signed => associated comparison
+_min_max_func = {
+    ("min", False): m2_expr.expr_is_unsigned_lower,
+    ("min", True): m2_expr.expr_is_signed_lower,
+    ("max", False): m2_expr.expr_is_unsigned_greater,
+    ("max", True): m2_expr.expr_is_signed_greater,
+}
+def _min_max(expr, signed):
+    assert (expr.is_op("min") or expr.is_op("max")) and len(expr.args) == 2
     return m2_expr.ExprCond(
-        m2_expr.expr_is_signed_lower(expr.args[1], expr.args[0]),
+        _min_max_func[(expr.op, signed)](expr.args[1], expr.args[0]),
         expr.args[1],
         expr.args[0],
     )
@@ -3453,8 +3460,13 @@ pmulhq = vec_vertical_instr('*', 64, lambda x: _keep_mul_high(x, signed=True))
 #
 
 # SSE
-pminsw = vec_vertical_instr('min', 16, _signed_min)
-
+pminsw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=True))
+pminub = vec_vertical_instr('min', 8, lambda x: _min_max(x, signed=False))
+pminuw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=False))
+pminud = vec_vertical_instr('min', 32, lambda x: _min_max(x, signed=False))
+pmaxub = vec_vertical_instr('max', 8, lambda x: _min_max(x, signed=False))
+pmaxuw = vec_vertical_instr('max', 16, lambda x: _min_max(x, signed=False))
+pmaxud = vec_vertical_instr('max', 32, lambda x: _min_max(x, signed=False))
 
 # Floating-point arithmetic
 #
@@ -3871,62 +3883,6 @@ def iret(ir, instr):
     return exprs, []
 
 
-def pmaxu(_, instr, dst, src, size):
-    e = []
-    for i in xrange(0, dst.size, size):
-        op1 = dst[i:i + size]
-        op2 = src[i:i + size]
-        res = op1 - op2
-        # Compote CF in @res = @op1 - @op2
-        ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()
-
-        e.append(m2_expr.ExprAff(dst[i:i + size],
-                                 m2_expr.ExprCond(ret,
-                                                  src[i:i + size],
-                                                  dst[i:i + size])))
-    return e, []
-
-
-def pmaxub(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 8)
-
-
-def pmaxuw(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 16)
-
-
-def pmaxud(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 32)
-
-
-def pminu(_, instr, dst, src, size):
-    e = []
-    for i in xrange(0, dst.size, size):
-        op1 = dst[i:i + size]
-        op2 = src[i:i + size]
-        res = op1 - op2
-        # Compote CF in @res = @op1 - @op2
-        ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()
-
-        e.append(m2_expr.ExprAff(dst[i:i + size],
-                                 m2_expr.ExprCond(ret,
-                                                  dst[i:i + size],
-                                                  src[i:i + size])))
-    return e, []
-
-
-def pminub(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 8)
-
-
-def pminuw(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 16)
-
-
-def pminud(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 32)
-
-
 def pcmpeq(_, instr, dst, src, size):
     e = []
     for i in xrange(0, dst.size, size):