about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-02-09 11:15:14 +0100
committerAjax <commial@gmail.com>2018-02-09 17:36:31 +0100
commit649c7b519fc93e9ef5750d03dfcc3e91c2968a36 (patch)
tree2b75e8995f06a2c9ccb953e2cc0b4ed471422255
parent4a94e84923d8ac059fc2c41a5876835613204ad2 (diff)
downloadmiasm-649c7b519fc93e9ef5750d03dfcc3e91c2968a36.tar.gz
miasm-649c7b519fc93e9ef5750d03dfcc3e91c2968a36.zip
Add PSADBW instruction
0F F6 /r 	PSADBW mm1, mm2/m64
66 0F F6 /r 	PSADBW xmm1, xmm2/m128
-rw-r--r--miasm2/arch/x86/arch.py5
-rw-r--r--miasm2/arch/x86/sem.py26
-rw-r--r--test/arch/x86/arch.py5
3 files changed, 36 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index ae5f3fd7..a9a59a08 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -4534,6 +4534,11 @@ addop("pmaddwd", [bs8(0x0f), bs8(0xf5), no_xmm_pref] +
 addop("pmaddwd", [bs8(0x0f), bs8(0xf5), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm_m128))
 
+addop("psadbw", [bs8(0x0f), bs8(0xf6), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psadbw", [bs8(0x0f), bs8(0xf6), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
 mn_x86.bintree = factor_one_bit(mn_x86.bintree)
 # mn_x86.bintree = factor_fields_all(mn_x86.bintree)
 """
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 3880ed67..51fcbe05 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3494,6 +3494,31 @@ def pmaddwd(ir, instr, dst, src):
     return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], []
 
 
+def _absolute(expr):
+    """Return abs(@expr)"""
+    signed = expr.msb()
+    value_unsigned = (expr ^ expr.mask) + m2_expr.ExprInt(1, expr.size)
+    return m2_expr.ExprCond(signed, value_unsigned, expr)
+
+
+def psadbw(ir, instr, dst, src):
+    sizedst = 16
+    sizesrc = 8
+    out_dst = []
+    for start in xrange(0, dst.size, 64):
+        out = []
+        for src_start in xrange(0, 64, sizesrc):
+            beg = start + src_start
+            end = beg + sizesrc
+            # Not clear in the doc equations, but in the text, src and dst are:
+            # "8 unsigned byte integers"
+            out.append(_absolute(dst[beg: end].zeroExtend(sizedst) - src[beg: end].zeroExtend(sizedst)))
+        out_dst.append(m2_expr.ExprOp("+", *out))
+        out_dst.append(m2_expr.ExprInt(0, 64 - sizedst))
+
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out_dst))], []
+
+
 # Comparisons
 #
 
@@ -4768,6 +4793,7 @@ mnemo_func = {'mov': mov,
               # Mix
               # SSE
               "pmaddwd": pmaddwd,
+              "psadbw": psadbw,
 
               # Arithmetic (floating-point)
               #
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 3d9fd31f..0e6ffdd9 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -3054,6 +3054,11 @@ reg_tests = [
      "0ff5d9"),
     (m32, "00000000    PMADDWD    XMM0, XMM6",
      "660ff5c6"),
+
+    (m32, "00000000    PSADBW     MM3, MM1",
+     "0ff6d9"),
+    (m32, "00000000    PSADBW     XMM0, XMM6",
+     "660ff6c6"),
 ]