diff options
| -rw-r--r-- | miasm2/arch/x86/arch.py | 9 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 21 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 9 |
3 files changed, 39 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index f4ef7349..303cad6e 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -4486,6 +4486,15 @@ addop("psubusw", [bs8(0x0f), bs8(0xd9), no_xmm_pref] + addop("psubusw", [bs8(0x0f), bs8(0xd9), pref_66] + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("paddusb", [bs8(0x0f), bs8(0xdc), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("paddusb", [bs8(0x0f), bs8(0xdc), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) +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)) + 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 4b4f40a1..adf5820d 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -4294,11 +4294,30 @@ def _saturation_sub(expr): arg2 = expr.args[1].args[0].zeroExtend(expr.size + 1) return _unsigned_saturation(arg1 - arg2, expr.size) +def _saturation_add(expr): + assert expr.is_op("+") and len(expr.args) == 2 + + # Compute the addition on one more bit to be able to distinguish cases: + # 0x48 + 0xd7 in 8 bit, should saturate + + arg1 = expr.args[0].zeroExtend(expr.size + 1) + arg2 = expr.args[1].zeroExtend(expr.size + 1) + + # We can also use _unsigned_saturation with two additionnal bits (to + # distinguish minus and overflow case) + # The resulting expression being more complicated with an impossible case + # (signed=True), we rewrite the rule here + + return m2_expr.ExprCond((arg1 + arg2).msb(), m2_expr.ExprInt(-1, expr.size), + expr) + # Saturate SSE operations psubusb = vec_vertical_instr('-', 8, _saturation_sub) psubusw = vec_vertical_instr('-', 16, _saturation_sub) +paddusb = vec_vertical_instr('+', 8, _saturation_add) +paddusw = vec_vertical_instr('+', 16, _saturation_add) mnemo_func = {'mov': mov, @@ -4810,6 +4829,8 @@ mnemo_func = {'mov': mov, "psubusb": psubusb, "psubusw": psubusw, + "paddusb": paddusb, + "paddusw": paddusw, "smsw": smsw, diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 3e0b9333..9b1a4d25 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -3000,6 +3000,15 @@ reg_tests = [ (m32, "00000000 PSUBUSW XMM0, XMM5", "660fd9c5"), + (m32, "00000000 PADDUSB MM5, MM3", + "0fdceb"), + (m32, "00000000 PADDUSB XMM0, XMM6", + "660fdcc6"), + + (m32, "00000000 PADDUSW MM7, MM5", + "0fddfd"), + (m32, "00000000 PADDUSW XMM0, XMM1", + "660fddc1"), ] |