about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-02-08 16:43:37 +0100
committerAjax <commial@gmail.com>2018-02-09 17:36:31 +0100
commit98a0c25a6e914089feb73e8bc4b79ff33a38a86b (patch)
tree1a1e0ece0f45bfd671db537db329b8ca3dcb36d1
parentbee25554ff9c86f81f16e191f09693f336365ad2 (diff)
downloadmiasm-98a0c25a6e914089feb73e8bc4b79ff33a38a86b.tar.gz
miasm-98a0c25a6e914089feb73e8bc4b79ff33a38a86b.zip
Add PMULHW / PMULHUW instruction
0F E5 /r 	PMULHW mm, mm/m64
66 0F E5 /r 	PMULHW xmm1, xmm2/m128
NP 0F E4 /r PMULHUW mm1, mm2/m64
66 0F E4 /r PMULHUW xmm1, xmm2/m128
-rw-r--r--miasm2/arch/x86/arch.py9
-rw-r--r--miasm2/arch/x86/sem.py29
-rw-r--r--test/arch/x86/arch.py10
3 files changed, 48 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 303cad6e..d58ac64b 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -4476,6 +4476,15 @@ addop("pmullw", [bs8(0x0f), bs8(0xd5), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm_m64))
 addop("pmullw", [bs8(0x0f), bs8(0xd5), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pmulhuw", [bs8(0x0f), bs8(0xe4), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmulhuw", [bs8(0x0f), bs8(0xe4), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pmulhw", [bs8(0x0f), bs8(0xe5), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmulhw", [bs8(0x0f), bs8(0xe5), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
 
 addop("psubusb", [bs8(0x0f), bs8(0xd8), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm_m64))
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index adf5820d..ba56c91c 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3392,6 +3392,17 @@ def float_vec_vertical_instr(op, elt_size, apply_on_output=lambda x: x):
                                     apply_on_output)
 
 
+def _keep_mul_high(expr, signed=False):
+    assert expr.is_op("*") and len(expr.args) == 2
+
+    if signed:
+        arg1 = expr.args[0].signExtend(expr.size * 2)
+        arg2 = expr.args[1].signExtend(expr.size * 2)
+    else:
+        arg1 = expr.args[0].zeroExtend(expr.size * 2)
+        arg2 = expr.args[1].zeroExtend(expr.size * 2)
+    return m2_expr.ExprOp("*", arg1, arg2)[expr.size:]
+
 # Integer arithmetic
 #
 
@@ -3421,6 +3432,14 @@ pmullb = vec_vertical_instr('*', 8)
 pmullw = vec_vertical_instr('*', 16)
 pmulld = vec_vertical_instr('*', 32)
 pmullq = vec_vertical_instr('*', 64)
+pmulhub = vec_vertical_instr('*', 8, _keep_mul_high)
+pmulhuw = vec_vertical_instr('*', 16, _keep_mul_high)
+pmulhud = vec_vertical_instr('*', 32, _keep_mul_high)
+pmulhuq = vec_vertical_instr('*', 64, _keep_mul_high)
+pmulhb = vec_vertical_instr('*', 8, lambda x: _keep_mul_high(x, signed=True))
+pmulhw = vec_vertical_instr('*', 16, lambda x: _keep_mul_high(x, signed=True))
+pmulhd = vec_vertical_instr('*', 32, lambda x: _keep_mul_high(x, signed=True))
+pmulhq = vec_vertical_instr('*', 64, lambda x: _keep_mul_high(x, signed=True))
 
 # Floating-point arithmetic
 #
@@ -4704,11 +4723,21 @@ mnemo_func = {'mov': mov,
               "psubd": psubd,
               "psubq": psubq,
 
+              # Multiplications
               # SSE
               "pmullb": pmullb,
               "pmullw": pmullw,
               "pmulld": pmulld,
               "pmullq": pmullq,
+              "pmulhub": pmulhub,
+              "pmulhuw": pmulhuw,
+              "pmulhud": pmulhud,
+              "pmulhuq": pmulhuq,
+              "pmulhb": pmulhb,
+              "pmulhw": pmulhw,
+              "pmulhd": pmulhd,
+              "pmulhq": pmulhq,
+
 
               # Arithmetic (floating-point)
               #
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 9b1a4d25..82475e51 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -3009,6 +3009,16 @@ reg_tests = [
      "0fddfd"),
     (m32, "00000000    PADDUSW    XMM0, XMM1",
      "660fddc1"),
+
+    (m32, "00000000    PMULHUW    MM6, MM4",
+     "0fe4f4"),
+    (m32, "00000000    PMULHUW    XMM0, XMM7",
+     "660fe4c7"),
+
+    (m32, "00000000    PMULHW     MM6, MM4",
+     "0fe5f4"),
+    (m32, "00000000    PMULHW     XMM0, XMM7",
+     "660fe5c7"),
 ]