diff options
| author | Ajax <commial@gmail.com> | 2018-02-08 16:19:55 +0100 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2018-02-09 17:36:31 +0100 |
| commit | bee25554ff9c86f81f16e191f09693f336365ad2 (patch) | |
| tree | cd8adcd77710f359d697f406a0c50aad1c3853d7 | |
| parent | c92be77fa7afa23dd06124325e9dc127ebb67e22 (diff) | |
| download | miasm-bee25554ff9c86f81f16e191f09693f336365ad2.tar.gz miasm-bee25554ff9c86f81f16e191f09693f336365ad2.zip | |
Add PADDUSB/PADDUSW instruction
0F DC /r PADDUSB mm, mm/m64 66 0F DC /r PADDUSB xmm1, xmm2/m128
| -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"), ] |