about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2015-12-24 00:44:43 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2015-12-24 18:38:19 +0100
commitaf7e524f56ba0bf1dce26b9c968c0806c418ea47 (patch)
tree0c445178400e889ef725446838bcf7130e396d65
parent3ba62672ccb2190b7598ec5e362c670f031f74a9 (diff)
downloadmiasm-af7e524f56ba0bf1dce26b9c968c0806c418ea47.tar.gz
miasm-af7e524f56ba0bf1dce26b9c968c0806c418ea47.zip
X86: add pinsr
-rw-r--r--miasm2/arch/x86/arch.py69
-rw-r--r--miasm2/arch/x86/sem.py32
-rw-r--r--test/arch/x86/arch.py44
3 files changed, 143 insertions, 2 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 89683e31..b996f4f0 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -2151,6 +2151,54 @@ class x86_rm_wd(x86_rm_sd):
             yield x
 
 
+class x86_rm_08(x86_rm_arg):
+    msize = 8
+
+    def decode(self, v):
+        p = self.parent
+        xx = self.get_modrm()
+        expr = modrm2expr(xx, p, 0)
+        if not isinstance(expr, ExprMem):
+            self.expr = expr
+            return True
+        self.expr = ExprMem(expr.arg, self.msize)
+        return self.expr is not None
+
+    def encode(self):
+        if isinstance(self.expr, ExprInt):
+            raise StopIteration
+        p = self.parent
+        v_cand, segm, ok = expr2modrm(self.expr, p, 0, 0, 0, 0)
+        for x in self.gen_cand(v_cand, p.v_admode()):
+            yield x
+
+class x86_rm_reg_m08(x86_rm_arg):
+    msize = 8
+
+    def decode(self, v):
+        ret = x86_rm_arg.decode(self, v)
+        if not ret:
+            return ret
+        if not isinstance(self.expr, ExprMem):
+            return True
+        self.expr = ExprMem(self.expr.arg, self.msize)
+        return self.expr is not None
+
+    def encode(self):
+        if isinstance(self.expr, ExprInt):
+            raise StopIteration
+        p = self.parent
+        if isinstance(self.expr, ExprMem):
+            expr = ExprMem(self.expr.arg, 32)
+        else:
+            expr = self.expr
+        v_cand, segm, ok = expr2modrm(expr, p, 1, 0, 0, 0)
+        for x in self.gen_cand(v_cand, p.v_admode()):
+            yield x
+
+class x86_rm_reg_m16(x86_rm_reg_m08):
+    msize = 16
+
 class x86_rm_m64(x86_rm_arg):
     msize = 64
 
@@ -3068,9 +3116,12 @@ rm_arg_sx = bs(l=0, cls=(x86_rm_sx,), fname='rmarg')
 rm_arg_sxd = bs(l=0, cls=(x86_rm_sxd,), fname='rmarg')
 rm_arg_sd = bs(l=0, cls=(x86_rm_sd,), fname='rmarg')
 rm_arg_wd = bs(l=0, cls=(x86_rm_wd,), fname='rmarg')
+rm_arg_08 = bs(l=0, cls=(x86_rm_08,), fname='rmarg')
+rm_arg_reg_m08 = bs(l=0, cls=(x86_rm_reg_m08,), fname='rmarg')
+rm_arg_reg_m16 = bs(l=0, cls=(x86_rm_reg_m16,), fname='rmarg')
+rm_arg_m08 = bs(l=0, cls=(x86_rm_m08,), fname='rmarg')
 rm_arg_m64 = bs(l=0, cls=(x86_rm_m64,), fname='rmarg')
 rm_arg_m80 = bs(l=0, cls=(x86_rm_m80,), fname='rmarg')
-rm_arg_m08 = bs(l=0, cls=(x86_rm_m08,), fname='rmarg')
 rm_arg_m16 = bs(l=0, cls=(x86_rm_m16,), fname='rmarg')
 
 rm_arg_mm = bs(l=0, cls=(x86_rm_mm,), fname='rmarg')
@@ -3725,7 +3776,7 @@ addop("sbb", [bs("100000"), se, w8] + rmmod(d3, rm_arg_w8) + [d_imm])
 addop("sbb", [bs("000110"), swapargs, w8] +
       rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg])
 
-addop("set", [bs8(0x0f), bs('1001'), cond] + rmmod(regnoarg, rm_arg_m08))
+addop("set", [bs8(0x0f), bs('1001'), cond] + rmmod(regnoarg, rm_arg_08))
 addop("sgdt", [bs8(0x0f), bs8(0x01)] + rmmod(d0, modrm=mod_mem))
 addop("shld", [bs8(0x0f), bs8(0xa4)] +
       rmmod(rmreg) + [u08], [rm_arg, rmreg, u08])
@@ -4109,6 +4160,20 @@ addop("punpcklqdq", [bs8(0x0f), bs8(0x6c), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm))
 
 
+
+addop("pinsrb", [bs8(0x0f), bs8(0x3a), bs8(0x20), pref_66] +
+      rmmod(xmm_reg, rm_arg_reg_m08) + [u08])
+addop("pinsrd", [bs8(0x0f), bs8(0x3a), bs8(0x22), pref_66, bs_opmode32] +
+      rmmod(xmm_reg, rm_arg) + [u08])
+addop("pinsrq", [bs8(0x0f), bs8(0x3a), bs8(0x22), pref_66] +
+      rmmod(xmm_reg, rm_arg_m64) + [bs_opmode64] + [u08])
+
+addop("pinsrw", [bs8(0x0f), bs8(0xc4), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_reg_m16) + [u08])
+addop("pinsrw", [bs8(0x0f), bs8(0xc4), pref_66] +
+      rmmod(xmm_reg, rm_arg_reg_m16) + [u08])
+
+
 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 0312d002..9b20196d 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3622,6 +3622,33 @@ def punpcklqdq(ir, instr, a, b):
 
 
 
+def pinsr(ir, instr, a, b, c, size):
+    e = []
+
+    mask = {8 : 0xF,
+           16 : 0x7,
+           32 : 0x3,
+           64 : 0x1}[size]
+
+    sel = (int(c.arg) & mask) * size
+    e.append(m2_expr.ExprAff(a[sel:sel+size], b[:size]))
+
+    return e, []
+
+def pinsrb(ir, instr, a, b, c):
+    return pinsr(ir, instr, a, b, c, 8)
+
+def pinsrw(ir, instr, a, b, c):
+    return pinsr(ir, instr, a, b, c, 16)
+
+def pinsrd(ir, instr, a, b, c):
+    return pinsr(ir, instr, a, b, c, 32)
+
+def pinsrq(ir, instr, a, b, c):
+    return pinsr(ir, instr, a, b, c, 64)
+
+
+
 mnemo_func = {'mov': mov,
               'xchg': xchg,
               'movzx': movzx,
@@ -4068,6 +4095,11 @@ mnemo_func = {'mov': mov,
               "punpckldq" : punpckldq,
               "punpcklqdq" : punpcklqdq,
 
+              "pinsrb" : pinsrb,
+              "pinsrw" : pinsrw,
+              "pinsrd" : pinsrd,
+              "pinsrq" : pinsrq,
+
               }
 
 
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 2048dda4..c35a630c 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -2729,6 +2729,50 @@ reg_tests = [
     (m32, "00000000    PUNPCKLQDQ XMM2, XMMWORD PTR [EDX]",
     "660F6C12"),
 
+
+    (m32, "00000000    PINSRB     XMM2, BYTE PTR [EDX], 0x5",
+    "660F3A201205"),
+
+    (m32, "00000000    PINSRW     MM2, WORD PTR [EDX], 0x5",
+    "0FC41205"),
+    (m32, "00000000    PINSRW     XMM2, WORD PTR [EDX], 0x5",
+    "660FC41205"),
+
+    (m32, "00000000    PINSRD     XMM2, DWORD PTR [EDX], 0x5",
+    "660F3A221205"),
+
+
+    (m64, "00000000    PINSRB     XMM2, BYTE PTR [RDX], 0x5",
+    "660F3A201205"),
+
+    (m64, "00000000    PINSRW     MM2, WORD PTR [RDX], 0x5",
+    "0FC41205"),
+    (m64, "00000000    PINSRW     XMM2, WORD PTR [RDX], 0x5",
+    "660FC41205"),
+
+
+    (m64, "00000000    PINSRB     XMM2, EDX, 0x5",
+    "660F3A20D205"),
+
+    (m64, "00000000    PINSRW     MM2, EDX, 0x5",
+    "0FC4D205"),
+    (m64, "00000000    PINSRW     XMM2, EDX, 0x5",
+    "660FC4D205"),
+
+    (m64, "00000000    PINSRB     XMM2, RDX, 0x5",
+    "66480F3A20D205"),
+
+    (m64, "00000000    PINSRW     MM2, RDX, 0x5",
+    "480FC4D205"),
+    (m64, "00000000    PINSRW     XMM2, RDX, 0x5",
+    "66480FC4D205"),
+
+
+    (m64, "00000000    PINSRD     XMM2, DWORD PTR [RDX], 0x5",
+    "660F3A221205"),
+    (m64, "00000000    PINSRQ     XMM2, QWORD PTR [RDX], 0x5",
+    "66480F3A221205"),
+
 ]