about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/miasm/arch/x86/arch.py38
-rw-r--r--src/miasm/arch/x86/regs.py25
-rw-r--r--src/miasm/arch/x86/sem.py1
3 files changed, 59 insertions, 5 deletions
diff --git a/src/miasm/arch/x86/arch.py b/src/miasm/arch/x86/arch.py
index 3c557b31..591a682b 100644
--- a/src/miasm/arch/x86/arch.py
+++ b/src/miasm/arch/x86/arch.py
@@ -185,6 +185,7 @@ gpreg = (
     gpregs64.parser |
     gpregs_xmm.parser |
     gpregs_mm.parser |
+    gpregs_ymm.parser |
     gpregs_bnd.parser
 )
 
@@ -226,9 +227,11 @@ DWORD = Literal('DWORD')
 QWORD = Literal('QWORD')
 TBYTE = Literal('TBYTE')
 XMMWORD = Literal('XMMWORD')
+YMMWORD = Literal('YMMWORD')
 
 MEMPREFIX2SIZE = {'BYTE': 8, 'WORD': 16, 'DWORD': 32,
-                  'QWORD': 64, 'TBYTE': 80, 'XMMWORD': 128}
+                  'QWORD': 64, 'TBYTE': 80, 'XMMWORD': 128,
+                  'YMMWORD': 256}
 
 SIZE2MEMPREFIX = dict((value, key) for key, value in viewitems(MEMPREFIX2SIZE))
 
@@ -242,7 +245,7 @@ def cb_deref_mem(tokens):
         return AstMem(AstOp('segm', segm, ptr), MEMPREFIX2SIZE[s])
     raise ValueError('len(tokens) > 3')
 
-mem_size = (BYTE | DWORD | QWORD | WORD | TBYTE | XMMWORD)
+mem_size = (BYTE | DWORD | QWORD | WORD | TBYTE | XMMWORD | YMMWORD)
 deref_mem = (mem_size + PTR + Optional((base_expr + COLON))+ deref_mem_ad).setParseAction(cb_deref_mem)
 
 
@@ -254,7 +257,8 @@ rmarg = (
     gpregs64.parser |
     gpregs_mm.parser |
     gpregs_xmm.parser |
-    gpregs_bnd.parser
+    gpregs_bnd.parser |
+    gpregs_ymm.parser
 )
 
 rmarg |= deref_mem
@@ -857,16 +861,20 @@ class mn_x86(cls_mn):
             pre_dis_info['rex_x'] = 0
             pre_dis_info['rex_b'] = 0
             pre_dis_info['rex_w'] = 0
+            pre_dis_info['vex_m'] = 1
             pre_dis_info['vex_l'] = (c >> 2) & 1
             pre_dis_info['vex_p'] = c & int('0b11', 2)
             offset += 1
 
             if pre_dis_info['vex_p'] == 1:
                 pre_dis_info['opmode'] = 1
+                pre_dis_info['prefix'] += b'\x66'
             elif pre_dis_info['vex_p'] == 3:
                 pre_dis_info['g1'] = 2
+                pre_dis_info['prefix'] += b'\xf2'
             elif pre_dis_info['vex_p'] == 2:
                 pre_dis_info['g1'] = 12
+                pre_dis_info['prefix'] += b'\xf3'
 
         elif pre_dis_info.get('g1', None) == 12 and c in [b'\xa6', b'\xa7', b'\xae', b'\xaf']:
             pre_dis_info['g1'] = 4
@@ -2051,7 +2059,7 @@ def expr2modrm(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
         return [dct_expr], None, True
     return parse_mem(expr, parent, w8, sx, xmm, mm, bnd)
 
-def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
+def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0, ymm=0):
     o = []
     if not modrm[f_isad]:
         modrm_k = [key for key, value in viewitems(modrm) if value == 1]
@@ -2072,6 +2080,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
             expr = gpregs_mm.expr[modrm_k]
         elif bnd:
             expr = gpregs_bnd.expr[modrm_k]
+        elif ymm:
+            expr = gpregs_ymm.expr[modrm_k]
         elif opmode == 8 and (parent.v_opmode() == 64 or parent.rex_p.value == 1):
             expr = gpregs08_64.expr[modrm_k]
         else:
@@ -2105,6 +2115,8 @@ def modrm2expr(modrm, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
         opmode = 64
     elif bnd:
         opmode = 128
+    elif ymm:
+        opmode = 256
 
     expr = ExprMem(expr, size=opmode)
     return expr
@@ -2523,11 +2535,12 @@ class x86_rm_mm(x86_rm_m80):
     is_mm = True
     is_xmm = False
     is_bnd = False
+    is_ymm = False
 
     def decode(self, v):
         p = self.parent
         xx = self.get_modrm()
-        expr = modrm2expr(xx, p, 0, 0, self.is_xmm, self.is_mm, self.is_bnd)
+        expr = modrm2expr(xx, p, 0, 0, self.is_xmm, self.is_mm, self.is_bnd, self.is_ymm)
         if isinstance(expr, ExprMem):
             if self.msize is None:
                 return False
@@ -2585,6 +2598,11 @@ class x86_rm_xmm_m128(x86_rm_mm):
     is_mm = False
     is_xmm = True
 
+class x86_rm_ymm(x86_rm_mm):
+    msize = 256
+    is_mm = False
+    is_xmm = False
+    is_ymm = True
 
 class x86_rm_xmm_reg(x86_rm_mm):
     msize = None
@@ -2739,6 +2757,9 @@ class x86_rm_reg_mm(x86_rm_reg_noarg, x86_arg):
 class x86_rm_reg_xmm(x86_rm_reg_mm):
     selreg = gpregs_xmm
 
+class x86_rm_reg_ymm(x86_rm_reg_mm):
+    selreg = gpregs_ymm
+
 class x86_rm_reg_bnd(x86_rm_reg_mm):
     selreg = gpregs_bnd
 
@@ -3475,6 +3496,7 @@ mm_reg = bs(l=3, cls=(x86_rm_reg_mm, ), order =1, fname = "reg")
 xmm_reg = bs(l=3, cls=(x86_rm_reg_xmm, ), order =1, fname = "reg")
 bnd_reg = bs(l=3, cls=(x86_rm_reg_bnd, ), order =1, fname = "reg")
 
+ymm_reg = bs(l=3, cls=(x86_rm_reg_ymm, ), order =1, fname = "reg")
 
 fltreg = bs(l=3, cls=(x86_rm_flt, ), order =1, fname = "reg")
 
@@ -3512,6 +3534,8 @@ rm_arg_bnd_m64 = bs(l=0, cls=(x86_rm_bnd_m64,), fname='rmarg')
 rm_arg_bnd_m128 = bs(l=0, cls=(x86_rm_bnd_m128,), fname='rmarg')
 rm_arg_bnd_reg = bs(l=0, cls=(x86_rm_bnd_reg,), fname='rmarg')
 
+rm_arg_ymm = bs(l=0, cls=(x86_rm_ymm,), fname='rmarg')
+
 
 swapargs = bs_swapargs(l=1, fname="swap", mn_mod=list(range(1 << 1)))
 
@@ -4297,6 +4321,10 @@ addop("movdq2q", [bs8(0x0f), bs8(0xd6), pref_f2] +
 addop("movq2dq", [bs8(0x0f), bs8(0xd6), pref_f3] +
       rmmod(xmm_reg, rm_arg_mm))
 
+# AVX
+addop("vmovdqu", [bs("011"), swapargs, bs("1111"), pref_f3, pref_0f] +
+      rmmod(ymm_reg, rm_arg_ymm), [ymm_reg, rm_arg_ymm])
+
 ## Additions
 # SSE
 addop("paddb", [bs8(0x0f), bs8(0xfc), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
diff --git a/src/miasm/arch/x86/regs.py b/src/miasm/arch/x86/regs.py
index b08d7d35..8a300e4b 100644
--- a/src/miasm/arch/x86/regs.py
+++ b/src/miasm/arch/x86/regs.py
@@ -38,6 +38,9 @@ regs64_expr = [ExprId(x, 64) for x in regs64_str]
 regs_xmm_str = ["XMM%d" % i for i in range(16)]
 regs_xmm_expr = [ExprId(x, 128) for x in regs_xmm_str]
 
+regs_ymm_str = ["YMM%d" % i for i in range(16)]
+regs_ymm_expr = [ExprId(x, 256) for x in regs_ymm_str]
+
 regs_mm_str = ["MM%d" % i for i in range(16)]
 regs_mm_expr = [ExprId(x, 64) for x in regs_mm_str]
 
@@ -51,6 +54,7 @@ gpregs32 = reg_info(regs32_str, regs32_expr)
 gpregs64 = reg_info(regs64_str, regs64_expr)
 
 gpregs_xmm = reg_info(regs_xmm_str, regs_xmm_expr)
+gpregs_ymm = reg_info(regs_ymm_str, regs_ymm_expr)
 gpregs_mm = reg_info(regs_mm_str, regs_mm_expr)
 gpregs_bnd = reg_info(regs_bnd_str, regs_bnd_expr)
 
@@ -305,6 +309,23 @@ XMM13 = regs_xmm_expr[13]
 XMM14 = regs_xmm_expr[14]
 XMM15 = regs_xmm_expr[15]
 
+YMM0 = regs_ymm_expr[0]
+YMM1 = regs_ymm_expr[1]
+YMM2 = regs_ymm_expr[2]
+YMM3 = regs_ymm_expr[3]
+YMM4 = regs_ymm_expr[4]
+YMM5 = regs_ymm_expr[5]
+YMM6 = regs_ymm_expr[6]
+YMM7 = regs_ymm_expr[7]
+YMM8 = regs_ymm_expr[8]
+YMM9 = regs_ymm_expr[9]
+YMM10 = regs_ymm_expr[10]
+YMM11 = regs_ymm_expr[11]
+YMM12 = regs_ymm_expr[12]
+YMM13 = regs_ymm_expr[13]
+YMM14 = regs_ymm_expr[14]
+YMM15 = regs_ymm_expr[15]
+
 # tmp1= ExprId(reg_tmp1)
 zf = ExprId(reg_zf, size=1)
 nf = ExprId(reg_nf, size=1)
@@ -410,6 +431,8 @@ all_regs_ids = [
     XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
     XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
 
+    YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
+    YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,
 
     exception_flags, interrupt_num,
 ] + fltregs32_expr
@@ -431,6 +454,8 @@ all_regs_ids_no_alias = [
     mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
     XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
     XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15,
+    YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
+    YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15,
 
 
     exception_flags, interrupt_num,
diff --git a/src/miasm/arch/x86/sem.py b/src/miasm/arch/x86/sem.py
index 895be1fa..b145334a 100644
--- a/src/miasm/arch/x86/sem.py
+++ b/src/miasm/arch/x86/sem.py
@@ -5623,6 +5623,7 @@ mnemo_func = {'mov': mov,
               "movd": movd,
               "movdqu": movdqu,
               "movdqa": movdqu,
+              "vmovdqu": movdqu,
               "movapd": movapd,  # XXX TODO alignment check
               "movupd": movapd,  # XXX TODO alignment check
               "movaps": movapd,  # XXX TODO alignment check