about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/x86/arch.py65
-rw-r--r--miasm2/arch/x86/sem.py58
-rw-r--r--test/arch/x86/arch.py61
3 files changed, 184 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 75fa2986..f0113dbb 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -3963,6 +3963,71 @@ addop("cvttsd2si",[bs8(0x0f), bs8(0x2c), pref_f2]
 addop("cvttss2si",[bs8(0x0f), bs8(0x2c), pref_f3]
       + rmmod(reg, rm_arg_xmm_m32))
 
+addop("psrlq", [bs8(0x0f), bs8(0x73), no_xmm_pref] +
+      rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("psrlq", [bs8(0x0f), bs8(0x73), pref_66] +
+      rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("psrlq", [bs8(0x0f), bs8(0xd3), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("psrlq", [bs8(0x0f), bs8(0xd3), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
+
+
+addop("psrld", [bs8(0x0f), bs8(0x72), no_xmm_pref] +
+      rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("psrld", [bs8(0x0f), bs8(0x72), pref_66] +
+      rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("psrld", [bs8(0x0f), bs8(0xd2), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("psrld", [bs8(0x0f), bs8(0xd2), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
+
+
+addop("psrlw", [bs8(0x0f), bs8(0x71), no_xmm_pref] +
+      rmmod(d2, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("psrlw", [bs8(0x0f), bs8(0x71), pref_66] +
+      rmmod(d2, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("psrlw", [bs8(0x0f), bs8(0xd1), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("psrlw", [bs8(0x0f), bs8(0xd1), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
+
+
+
+addop("psllq", [bs8(0x0f), bs8(0x73), no_xmm_pref] +
+      rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("psllq", [bs8(0x0f), bs8(0x73), pref_66] +
+      rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("psllq", [bs8(0x0f), bs8(0xf3), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("psllq", [bs8(0x0f), bs8(0xf3), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
+
+
+addop("pslld", [bs8(0x0f), bs8(0x72), no_xmm_pref] +
+      rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("pslld", [bs8(0x0f), bs8(0x72), pref_66] +
+      rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("pslld", [bs8(0x0f), bs8(0xf2), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("pslld", [bs8(0x0f), bs8(0xf2), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
+
+
+addop("psllw", [bs8(0x0f), bs8(0x71), no_xmm_pref] +
+      rmmod(d6, rm_arg_mm) + [u08], [rm_arg_mm, u08])
+addop("psllw", [bs8(0x0f), bs8(0x71), pref_66] +
+      rmmod(d6, rm_arg_xmm) + [u08], [rm_arg_xmm, u08])
+
+addop("psllw", [bs8(0x0f), bs8(0xf1), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm), [mm_reg, rm_arg_mm])
+addop("psllw", [bs8(0x0f), bs8(0xf1), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm), [xmm_reg, rm_arg_xmm])
 
 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 5fb7e34d..48114852 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3448,6 +3448,57 @@ def pshufb(ir, instr, a, b):
     return e, []
 
 
+def ps_rl_ll(ir, instr, a, b, op, size):
+    lbl_zero = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+
+    if b.size == 8:
+        count = b.zeroExtend(a.size)
+    else:
+        count = b.zeroExtend(a.size)
+
+    mask = {16: 0xF,
+            32: 0x1F,
+            64: 0x3F}[size]
+    test = count & m2_expr.ExprInt(((1 << a.size) - 1) ^ mask, a.size)
+    e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(test,
+                                                        lbl_zero,
+                                                        lbl_do))]
+
+    e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)),
+              m2_expr.ExprAff(ir.IRDst, lbl_next)]
+
+    e_do = []
+    for i in xrange(0, a.size, size):
+        e.append(m2_expr.ExprAff(a[i:i+size], m2_expr.ExprOp(op,
+                                                             a[i:i+size],
+                                                             count[:size])))
+
+    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
+    return e, [irbloc(lbl_do.name, [e_do]), irbloc(lbl_zero.name, [e_zero])]
+
+def psrlw(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, ">>", 16)
+
+def psrld(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, ">>", 32)
+
+def psrlq(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, ">>", 64)
+
+
+
+def psllw(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, "<<", 16)
+
+def pslld(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, "<<",  32)
+
+def psllq(ir, instr, a, b):
+    return ps_rl_ll(ir, instr, a, b, "<<",  64)
+
+
 def iret(ir, instr):
     """IRET implementation
     XXX: only support "no-privilege change"
@@ -3874,6 +3925,13 @@ mnemo_func = {'mov': mov,
               "rdmsr": rdmsr,
               "wrmsr": wrmsr,
               "pshufb" : pshufb,
+
+              "psrlw" : psrlw,
+              "psrld" : psrld,
+              "psrlq" : psrlq,
+              "psllw" : psllw,
+              "pslld" : pslld,
+              "psllq" : psllq,
               }
 
 
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index a38cbcf3..3dd91581 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -2592,6 +2592,67 @@ reg_tests = [
     "660F380036"),
 
 
+    (m32, "00000000    PSRLQ      MM6, 0x5",
+    "0F73D605"),
+    (m32, "00000000    PSRLQ      XMM6, 0x5",
+    "660F73D605"),
+    (m32, "00000000    PSRLD      MM6, 0x5",
+    "0F72D605"),
+    (m32, "00000000    PSRLD      XMM6, 0x5",
+    "660F72D605"),
+    (m32, "00000000    PSRLW      MM6, 0x5",
+    "0F71D605"),
+    (m32, "00000000    PSRLW      XMM6, 0x5",
+    "660F71D605"),
+
+
+    (m32, "00000000    PSRLQ      MM2, QWORD PTR [EDX]",
+    "0FD312"),
+    (m32, "00000000    PSRLQ      XMM2, XMMWORD PTR [EDX]",
+    "660FD312"),
+
+    (m32, "00000000    PSRLD      MM2, QWORD PTR [EDX]",
+    "0FD212"),
+    (m32, "00000000    PSRLD      XMM2, XMMWORD PTR [EDX]",
+    "660FD212"),
+
+    (m32, "00000000    PSRLW      MM2, QWORD PTR [EDX]",
+    "0FD112"),
+    (m32, "00000000    PSRLW      XMM2, XMMWORD PTR [EDX]",
+    "660FD112"),
+
+
+
+
+    (m32, "00000000    PSLLQ      MM6, 0x5",
+    "0F73F605"),
+    (m32, "00000000    PSLLQ      XMM6, 0x5",
+    "660F73F605"),
+    (m32, "00000000    PSLLD      MM6, 0x5",
+    "0F72F605"),
+    (m32, "00000000    PSLLD      XMM6, 0x5",
+    "660F72F605"),
+    (m32, "00000000    PSLLW      MM6, 0x5",
+    "0F71F605"),
+    (m32, "00000000    PSLLW      XMM6, 0x5",
+    "660F71F605"),
+
+
+    (m32, "00000000    PSLLQ      MM2, QWORD PTR [EDX]",
+    "0FF312"),
+    (m32, "00000000    PSLLQ      XMM2, XMMWORD PTR [EDX]",
+    "660FF312"),
+
+    (m32, "00000000    PSLLD      MM2, QWORD PTR [EDX]",
+    "0FF212"),
+    (m32, "00000000    PSLLD      XMM2, XMMWORD PTR [EDX]",
+    "660FF212"),
+
+    (m32, "00000000    PSLLW      MM2, QWORD PTR [EDX]",
+    "0FF112"),
+    (m32, "00000000    PSLLW      XMM2, XMMWORD PTR [EDX]",
+    "660FF112"),
+
 
 ]