about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-02-09 09:49:15 +0100
committerAjax <commial@gmail.com>2018-02-09 17:36:31 +0100
commit60a82ffba739af32ffadd56b16e755a5ea410009 (patch)
tree65b27072106a08083f43b681527cd5d8ea3b0de6
parentdf4b2904c00bca0d15062493666ce50ff0b56632 (diff)
downloadmiasm-60a82ffba739af32ffadd56b16e755a5ea410009.tar.gz
miasm-60a82ffba739af32ffadd56b16e755a5ea410009.zip
Add PADDSB/PADDSW instruction
NP 0F EC /r PADDSB mm, mm/m64
66 0F EC /r PADDSB xmm1, xmm2/m128
NP 0F ED /r PADDSW mm, mm/m64
66 0F ED /r PADDSW xmm1, xmm2/m128
-rw-r--r--miasm2/arch/x86/arch.py8
-rw-r--r--miasm2/arch/x86/sem.py14
-rw-r--r--test/arch/x86/arch.py10
3 files changed, 32 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 03d7449d..1b181f6f 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -4512,6 +4512,14 @@ addop("paddusw", [bs8(0x0f), bs8(0xdd), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm_m64))
 addop("paddusw", [bs8(0x0f), bs8(0xdd), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("paddsb", [bs8(0x0f), bs8(0xec), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddsb", [bs8(0x0f), bs8(0xec), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("paddsw", [bs8(0x0f), bs8(0xed), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddsw", [bs8(0x0f), bs8(0xed), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
 
 
 mn_x86.bintree = factor_one_bit(mn_x86.bintree)
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 97373abf..a30bcdc9 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -4347,6 +4347,16 @@ def _saturation_add(expr):
     return m2_expr.ExprCond((arg1 + arg2).msb(), m2_expr.ExprInt(-1, expr.size),
                             expr)
 
+def _saturation_add_signed(expr):
+    assert expr.is_op("+") and len(expr.args) == 2
+
+    # Compute the substraction on two more bits, see _saturation_add_unsigned
+
+    arg1 = expr.args[0].signExtend(expr.size + 2)
+    arg2 = expr.args[1].signExtend(expr.size + 2)
+
+    return _signed_saturation(arg1 + arg2, expr.size)
+
 
 # Saturate SSE operations
 
@@ -4356,6 +4366,8 @@ paddusb = vec_vertical_instr('+', 8, _saturation_add)
 paddusw = vec_vertical_instr('+', 16, _saturation_add)
 psubsb = vec_vertical_instr('-', 8, _saturation_sub_signed)
 psubsw = vec_vertical_instr('-', 16, _saturation_sub_signed)
+paddsb = vec_vertical_instr('+', 8, _saturation_add_signed)
+paddsw = vec_vertical_instr('+', 16, _saturation_add_signed)
 
 
 mnemo_func = {'mov': mov,
@@ -4881,6 +4893,8 @@ mnemo_func = {'mov': mov,
               "paddusw": paddusw,
               "psubsb": psubsb,
               "psubsw": psubsw,
+              "paddsb": paddsb,
+              "paddsw": paddsw,
 
               "smsw": smsw,
 
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index fb757b33..8c191aad 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -3029,6 +3029,16 @@ reg_tests = [
      "0fe9d9"),
     (m32, "00000000    PSUBSW     XMM0, XMM6",
      "660fe9c6"),
+
+    (m32, "00000000    PADDSB     MM2, MM0",
+     "0fecd0"),
+    (m32, "00000000    PADDSB     XMM0, XMM4",
+     "660fecc4"),
+
+    (m32, "00000000    PADDSW     MM3, MM1",
+     "0fedd9"),
+    (m32, "00000000    PADDSW     XMM0, XMM6",
+     "660fedc6"),
 ]