* doc/binutils.texi (c++filt): Remove spurious description of
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index e89f200295e2d4af6149173b2107a2e3beac493e..e6b80497d4d1a0fd09eadaf35c440947bc78f59d 100644 (file)
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
@@ -55,8 +55,8 @@ static void append_seg (void);
 static void OP_indirE (int, int);
 static void print_operand_value (char *, int, bfd_vma);
 static void OP_E_register (int, int);
-static void OP_E_memory (int, int, int);
-static void OP_E_extended (int, int, int);
+static void OP_E_memory (int, int);
+static void OP_E_extended (int, int);
 static void print_displacement (char *, bfd_vma);
 static void OP_E (int, int);
 static void OP_G (int, int);
@@ -96,7 +96,6 @@ static void OP_VEX (int, int);
 static void OP_VEX_FMA (int, int);
 static void OP_EX_Vex (int, int);
 static void OP_EX_VexW (int, int);
-static void OP_EX_VexImmW (int, int);
 static void OP_XMM_Vex (int, int);
 static void OP_XMM_VexW (int, int);
 static void OP_REG_VexI4 (int, int);
@@ -104,7 +103,6 @@ static void PCLMUL_Fixup (int, int);
 static void VEXI4_Fixup (int, int);
 static void VZERO_Fixup (int, int);
 static void VCMP_Fixup (int, int);
-static void VPERMIL2_Fixup (int, int);
 static void OP_0f07 (int, int);
 static void OP_Monitor (int, int);
 static void OP_Mwait (int, int);
@@ -117,11 +115,7 @@ static void REP_Fixup (int, int);
 static void CMPXCHG8B_Fixup (int, int);
 static void XMM_Fixup (int, int);
 static void CRC32_Fixup (int, int);
-static void print_drex_arg (unsigned int, int, int);
-static void OP_DREX4 (int, int);
-static void OP_DREX3 (int, int);
-static void OP_DREX_ICMP (int, int);
-static void OP_DREX_FCMP (int, int);
+
 static void MOVBE_Fixup (int, int);
 
 struct dis_private {
@@ -169,20 +163,6 @@ static int rex_ignored;
       rex_used |= REX_OPCODE;                          \
   }
 
-/* Special 'registers' for DREX handling */
-#define DREX_REG_UNKNOWN       1000    /* not initialized */
-#define DREX_REG_MEMORY         1001   /* use MODRM/SIB/OFFSET memory */
-
-/* The DREX byte has the following fields:
-   Bits 7-4 -- DREX.Dest, xmm destination register
-   Bit 3    -- DREX.OC0, operand config bit defines operand order
-   Bit 2    -- DREX.R, equivalent to REX_R bit, to extend ModRM register
-   Bit 1    -- DREX.X, equivalent to REX_X bit, to extend SIB index field
-   Bit 0    -- DREX.W, equivalent to REX_B bit, to extend ModRM r/m field,
-              SIB base field, or opcode reg field.  */
-#define DREX_XMM(drex) ((drex >> 4) & 0xf)
-#define DREX_OC0(drex) ((drex >> 3) & 0x1)
-
 /* Flags for prefixes which we somehow handled when printing the
    current instruction.  */
 static int used_prefixes;
@@ -370,6 +350,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EXxmm { OP_EX, xmm_mode }
 #define EXxmmq { OP_EX, xmmq_mode }
 #define EXymmq { OP_EX, ymmq_mode }
+#define EXVexWdq { OP_EX, vex_w_dq_mode }
 #define MS { OP_MS, v_mode }
 #define XS { OP_XS, v_mode }
 #define EMCq { OP_EMC, q_mode }
@@ -391,14 +372,12 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EXVexW { OP_EX_VexW, x_mode }
 #define EXdVexW { OP_EX_VexW, d_mode }
 #define EXqVexW { OP_EX_VexW, q_mode }
-#define EXVexImmW { OP_EX_VexImmW, x_mode }
 #define XMVex { OP_XMM_Vex, 0 }
 #define XMVexW { OP_XMM_VexW, 0 }
 #define XMVexI4 { OP_REG_VexI4, x_mode }
 #define PCLMUL { PCLMUL_Fixup, 0 }
 #define VZERO { VZERO_Fixup, 0 }
 #define VCMP { VCMP_Fixup, 0 }
-#define VPERMIL2 { VPERMIL2_Fixup, 0 }
 
 /* Used handle "rep" prefix for string instructions.  */
 #define Xbr { REP_Fixup, eSI_reg }
@@ -477,8 +456,10 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define vex128_mode            (vex_mode + 1)
 /* 256bit vex mode */
 #define vex256_mode            (vex128_mode + 1)
+/* operand size depends on the VEX.W bit.  */
+#define vex_w_dq_mode          (vex256_mode + 1)
 
-#define es_reg                 (vex256_mode + 1)
+#define es_reg                 (vex_w_dq_mode + 1)
 #define cs_reg                 (es_reg + 1)
 #define ss_reg                 (cs_reg + 1)
 #define ds_reg                 (ss_reg + 1)
@@ -526,15 +507,6 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 
 #define MAX_BYTEMODE   indir_dx_reg
 
-/* Flags that are OR'ed into the bytemode field to pass extra
-   information.  */
-#define DREX_OC1               0x10000 /* OC1 bit set */
-#define DREX_NO_OC0            0x20000 /* OC0 bit not used */
-#define DREX_MASK              0x40000 /* mask to delete */
-
-#if MAX_BYTEMODE >= DREX_OC1
-#error MAX_BYTEMODE must be less than DREX_OC1
-#endif
 
 #define FLOATCODE              1
 #define USE_REG_TABLE          (FLOATCODE + 1)
@@ -957,7 +929,37 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_VEX_383F                (PREFIX_VEX_383E + 1)
 #define PREFIX_VEX_3840                (PREFIX_VEX_383F + 1)
 #define PREFIX_VEX_3841                (PREFIX_VEX_3840 + 1)
-#define PREFIX_VEX_38DB                (PREFIX_VEX_3841 + 1)
+#define PREFIX_VEX_3896                (PREFIX_VEX_3841 + 1)
+#define PREFIX_VEX_3897                (PREFIX_VEX_3896 + 1)
+#define PREFIX_VEX_3898                (PREFIX_VEX_3897 + 1)
+#define PREFIX_VEX_3899                (PREFIX_VEX_3898 + 1)
+#define PREFIX_VEX_389A                (PREFIX_VEX_3899 + 1)
+#define PREFIX_VEX_389B                (PREFIX_VEX_389A + 1)
+#define PREFIX_VEX_389C                (PREFIX_VEX_389B + 1)
+#define PREFIX_VEX_389D                (PREFIX_VEX_389C + 1)
+#define PREFIX_VEX_389E                (PREFIX_VEX_389D + 1)
+#define PREFIX_VEX_389F                (PREFIX_VEX_389E + 1)
+#define PREFIX_VEX_38A6                (PREFIX_VEX_389F + 1)
+#define PREFIX_VEX_38A7                (PREFIX_VEX_38A6 + 1)
+#define PREFIX_VEX_38A8                (PREFIX_VEX_38A7 + 1)
+#define PREFIX_VEX_38A9                (PREFIX_VEX_38A8 + 1)
+#define PREFIX_VEX_38AA                (PREFIX_VEX_38A9 + 1)
+#define PREFIX_VEX_38AB                (PREFIX_VEX_38AA + 1)
+#define PREFIX_VEX_38AC                (PREFIX_VEX_38AB + 1)
+#define PREFIX_VEX_38AD                (PREFIX_VEX_38AC + 1)
+#define PREFIX_VEX_38AE                (PREFIX_VEX_38AD + 1)
+#define PREFIX_VEX_38AF                (PREFIX_VEX_38AE + 1)
+#define PREFIX_VEX_38B6                (PREFIX_VEX_38AF + 1)
+#define PREFIX_VEX_38B7                (PREFIX_VEX_38B6 + 1)
+#define PREFIX_VEX_38B8                (PREFIX_VEX_38B7 + 1)
+#define PREFIX_VEX_38B9                (PREFIX_VEX_38B8 + 1)
+#define PREFIX_VEX_38BA                (PREFIX_VEX_38B9 + 1)
+#define PREFIX_VEX_38BB                (PREFIX_VEX_38BA + 1)
+#define PREFIX_VEX_38BC                (PREFIX_VEX_38BB + 1)
+#define PREFIX_VEX_38BD                (PREFIX_VEX_38BC + 1)
+#define PREFIX_VEX_38BE                (PREFIX_VEX_38BD + 1)
+#define PREFIX_VEX_38BF                (PREFIX_VEX_38BE + 1)
+#define PREFIX_VEX_38DB                (PREFIX_VEX_38BF + 1)
 #define PREFIX_VEX_38DC                (PREFIX_VEX_38DB + 1)
 #define PREFIX_VEX_38DD                (PREFIX_VEX_38DC + 1)
 #define PREFIX_VEX_38DE                (PREFIX_VEX_38DD + 1)
@@ -985,9 +987,8 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_VEX_3A40                (PREFIX_VEX_3A22 + 1)
 #define PREFIX_VEX_3A41                (PREFIX_VEX_3A40 + 1)
 #define PREFIX_VEX_3A42                (PREFIX_VEX_3A41 + 1)
-#define PREFIX_VEX_3A48                (PREFIX_VEX_3A42 + 1)
-#define PREFIX_VEX_3A49                (PREFIX_VEX_3A48 + 1)
-#define PREFIX_VEX_3A4A                (PREFIX_VEX_3A49 + 1)
+#define PREFIX_VEX_3A44                (PREFIX_VEX_3A42 + 1)
+#define PREFIX_VEX_3A4A                (PREFIX_VEX_3A44 + 1)
 #define PREFIX_VEX_3A4B                (PREFIX_VEX_3A4A + 1)
 #define PREFIX_VEX_3A4C                (PREFIX_VEX_3A4B + 1)
 #define PREFIX_VEX_3A5C                (PREFIX_VEX_3A4C + 1)
@@ -1045,12 +1046,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define X86_64_0F01_REG_2      (X86_64_0F01_REG_1 + 1)
 #define X86_64_0F01_REG_3      (X86_64_0F01_REG_2 + 1)
 
-#define THREE_BYTE_0F24                0
-#define THREE_BYTE_0F25                (THREE_BYTE_0F24 + 1)
-#define THREE_BYTE_0F38                (THREE_BYTE_0F25 + 1)
+#define THREE_BYTE_0F38                0
 #define THREE_BYTE_0F3A                (THREE_BYTE_0F38 + 1)
 #define THREE_BYTE_0F7A                (THREE_BYTE_0F3A + 1)
-#define THREE_BYTE_0F7B                (THREE_BYTE_0F7A + 1)
 
 #define VEX_0F                 0
 #define VEX_0F38               (VEX_0F + 1)
@@ -1070,8 +1068,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define VEX_LEN_17_M_0 (VEX_LEN_16_P_2 + 1)
 #define VEX_LEN_2A_P_1 (VEX_LEN_17_M_0 + 1)
 #define VEX_LEN_2A_P_3 (VEX_LEN_2A_P_1 + 1)
-#define VEX_LEN_2B_M_0 (VEX_LEN_2A_P_3 + 1)
-#define VEX_LEN_2C_P_1 (VEX_LEN_2B_M_0 + 1)
+#define VEX_LEN_2C_P_1 (VEX_LEN_2A_P_3 + 1)
 #define VEX_LEN_2C_P_3 (VEX_LEN_2C_P_1 + 1)
 #define VEX_LEN_2D_P_1 (VEX_LEN_2C_P_3 + 1)
 #define VEX_LEN_2D_P_3 (VEX_LEN_2D_P_1 + 1)
@@ -1157,8 +1154,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define VEX_LEN_E3_P_2 (VEX_LEN_E2_P_2 + 1)
 #define VEX_LEN_E4_P_2 (VEX_LEN_E3_P_2 + 1)
 #define VEX_LEN_E5_P_2 (VEX_LEN_E4_P_2 + 1)
-#define VEX_LEN_E7_P_2_M_0     (VEX_LEN_E5_P_2 + 1)
-#define VEX_LEN_E8_P_2 (VEX_LEN_E7_P_2_M_0 + 1)
+#define VEX_LEN_E8_P_2 (VEX_LEN_E5_P_2 + 1)
 #define VEX_LEN_E9_P_2 (VEX_LEN_E8_P_2 + 1)
 #define VEX_LEN_EA_P_2 (VEX_LEN_E9_P_2 + 1)
 #define VEX_LEN_EB_P_2 (VEX_LEN_EA_P_2 + 1)
@@ -1245,7 +1241,8 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define VEX_LEN_3A22_P_2       (VEX_LEN_3A21_P_2 + 1)
 #define VEX_LEN_3A41_P_2       (VEX_LEN_3A22_P_2 + 1)
 #define VEX_LEN_3A42_P_2       (VEX_LEN_3A41_P_2 + 1)
-#define VEX_LEN_3A4C_P_2       (VEX_LEN_3A42_P_2 + 1)
+#define VEX_LEN_3A44_P_2       (VEX_LEN_3A42_P_2 + 1)
+#define VEX_LEN_3A4C_P_2       (VEX_LEN_3A44_P_2 + 1)
 #define VEX_LEN_3A60_P_2       (VEX_LEN_3A4C_P_2 + 1)
 #define VEX_LEN_3A61_P_2       (VEX_LEN_3A60_P_2 + 1)
 #define VEX_LEN_3A62_P_2       (VEX_LEN_3A61_P_2 + 1)
@@ -1310,6 +1307,7 @@ struct dis386 {
    2 upper case letter macros:
    "XY" => print 'x' or 'y' if no register operands or suffix_always
           is true.
+   'XW' => print 's', 'd' depending on the VEX.W bit (for FMA)
    'LQ' => print 'l' ('d' in Intel mode) or 'q' for memory operand
           or suffix_always is true
 
@@ -1323,8 +1321,8 @@ static const struct dis386 dis386[] = {
   /* 00 */
   { "addB",            { Eb, Gb } },
   { "addS",            { Ev, Gv } },
-  { "addB",            { Gb, Eb } },
-  { "addS",            { Gv, Ev } },
+  { "addB",            { Gb, EbS } },
+  { "addS",            { Gv, EvS } },
   { "addB",            { AL, Ib } },
   { "addS",            { eAX, Iv } },
   { X86_64_TABLE (X86_64_06) },
@@ -1332,8 +1330,8 @@ static const struct dis386 dis386[] = {
   /* 08 */
   { "orB",             { Eb, Gb } },
   { "orS",             { Ev, Gv } },
-  { "orB",             { Gb, Eb } },
-  { "orS",             { Gv, Ev } },
+  { "orB",             { Gb, EbS } },
+  { "orS",             { Gv, EvS } },
   { "orB",             { AL, Ib } },
   { "orS",             { eAX, Iv } },
   { X86_64_TABLE (X86_64_0D) },
@@ -1341,8 +1339,8 @@ static const struct dis386 dis386[] = {
   /* 10 */
   { "adcB",            { Eb, Gb } },
   { "adcS",            { Ev, Gv } },
-  { "adcB",            { Gb, Eb } },
-  { "adcS",            { Gv, Ev } },
+  { "adcB",            { Gb, EbS } },
+  { "adcS",            { Gv, EvS } },
   { "adcB",            { AL, Ib } },
   { "adcS",            { eAX, Iv } },
   { X86_64_TABLE (X86_64_16) },
@@ -1350,8 +1348,8 @@ static const struct dis386 dis386[] = {
   /* 18 */
   { "sbbB",            { Eb, Gb } },
   { "sbbS",            { Ev, Gv } },
-  { "sbbB",            { Gb, Eb } },
-  { "sbbS",            { Gv, Ev } },
+  { "sbbB",            { Gb, EbS } },
+  { "sbbS",            { Gv, EvS } },
   { "sbbB",            { AL, Ib } },
   { "sbbS",            { eAX, Iv } },
   { X86_64_TABLE (X86_64_1E) },
@@ -1359,8 +1357,8 @@ static const struct dis386 dis386[] = {
   /* 20 */
   { "andB",            { Eb, Gb } },
   { "andS",            { Ev, Gv } },
-  { "andB",            { Gb, Eb } },
-  { "andS",            { Gv, Ev } },
+  { "andB",            { Gb, EbS } },
+  { "andS",            { Gv, EvS } },
   { "andB",            { AL, Ib } },
   { "andS",            { eAX, Iv } },
   { "(bad)",           { XX } },       /* SEG ES prefix */
@@ -1368,8 +1366,8 @@ static const struct dis386 dis386[] = {
   /* 28 */
   { "subB",            { Eb, Gb } },
   { "subS",            { Ev, Gv } },
-  { "subB",            { Gb, Eb } },
-  { "subS",            { Gv, Ev } },
+  { "subB",            { Gb, EbS } },
+  { "subS",            { Gv, EvS } },
   { "subB",            { AL, Ib } },
   { "subS",            { eAX, Iv } },
   { "(bad)",           { XX } },       /* SEG CS prefix */
@@ -1377,8 +1375,8 @@ static const struct dis386 dis386[] = {
   /* 30 */
   { "xorB",            { Eb, Gb } },
   { "xorS",            { Ev, Gv } },
-  { "xorB",            { Gb, Eb } },
-  { "xorS",            { Gv, Ev } },
+  { "xorB",            { Gb, EbS } },
+  { "xorS",            { Gv, EvS } },
   { "xorB",            { AL, Ib } },
   { "xorS",            { eAX, Iv } },
   { "(bad)",           { XX } },       /* SEG SS prefix */
@@ -1386,8 +1384,8 @@ static const struct dis386 dis386[] = {
   /* 38 */
   { "cmpB",            { Eb, Gb } },
   { "cmpS",            { Ev, Gv } },
-  { "cmpB",            { Gb, Eb } },
-  { "cmpS",            { Gv, Ev } },
+  { "cmpB",            { Gb, EbS } },
+  { "cmpS",            { Gv, EvS } },
   { "cmpB",            { AL, Ib } },
   { "cmpS",            { eAX, Iv } },
   { "(bad)",           { XX } },       /* SEG DS prefix */
@@ -1653,7 +1651,7 @@ static const struct dis386 dis386_twobyte[] = {
   { MOD_TABLE (MOD_0F22) },
   { MOD_TABLE (MOD_0F23) },
   { MOD_TABLE (MOD_0F24) },
-  { THREE_BYTE_TABLE (THREE_BYTE_0F25) },
+  { "(bad)",           { XX } },
   { MOD_TABLE (MOD_0F26) },
   { "(bad)",           { XX } },
   /* 28 */
@@ -1750,7 +1748,7 @@ static const struct dis386 dis386_twobyte[] = {
   { PREFIX_TABLE (PREFIX_0F78) },
   { PREFIX_TABLE (PREFIX_0F79) },
   { THREE_BYTE_TABLE (THREE_BYTE_0F7A) },
-  { THREE_BYTE_TABLE (THREE_BYTE_0F7B) },
+  { "(bad)",           { XX } },
   { PREFIX_TABLE (PREFIX_0F7C) },
   { PREFIX_TABLE (PREFIX_0F7D) },
   { PREFIX_TABLE (PREFIX_0F7E) },
@@ -4573,6 +4571,246 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
+  /* PREFIX_VEX_3896 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddsub132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3897 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubadd132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3898 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3899 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd132s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389A */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389B */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub132s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389C */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389D */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd132s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389E */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub132p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_389F */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub132s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38A6 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddsub213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38A7 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubadd213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38A8 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38A9 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd213s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AA */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AB */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub213s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AC */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AD */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd213s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AE */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub213p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38AF */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub213s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38B6 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddsub231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38B7 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubadd231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38B8 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38B9 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmadd231s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BA */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BB */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsub231s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BC */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BD */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmadd231s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BE */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub231p%XW", { XM, Vex, EXx } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_38BF */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsub231s%XW", { XM, Vex, EXVexWdq } },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_VEX_38DB */
   {
     { "(bad)", { XX } },
@@ -4797,19 +5035,11 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A48 */
-  {
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "vpermil2ps", { XMVexW, Vex, EXVexImmW, EXVexImmW, VPERMIL2 } },
-    { "(bad)", { XX } },
-  },
-
-  /* PREFIX_VEX_3A49 */
+  /* PREFIX_VEX_3A44 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vpermil2pd", { XMVexW, Vex, EXVexImmW, EXVexImmW, VPERMIL2 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A44_P_2) },
     { "(bad)", { XX } },
   },
 
@@ -5209,960 +5439,88 @@ static const struct dis386 x86_64_table[][2] = {
 };
 
 static const struct dis386 three_byte_table[][256] = {
-  /* THREE_BYTE_0F24 */
+
+  /* THREE_BYTE_0F38 */
   {
     /* 00 */
-    { "fmaddps",       { { OP_DREX4, q_mode } } },
-    { "fmaddpd",       { { OP_DREX4, q_mode } } },
-    { "fmaddss",       { { OP_DREX4, w_mode } } },
-    { "fmaddsd",       { { OP_DREX4, d_mode } } },
-    { "fmaddps",       { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fmaddpd",       { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fmaddss",       { { OP_DREX4, DREX_OC1 + w_mode } } },
-    { "fmaddsd",       { { OP_DREX4, DREX_OC1 + d_mode } } },
+    { "pshufb",                { MX, EM } },
+    { "phaddw",                { MX, EM } },
+    { "phaddd",                { MX, EM } },
+    { "phaddsw",       { MX, EM } },
+    { "pmaddubsw",     { MX, EM } },
+    { "phsubw",                { MX, EM } },
+    { "phsubd",                { MX, EM } },
+    { "phsubsw",       { MX, EM } },
     /* 08 */
-    { "fmsubps",       { { OP_DREX4, q_mode } } },
-    { "fmsubpd",       { { OP_DREX4, q_mode } } },
-    { "fmsubss",       { { OP_DREX4, w_mode } } },
-    { "fmsubsd",       { { OP_DREX4, d_mode } } },
-    { "fmsubps",       { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fmsubpd",       { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fmsubss",       { { OP_DREX4, DREX_OC1 + w_mode } } },
-    { "fmsubsd",       { { OP_DREX4, DREX_OC1 + d_mode } } },
-    /* 10 */
-    { "fnmaddps",      { { OP_DREX4, q_mode } } },
-    { "fnmaddpd",      { { OP_DREX4, q_mode } } },
-    { "fnmaddss",      { { OP_DREX4, w_mode } } },
-    { "fnmaddsd",      { { OP_DREX4, d_mode } } },
-    { "fnmaddps",      { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fnmaddpd",      { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fnmaddss",      { { OP_DREX4, DREX_OC1 + w_mode } } },
-    { "fnmaddsd",      { { OP_DREX4, DREX_OC1 + d_mode } } },
-    /* 18 */
-    { "fnmsubps",      { { OP_DREX4, q_mode } } },
-    { "fnmsubpd",      { { OP_DREX4, q_mode } } },
-    { "fnmsubss",      { { OP_DREX4, w_mode } } },
-    { "fnmsubsd",      { { OP_DREX4, d_mode } } },
-    { "fnmsubps",      { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fnmsubpd",      { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "fnmsubss",      { { OP_DREX4, DREX_OC1 + w_mode } } },
-    { "fnmsubsd",      { { OP_DREX4, DREX_OC1 + d_mode } } },
-    /* 20 */
-    { "permps",                { { OP_DREX4, q_mode } } },
-    { "permpd",                { { OP_DREX4, q_mode } } },
-    { "pcmov",         { { OP_DREX4, q_mode } } },
-    { "pperm",         { { OP_DREX4, q_mode } } },
-    { "permps",                { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "permpd",                { { OP_DREX4, DREX_OC1 + q_mode } } },
-    { "pcmov",         { { OP_DREX4, DREX_OC1 + w_mode } } },
-    { "pperm",         { { OP_DREX4, DREX_OC1 + d_mode } } },
-    /* 28 */
+    { "psignb",                { MX, EM } },
+    { "psignw",                { MX, EM } },
+    { "psignd",                { MX, EM } },
+    { "pmulhrsw",      { MX, EM } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 10 */
+    { PREFIX_TABLE (PREFIX_0F3810) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3814) },
+    { PREFIX_TABLE (PREFIX_0F3815) },
     { "(bad)",         { XX } },
-    /* 30 */
+    { PREFIX_TABLE (PREFIX_0F3817) },
+    /* 18 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { "pabsb",         { MX, EM } },
+    { "pabsw",         { MX, EM } },
+    { "pabsd",         { MX, EM } },
     { "(bad)",         { XX } },
+    /* 20 */
+    { PREFIX_TABLE (PREFIX_0F3820) },
+    { PREFIX_TABLE (PREFIX_0F3821) },
+    { PREFIX_TABLE (PREFIX_0F3822) },
+    { PREFIX_TABLE (PREFIX_0F3823) },
+    { PREFIX_TABLE (PREFIX_0F3824) },
+    { PREFIX_TABLE (PREFIX_0F3825) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 28 */
+    { PREFIX_TABLE (PREFIX_0F3828) },
+    { PREFIX_TABLE (PREFIX_0F3829) },
+    { PREFIX_TABLE (PREFIX_0F382A) },
+    { PREFIX_TABLE (PREFIX_0F382B) },
     { "(bad)",         { XX } },
-    /* 38 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 30 */
+    { PREFIX_TABLE (PREFIX_0F3830) },
+    { PREFIX_TABLE (PREFIX_0F3831) },
+    { PREFIX_TABLE (PREFIX_0F3832) },
+    { PREFIX_TABLE (PREFIX_0F3833) },
+    { PREFIX_TABLE (PREFIX_0F3834) },
+    { PREFIX_TABLE (PREFIX_0F3835) },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3837) },
+    /* 38 */
+    { PREFIX_TABLE (PREFIX_0F3838) },
+    { PREFIX_TABLE (PREFIX_0F3839) },
+    { PREFIX_TABLE (PREFIX_0F383A) },
+    { PREFIX_TABLE (PREFIX_0F383B) },
+    { PREFIX_TABLE (PREFIX_0F383C) },
+    { PREFIX_TABLE (PREFIX_0F383D) },
+    { PREFIX_TABLE (PREFIX_0F383E) },
+    { PREFIX_TABLE (PREFIX_0F383F) },
+    /* 40 */
+    { PREFIX_TABLE (PREFIX_0F3840) },
+    { PREFIX_TABLE (PREFIX_0F3841) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* 40 */
-    { "protb",         { { OP_DREX3, q_mode } } },
-    { "protw",         { { OP_DREX3, q_mode } } },
-    { "protd",         { { OP_DREX3, q_mode } } },
-    { "protq",         { { OP_DREX3, q_mode } } },
-    { "pshlb",         { { OP_DREX3, q_mode } } },
-    { "pshlw",         { { OP_DREX3, q_mode } } },
-    { "pshld",         { { OP_DREX3, q_mode } } },
-    { "pshlq",         { { OP_DREX3, q_mode } } },
-    /* 48 */
-    { "pshab",         { { OP_DREX3, q_mode } } },
-    { "pshaw",         { { OP_DREX3, q_mode } } },
-    { "pshad",         { { OP_DREX3, q_mode } } },
-    { "pshaq",         { { OP_DREX3, q_mode } } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 50 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 58 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 60 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 68 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 70 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 78 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 80 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmacssww",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacsswd",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacssdql",     { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    /* 88 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmacssdd",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacssdqh",     { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    /* 90 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmacsww",       { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacswd",       { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacsdql",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    /* 98 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmacsdd",       { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "pmacsdqh",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    /* a0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmadcsswd",     { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "(bad)",         { XX } },
-    /* a8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* b0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pmadcswd",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
-    { "(bad)",         { XX } },
-    /* b8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* e0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* e8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-  },
-  /* THREE_BYTE_0F25 */
-  {
-    /* 00 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 08 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 10 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 18 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 20 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 28 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "comps",         { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } },
-    { "compd",         { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } },
-    { "comss",         { { OP_DREX3, w_mode }, { OP_DREX_FCMP, b_mode } } },
-    { "comsd",         { { OP_DREX3, d_mode }, { OP_DREX_FCMP, b_mode } } },
-    /* 30 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 38 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 40 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 48 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pcomb",         { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomw",         { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomd",         { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomq",         { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    /* 50 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 58 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 60 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 68 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pcomub",                { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomuw",                { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomud",                { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    { "pcomuq",                { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } },
-    /* 70 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 78 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 80 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 88 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 90 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 98 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* b0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* b8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* e0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* e8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-  },
-  /* THREE_BYTE_0F38 */
-  {
-    /* 00 */
-    { "pshufb",                { MX, EM } },
-    { "phaddw",                { MX, EM } },
-    { "phaddd",                { MX, EM } },
-    { "phaddsw",       { MX, EM } },
-    { "pmaddubsw",     { MX, EM } },
-    { "phsubw",                { MX, EM } },
-    { "phsubd",                { MX, EM } },
-    { "phsubsw",       { MX, EM } },
-    /* 08 */
-    { "psignb",                { MX, EM } },
-    { "psignw",                { MX, EM } },
-    { "psignd",                { MX, EM } },
-    { "pmulhrsw",      { MX, EM } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 10 */
-    { PREFIX_TABLE (PREFIX_0F3810) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3814) },
-    { PREFIX_TABLE (PREFIX_0F3815) },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3817) },
-    /* 18 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "pabsb",         { MX, EM } },
-    { "pabsw",         { MX, EM } },
-    { "pabsd",         { MX, EM } },
-    { "(bad)",         { XX } },
-    /* 20 */
-    { PREFIX_TABLE (PREFIX_0F3820) },
-    { PREFIX_TABLE (PREFIX_0F3821) },
-    { PREFIX_TABLE (PREFIX_0F3822) },
-    { PREFIX_TABLE (PREFIX_0F3823) },
-    { PREFIX_TABLE (PREFIX_0F3824) },
-    { PREFIX_TABLE (PREFIX_0F3825) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 28 */
-    { PREFIX_TABLE (PREFIX_0F3828) },
-    { PREFIX_TABLE (PREFIX_0F3829) },
-    { PREFIX_TABLE (PREFIX_0F382A) },
-    { PREFIX_TABLE (PREFIX_0F382B) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 30 */
-    { PREFIX_TABLE (PREFIX_0F3830) },
-    { PREFIX_TABLE (PREFIX_0F3831) },
-    { PREFIX_TABLE (PREFIX_0F3832) },
-    { PREFIX_TABLE (PREFIX_0F3833) },
-    { PREFIX_TABLE (PREFIX_0F3834) },
-    { PREFIX_TABLE (PREFIX_0F3835) },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3837) },
-    /* 38 */
-    { PREFIX_TABLE (PREFIX_0F3838) },
-    { PREFIX_TABLE (PREFIX_0F3839) },
-    { PREFIX_TABLE (PREFIX_0F383A) },
-    { PREFIX_TABLE (PREFIX_0F383B) },
-    { PREFIX_TABLE (PREFIX_0F383C) },
-    { PREFIX_TABLE (PREFIX_0F383D) },
-    { PREFIX_TABLE (PREFIX_0F383E) },
-    { PREFIX_TABLE (PREFIX_0F383F) },
-    /* 40 */
-    { PREFIX_TABLE (PREFIX_0F3840) },
-    { PREFIX_TABLE (PREFIX_0F3841) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 48 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 50 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 58 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 60 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 68 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 70 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 78 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 80 */
-    { PREFIX_TABLE (PREFIX_0F3880) },
-    { PREFIX_TABLE (PREFIX_0F3881) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 88 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 90 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 98 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* b0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* b8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* c8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* d8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F38DB) },
-    { PREFIX_TABLE (PREFIX_0F38DC) },
-    { PREFIX_TABLE (PREFIX_0F38DD) },
-    { PREFIX_TABLE (PREFIX_0F38DE) },
-    { PREFIX_TABLE (PREFIX_0F38DF) },
-    /* e0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* e8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f0 */
-    { PREFIX_TABLE (PREFIX_0F38F0) },
-    { PREFIX_TABLE (PREFIX_0F38F1) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* f8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-  },
-  /* THREE_BYTE_0F3A */
-  {
-    /* 00 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 08 */
-    { PREFIX_TABLE (PREFIX_0F3A08) },
-    { PREFIX_TABLE (PREFIX_0F3A09) },
-    { PREFIX_TABLE (PREFIX_0F3A0A) },
-    { PREFIX_TABLE (PREFIX_0F3A0B) },
-    { PREFIX_TABLE (PREFIX_0F3A0C) },
-    { PREFIX_TABLE (PREFIX_0F3A0D) },
-    { PREFIX_TABLE (PREFIX_0F3A0E) },
-    { "palignr",       { MX, EM, Ib } },
-    /* 10 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3A14) },
-    { PREFIX_TABLE (PREFIX_0F3A15) },
-    { PREFIX_TABLE (PREFIX_0F3A16) },
-    { PREFIX_TABLE (PREFIX_0F3A17) },
-    /* 18 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 20 */
-    { PREFIX_TABLE (PREFIX_0F3A20) },
-    { PREFIX_TABLE (PREFIX_0F3A21) },
-    { PREFIX_TABLE (PREFIX_0F3A22) },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 28 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 30 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 38 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 40 */
-    { PREFIX_TABLE (PREFIX_0F3A40) },
-    { PREFIX_TABLE (PREFIX_0F3A41) },
-    { PREFIX_TABLE (PREFIX_0F3A42) },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3A44) },
-    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 48 */
@@ -6193,10 +5551,10 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 60 */
-    { PREFIX_TABLE (PREFIX_0F3A60) },
-    { PREFIX_TABLE (PREFIX_0F3A61) },
-    { PREFIX_TABLE (PREFIX_0F3A62) },
-    { PREFIX_TABLE (PREFIX_0F3A63) },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6229,8 +5587,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 80 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3880) },
+    { PREFIX_TABLE (PREFIX_0F3881) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6331,11 +5689,11 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { PREFIX_TABLE (PREFIX_0F3ADF) },
+    { PREFIX_TABLE (PREFIX_0F38DB) },
+    { PREFIX_TABLE (PREFIX_0F38DC) },
+    { PREFIX_TABLE (PREFIX_0F38DD) },
+    { PREFIX_TABLE (PREFIX_0F38DE) },
+    { PREFIX_TABLE (PREFIX_0F38DF) },
     /* e0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6355,8 +5713,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* f0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F38F0) },
+    { PREFIX_TABLE (PREFIX_0F38F1) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6373,7 +5731,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
   },
-  /* THREE_BYTE_0F7A */
+  /* THREE_BYTE_0F3A */
   {
     /* 00 */
     { "(bad)",         { XX } },
@@ -6385,23 +5743,23 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 08 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3A08) },
+    { PREFIX_TABLE (PREFIX_0F3A09) },
+    { PREFIX_TABLE (PREFIX_0F3A0A) },
+    { PREFIX_TABLE (PREFIX_0F3A0B) },
+    { PREFIX_TABLE (PREFIX_0F3A0C) },
+    { PREFIX_TABLE (PREFIX_0F3A0D) },
+    { PREFIX_TABLE (PREFIX_0F3A0E) },
+    { "palignr",       { MX, EM, Ib } },
     /* 10 */
-    { "frczps",                { XM, EXq } },
-    { "frczpd",                { XM, EXq } },
-    { "frczss",                { XM, EXq } },
-    { "frczsd",                { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3A14) },
+    { PREFIX_TABLE (PREFIX_0F3A15) },
+    { PREFIX_TABLE (PREFIX_0F3A16) },
+    { PREFIX_TABLE (PREFIX_0F3A17) },
     /* 18 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6412,9 +5770,9 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 20 */
-    { "ptest",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3A20) },
+    { PREFIX_TABLE (PREFIX_0F3A21) },
+    { PREFIX_TABLE (PREFIX_0F3A22) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6430,8 +5788,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 30 */
-    { "cvtph2ps",      { XM, EXd } },
-    { "cvtps2ph",      { EXd, XM } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6448,46 +5806,46 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 40 */
+    { PREFIX_TABLE (PREFIX_0F3A40) },
+    { PREFIX_TABLE (PREFIX_0F3A41) },
+    { PREFIX_TABLE (PREFIX_0F3A42) },
+    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3A44) },
     { "(bad)",         { XX } },
-    { "phaddbw",       { XM, EXq } },
-    { "phaddbd",       { XM, EXq } },
-    { "phaddbq",       { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "phaddwd",       { XM, EXq } },
-    { "phaddwq",       { XM, EXq } },
     /* 48 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "phadddq",       { XM, EXq } },
+    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 50 */
     { "(bad)",         { XX } },
-    { "phaddubw",      { XM, EXq } },
-    { "phaddubd",      { XM, EXq } },
-    { "phaddubq",      { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "phadduwd",      { XM, EXq } },
-    { "phadduwq",      { XM, EXq } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 58 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "phaddudq",      { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* 60 */
     { "(bad)",         { XX } },
-    { "phsubbw",       { XM, EXq } },
-    { "phsubbd",       { XM, EXq } },
-    { "phsubbq",       { XM, EXq } },
+    /* 60 */
+    { PREFIX_TABLE (PREFIX_0F3A60) },
+    { PREFIX_TABLE (PREFIX_0F3A61) },
+    { PREFIX_TABLE (PREFIX_0F3A62) },
+    { PREFIX_TABLE (PREFIX_0F3A63) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6626,7 +5984,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_0F3ADF) },
     /* e0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6664,7 +6022,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
   },
-  /* THREE_BYTE_0F7B */
+
+  /* THREE_BYTE_0F7A */
   {
     /* 00 */
     { "(bad)",         { XX } },
@@ -6703,7 +6062,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 20 */
-    { "(bad)",         { XX } },
+    { "ptest",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6739,46 +6098,46 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 40 */
-    { "protb",         { XM, EXq, Ib } },
-    { "protw",         { XM, EXq, Ib } },
-    { "protd",         { XM, EXq, Ib } },
-    { "protq",         { XM, EXq, Ib } },
-    { "pshlb",         { XM, EXq, Ib } },
-    { "pshlw",         { XM, EXq, Ib } },
-    { "pshld",         { XM, EXq, Ib } },
-    { "pshlq",         { XM, EXq, Ib } },
-    /* 48 */
-    { "pshab",         { XM, EXq, Ib } },
-    { "pshaw",         { XM, EXq, Ib } },
-    { "pshad",         { XM, EXq, Ib } },
-    { "pshaq",         { XM, EXq, Ib } },
+    { "(bad)",         { XX } },
+    { "phaddbw",       { XM, EXq } },
+    { "phaddbd",       { XM, EXq } },
+    { "phaddbq",       { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { "phaddwd",       { XM, EXq } },
+    { "phaddwq",       { XM, EXq } },
+    /* 48 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* 50 */
     { "(bad)",         { XX } },
+    { "phadddq",       { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 50 */
     { "(bad)",         { XX } },
+    { "phaddubw",      { XM, EXq } },
+    { "phaddubd",      { XM, EXq } },
+    { "phaddubq",      { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { "phadduwd",      { XM, EXq } },
+    { "phadduwq",      { XM, EXq } },
     /* 58 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { "phaddudq",      { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 60 */
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { "phsubbw",       { XM, EXq } },
+    { "phsubbd",       { XM, EXq } },
+    { "phsubbq",       { XM, EXq } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -6957,6 +6316,7 @@ static const struct dis386 three_byte_table[][256] = {
   },
 };
 
+
 static const struct dis386 vex_table[][256] = {
   /* VEX_0F */
   {
@@ -7413,60 +6773,60 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* 90 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* 98 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a0 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a8 */
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    /* 90 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* b0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_3896) },
+    { PREFIX_TABLE (PREFIX_VEX_3897) },
+    /* 98 */
+    { PREFIX_TABLE (PREFIX_VEX_3898) },
+    { PREFIX_TABLE (PREFIX_VEX_3899) },
+    { PREFIX_TABLE (PREFIX_VEX_389A) },
+    { PREFIX_TABLE (PREFIX_VEX_389B) },
+    { PREFIX_TABLE (PREFIX_VEX_389C) },
+    { PREFIX_TABLE (PREFIX_VEX_389D) },
+    { PREFIX_TABLE (PREFIX_VEX_389E) },
+    { PREFIX_TABLE (PREFIX_VEX_389F) },
+    /* a0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* b8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_38A6) },
+    { PREFIX_TABLE (PREFIX_VEX_38A7) },
+    /* a8 */
+    { PREFIX_TABLE (PREFIX_VEX_38A8) },
+    { PREFIX_TABLE (PREFIX_VEX_38A9) },
+    { PREFIX_TABLE (PREFIX_VEX_38AA) },
+    { PREFIX_TABLE (PREFIX_VEX_38AB) },
+    { PREFIX_TABLE (PREFIX_VEX_38AC) },
+    { PREFIX_TABLE (PREFIX_VEX_38AD) },
+    { PREFIX_TABLE (PREFIX_VEX_38AE) },
+    { PREFIX_TABLE (PREFIX_VEX_38AF) },
+    /* b0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_38B6) },
+    { PREFIX_TABLE (PREFIX_VEX_38B7) },
+    /* b8 */
+    { PREFIX_TABLE (PREFIX_VEX_38B8) },
+    { PREFIX_TABLE (PREFIX_VEX_38B9) },
+    { PREFIX_TABLE (PREFIX_VEX_38BA) },
+    { PREFIX_TABLE (PREFIX_VEX_38BB) },
+    { PREFIX_TABLE (PREFIX_VEX_38BC) },
+    { PREFIX_TABLE (PREFIX_VEX_38BD) },
+    { PREFIX_TABLE (PREFIX_VEX_38BE) },
+    { PREFIX_TABLE (PREFIX_VEX_38BF) },
     /* c0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7619,13 +6979,13 @@ static const struct dis386 vex_table[][256] = {
     { PREFIX_TABLE (PREFIX_VEX_3A41) },
     { PREFIX_TABLE (PREFIX_VEX_3A42) },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_3A44) },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 48 */
-    { PREFIX_TABLE (PREFIX_VEX_3A48) },
-    { PREFIX_TABLE (PREFIX_VEX_3A49) },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     { PREFIX_TABLE (PREFIX_VEX_3A4A) },
     { PREFIX_TABLE (PREFIX_VEX_3A4B) },
     { PREFIX_TABLE (PREFIX_VEX_3A4C) },
@@ -7918,12 +7278,6 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
-  /* VEX_LEN_2B_M_0 */
-  {
-    { "vmovntpX",      { Mx, XM } },
-    { "(bad)",         { XX } },
-  },
-
   /* VEX_LEN_2C_P_1 */
   {
     { "vcvttss2siY",   { Gv, EXd } },
@@ -8278,13 +7632,13 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
-  /* VEX_LEN_AE_R_2_M0 */
+  /* VEX_LEN_AE_R_2_M_0 */
   {
     { "vldmxcsr",      { Md } },
     { "(bad)",         { XX } },
   },
 
-  /* VEX_LEN_AE_R_3_M0 */
+  /* VEX_LEN_AE_R_3_M_0 */
   {
     { "vstmxcsr",      { Md } },
     { "(bad)",         { XX } },
@@ -8440,12 +7794,6 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
-  /* VEX_LEN_E7_P_2_M_0 */
-  {
-    { "vmovntdq",      { Mx, XM } },
-    { "(bad)",         { XX } },
-  },
-
   /* VEX_LEN_E8_P_2 */
   {
     { "vpsubsb",       { XM, Vex128, EXx } },
@@ -8968,6 +8316,12 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
+  /* VEX_LEN_3A44_P_2 */
+  {
+    { "vpclmulqdq",    { XM, Vex128, EXx, PCLMUL } },
+    { "(bad)",         { XX } },
+  },
+
   /* VEX_LEN_3A4C_P_2 */
   {
     { "vpblendvb",     { XM, Vex128, EXx, XMVexI4 } },
@@ -9146,7 +8500,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0F24 */
-    { THREE_BYTE_TABLE (THREE_BYTE_0F24) },
+    { "(bad)",         { XX } },    
     { "movL",          { Rd, Td } },
   },
   {
@@ -9351,7 +8705,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_VEX_2B */
-    { VEX_LEN_TABLE (VEX_LEN_2B_M_0) },
+    { "vmovntpX",      { Mx, XM } },
     { "(bad)",         { XX } },
   },
   {
@@ -9426,7 +8780,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_VEX_E7_PREFIX_2 */
-    { VEX_LEN_TABLE (VEX_LEN_E7_P_2_M_0) },
+    { "vmovntdq",      { Mx, XM } },
     { "(bad)",         { XX } },
   },
   {
@@ -10037,8 +9391,7 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       break;
 
     default:
-      oappend (INTERNAL_DISASSEMBLER_ERROR);
-      return NULL;
+      abort ();
     }
 
   if (dp->name != NULL)
@@ -10062,19 +9415,24 @@ print_insn (bfd_vma pc, disassemble_info *info)
   char *prefix_obufp;
 
   if (info->mach == bfd_mach_x86_64_intel_syntax
-      || info->mach == bfd_mach_x86_64)
+      || info->mach == bfd_mach_x86_64
+      || info->mach == bfd_mach_l1om
+      || info->mach == bfd_mach_l1om_intel_syntax)
     address_mode = mode_64bit;
   else
     address_mode = mode_32bit;
 
   if (intel_syntax == (char) -1)
     intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
-                   || info->mach == bfd_mach_x86_64_intel_syntax);
+                   || info->mach == bfd_mach_x86_64_intel_syntax
+                   || info->mach == bfd_mach_l1om_intel_syntax);
 
   if (info->mach == bfd_mach_i386_i386
       || info->mach == bfd_mach_x86_64
+      || info->mach == bfd_mach_l1om
       || info->mach == bfd_mach_i386_i386_intel_syntax
-      || info->mach == bfd_mach_x86_64_intel_syntax)
+      || info->mach == bfd_mach_x86_64_intel_syntax
+      || info->mach == bfd_mach_l1om_intel_syntax)
     priv.orig_sizeflag = AFLAG | DFLAG;
   else if (info->mach == bfd_mach_i386_i8086)
     priv.orig_sizeflag = 0;
@@ -10176,8 +9534,13 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   /* The output looks better if we put 7 bytes on a line, since that
-     puts most long word instructions on a single line.  */
-  info->bytes_per_line = 7;
+     puts most long word instructions on a single line.  Use 8 bytes
+     for Intel L1OM.  */
+  if (info->mach == bfd_mach_l1om
+      || info->mach == bfd_mach_l1om_intel_syntax)
+    info->bytes_per_line = 8;
+  else
+    info->bytes_per_line = 7;
 
   info->private_data = &priv;
   priv.max_fetched = priv.the_buffer;
@@ -10245,6 +9608,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   op = 0;
+
   if (*codep == 0x0f)
     {
       unsigned char threebyte;
@@ -10726,8 +10090,8 @@ static char *fgrps[][8] = {
 
   /* db_4  6 */
   {
-    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
-    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
+    "fNeni(8087 only)","fNdisi(8087 only)","fNclex","fNinit",
+    "fNsetpm(287 only)","frstpm(287 only)","(bad)","(bad)",
   },
 
   /* de_3  7 */
@@ -10820,7 +10184,7 @@ OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 
 /* Capital letters in template are macros.  */
 static int
-putop (const char *template, int sizeflag)
+putop (const char *in_template, int sizeflag)
 {
   const char *p;
   int alt = 0;
@@ -10834,7 +10198,7 @@ putop (const char *template, int sizeflag)
   else                                 \
     abort ();
 
-  for (p = template; *p; p++)
+  for (p = in_template; *p; p++)
     {
       switch (*p)
        {
@@ -11197,21 +10561,35 @@ case_Q:
            }
          break;
        case 'W':
-         /* operand size flag for cwtl, cbtw */
-         USED_REX (REX_W);
-         if (rex & REX_W)
+         if (l == 0 && len == 1)
            {
-             if (intel_syntax)
-               *obufp++ = 'd';
+             /* operand size flag for cwtl, cbtw */
+             USED_REX (REX_W);
+             if (rex & REX_W)
+               {
+                 if (intel_syntax)
+                   *obufp++ = 'd';
+                 else
+                   *obufp++ = 'l';
+               }
+             else if (sizeflag & DFLAG)
+               *obufp++ = 'w';
              else
-               *obufp++ = 'l';
+               *obufp++ = 'b';
+             if (!(rex & REX_W))
+               used_prefixes |= (prefixes & PREFIX_DATA);
            }
-         else if (sizeflag & DFLAG)
-           *obufp++ = 'w';
          else
-           *obufp++ = 'b';
-         if (!(rex & REX_W))
-           used_prefixes |= (prefixes & PREFIX_DATA);
+           {
+             if (l != 1 || len != 2 || last[0] != 'X')
+               {
+                 SAVE_LAST (*p);
+                 break;
+               }
+             if (!need_vex)
+               abort ();
+             *obufp++ = vex.w ? 'd': 's';
+           }
          break;
        }
       alt = 0;
@@ -11501,6 +10879,15 @@ intel_operand_size (int bytemode, int sizeflag)
     case o_mode:
       oappend ("OWORD PTR ");
       break;
+    case vex_w_dq_mode:
+      if (!need_vex)
+       abort ();
+
+      if (vex.w)
+       oappend ("QWORD PTR ");
+      else
+       oappend ("DWORD PTR ");
+      break;
     default:
       break;
     }
@@ -11578,7 +10965,7 @@ OP_E_register (int bytemode, int sizeflag)
 }
 
 static void
-OP_E_memory (int bytemode, int sizeflag, int has_drex)
+OP_E_memory (int bytemode, int sizeflag)
 {
   bfd_vma disp = 0;
   int add = (rex & REX_B) ? 8 : 0;
@@ -11621,14 +11008,6 @@ OP_E_memory (int bytemode, int sizeflag, int has_drex)
        }
       rbase = base + add;
 
-      /* If we have a DREX byte, skip it now 
-        (it has already been handled) */
-      if (has_drex)
-       {
-         FETCH_DATA (the_info, codep + 1);
-         codep++;
-       }
-
       switch (modrm.mod)
        {
        case 0:
@@ -11728,7 +11107,7 @@ OP_E_memory (int bytemode, int sizeflag, int has_drex)
                  *obufp++ = '+';
                  *obufp = '\0';
                }
-             else if (modrm.mod != 1)
+             else if (modrm.mod != 1 && disp != -disp)
                {
                  *obufp++ = '-';
                  *obufp = '\0';
@@ -11838,7 +11217,7 @@ OP_E_memory (int bytemode, int sizeflag, int has_drex)
 }
 
 static void
-OP_E_extended (int bytemode, int sizeflag, int has_drex)
+OP_E_extended (int bytemode, int sizeflag)
 {
   /* Skip mod/rm byte.  */
   MODRM_CHECK;
@@ -11847,13 +11226,13 @@ OP_E_extended (int bytemode, int sizeflag, int has_drex)
   if (modrm.mod == 3)
     OP_E_register (bytemode, sizeflag);
   else
-    OP_E_memory (bytemode, sizeflag, has_drex);
+    OP_E_memory (bytemode, sizeflag);
 }
 
 static void
 OP_E (int bytemode, int sizeflag)
 {
-  OP_E_extended (bytemode, sizeflag, 0);
+  OP_E_extended (bytemode, sizeflag);
 }
 
 
@@ -12646,11 +12025,17 @@ static void
 OP_EX (int bytemode, int sizeflag)
 {
   int add;
+
+  /* Skip mod/rm byte.  */
+  MODRM_CHECK;
+  codep++;
+
   if (modrm.mod != 3)
     {
-      OP_E (bytemode, sizeflag);
+      OP_E_memory (bytemode, sizeflag);
       return;
     }
+
   USED_REX (REX_B);
   if (rex & REX_B)
     add = 8;
@@ -12663,9 +12048,6 @@ OP_EX (int bytemode, int sizeflag)
          || bytemode == q_swap_mode))
     swap_operand ();
 
-  /* Skip mod/rm byte.  */
-  MODRM_CHECK;
-  codep++;
   if (need_vex
       && bytemode != xmm_mode
       && bytemode != xmmq_mode)
@@ -13070,347 +12452,6 @@ skip:
     OP_E (bytemode, sizeflag);
 }
 
-/* Print a DREX argument as either a register or memory operation.  */
-static void
-print_drex_arg (unsigned int reg, int bytemode, int sizeflag)
-{
-  if (reg == DREX_REG_UNKNOWN)
-    BadOp ();
-
-  else if (reg != DREX_REG_MEMORY)
-    {
-      sprintf (scratchbuf, "%%xmm%d", reg);
-      oappend (scratchbuf + intel_syntax);
-    }
-
-  else
-    OP_E_extended (bytemode, sizeflag, 1);
-}
-
-/* SSE5 instructions that have 4 arguments are encoded as:
-   0f 24 <sub-opcode> <modrm> <optional-sib> <drex> <offset>.
-
-   The <sub-opcode> byte has 1 bit (0x4) that is combined with 1 bit in
-   the DREX field (0x8) to determine how the arguments are laid out.  
-   The destination register must be the same register as one of the 
-   inputs, and it is encoded in the DREX byte.  No REX prefix is used 
-   for these instructions, since the DREX field contains the 3 extension
-   bits provided by the REX prefix.
-
-   The bytemode argument adds 2 extra bits for passing extra information:
-       DREX_OC1        -- Set the OC1 bit to indicate dest == 1st arg
-       DREX_NO_OC0     -- OC0 in DREX is invalid 
-       (but pretend it is set).  */
-
-static void
-OP_DREX4 (int flag_bytemode, int sizeflag)
-{
-  unsigned int drex_byte;
-  unsigned int regs[4];
-  unsigned int modrm_regmem;
-  unsigned int modrm_reg;
-  unsigned int drex_reg;
-  int bytemode;
-  int rex_save = rex;
-  int rex_used_save = rex_used;
-  int has_sib = 0;
-  int oc1 = (flag_bytemode & DREX_OC1) ? 2 : 0;
-  int oc0;
-  int i;
-
-  bytemode = flag_bytemode & ~ DREX_MASK;
-
-  for (i = 0; i < 4; i++)
-    regs[i] = DREX_REG_UNKNOWN;
-
-  /* Determine if we have a SIB byte in addition to MODRM before the 
-     DREX byte.  */
-  if (((sizeflag & AFLAG) || address_mode == mode_64bit)
-      && (modrm.mod != 3)
-      && (modrm.rm == 4))
-    has_sib = 1;
-
-  /* Get the DREX byte.  */
-  FETCH_DATA (the_info, codep + 2 + has_sib);
-  drex_byte = codep[has_sib+1];
-  drex_reg = DREX_XMM (drex_byte);
-  modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0);
-
-  /* Is OC0 legal?  If not, hardwire oc0 == 1.  */
-  if (flag_bytemode & DREX_NO_OC0)
-    {
-      oc0 = 1;
-      if (DREX_OC0 (drex_byte))
-       BadOp ();
-    }
-  else
-    oc0 = DREX_OC0 (drex_byte);
-
-  if (modrm.mod == 3)
-    {                  
-      /* regmem == register  */
-      modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0);
-      rex = rex_used = 0;
-      /* skip modrm/drex since we don't call OP_E_extended  */
-      codep += 2;
-    }
-  else
-    {                  
-      /* regmem == memory, fill in appropriate REX bits  */
-      modrm_regmem = DREX_REG_MEMORY;
-      rex = drex_byte & (REX_B | REX_X | REX_R);
-      if (rex)
-       rex |= REX_OPCODE;
-      rex_used = rex;
-    }
-  
-  /* Based on the OC1/OC0 bits, lay out the arguments in the correct 
-     order.  */
-  switch (oc0 + oc1)
-    {
-    default:
-      BadOp ();
-      return;
-
-    case 0:
-      regs[0] = modrm_regmem;
-      regs[1] = modrm_reg;
-      regs[2] = drex_reg;
-      regs[3] = drex_reg;
-      break;
-
-    case 1:
-      regs[0] = modrm_reg;
-      regs[1] = modrm_regmem;
-      regs[2] = drex_reg;
-      regs[3] = drex_reg;
-      break;
-
-    case 2:
-      regs[0] = drex_reg;
-      regs[1] = modrm_regmem;
-      regs[2] = modrm_reg;
-      regs[3] = drex_reg;
-      break;
-
-    case 3:
-      regs[0] = drex_reg;
-      regs[1] = modrm_reg;
-      regs[2] = modrm_regmem;
-      regs[3] = drex_reg;
-      break;
-    }
-
-  /* Print out the arguments.  */
-  for (i = 0; i < 4; i++)
-    {
-      int j = (intel_syntax) ? 3 - i : i;
-      if (i > 0)
-       {
-         *obufp++ = ',';
-         *obufp = '\0';
-       }
-
-      print_drex_arg (regs[j], bytemode, sizeflag);
-    }
-
-  rex = rex_save;
-  rex_used = rex_used_save;
-}
-
-/* SSE5 instructions that have 3 arguments, and are encoded as:
-   0f 24 <sub-opcode> <modrm> <optional-sib> <drex> <offset>   (or)
-   0f 25 <sub-opcode> <modrm> <optional-sib> <drex> <offset> <cmp-byte>
-
-   The DREX field has 1 bit (0x8) to determine how the arguments are 
-   laid out. The destination register is encoded in the DREX byte.  
-   No REX prefix is used for these instructions, since the DREX field 
-   contains the 3 extension bits provided by the REX prefix.  */
-
-static void
-OP_DREX3 (int flag_bytemode, int sizeflag)
-{
-  unsigned int drex_byte;
-  unsigned int regs[3];
-  unsigned int modrm_regmem;
-  unsigned int modrm_reg;
-  unsigned int drex_reg;
-  int bytemode;
-  int rex_save = rex;
-  int rex_used_save = rex_used;
-  int has_sib = 0;
-  int oc0;
-  int i;
-
-  bytemode = flag_bytemode & ~ DREX_MASK;
-
-  for (i = 0; i < 3; i++)
-    regs[i] = DREX_REG_UNKNOWN;
-
-  /* Determine if we have a SIB byte in addition to MODRM before the 
-     DREX byte.  */
-  if (((sizeflag & AFLAG) || address_mode == mode_64bit)
-      && (modrm.mod != 3)
-      && (modrm.rm == 4))
-    has_sib = 1;
-
-  /* Get the DREX byte.  */
-  FETCH_DATA (the_info, codep + 2 + has_sib);
-  drex_byte = codep[has_sib+1];
-  drex_reg = DREX_XMM (drex_byte);
-  modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0);
-
-  /* Is OC0 legal?  If not, hardwire oc0 == 0 */
-  oc0 = DREX_OC0 (drex_byte);
-  if ((flag_bytemode & DREX_NO_OC0) && oc0)
-    BadOp ();
-
-  if (modrm.mod == 3)
-    {                  
-      /* regmem == register */
-      modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0);
-      rex = rex_used = 0;
-      /* skip modrm/drex since we don't call OP_E_extended.  */
-      codep += 2;
-    }
-  else
-    {                  
-      /* regmem == memory, fill in appropriate REX bits.  */
-      modrm_regmem = DREX_REG_MEMORY;
-      rex = drex_byte & (REX_B | REX_X | REX_R);
-      if (rex)
-       rex |= REX_OPCODE;
-      rex_used = rex;
-    }
-
-  /* Based on the OC1/OC0 bits, lay out the arguments in the correct 
-     order.  */
-  switch (oc0)
-    {
-    default:
-      BadOp ();
-      return;
-
-    case 0:
-      regs[0] = modrm_regmem;
-      regs[1] = modrm_reg;
-      regs[2] = drex_reg;
-      break;
-
-    case 1:
-      regs[0] = modrm_reg;
-      regs[1] = modrm_regmem;
-      regs[2] = drex_reg;
-      break;
-    }
-
-  /* Print out the arguments.  */
-  for (i = 0; i < 3; i++)
-    {
-      int j = (intel_syntax) ? 2 - i : i;
-      if (i > 0)
-       {
-         *obufp++ = ',';
-         *obufp = '\0';
-       }
-
-      print_drex_arg (regs[j], bytemode, sizeflag);
-    }
-
-  rex = rex_save;
-  rex_used = rex_used_save;
-}
-
-/* Emit a floating point comparison for comp<xx> instructions.  */
-
-static void
-OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED, 
-             int sizeflag ATTRIBUTE_UNUSED)
-{
-  unsigned char byte;
-
-  static const char *const cmp_test[] = {
-    "eq",
-    "lt",
-    "le",
-    "unord",
-    "ne",
-    "nlt",
-    "nle",
-    "ord",
-    "ueq",
-    "ult",
-    "ule",
-    "false",
-    "une",
-    "unlt",
-    "unle",
-    "true"
-  };
-
-  FETCH_DATA (the_info, codep + 1);
-  byte = *codep & 0xff;
-
-  if (byte >= ARRAY_SIZE (cmp_test)
-      || obuf[0] != 'c'
-      || obuf[1] != 'o'
-      || obuf[2] != 'm')
-    {
-      /* The instruction isn't one we know about, so just append the 
-        extension byte as a numeric value.  */
-      OP_I (b_mode, 0);
-    }
-
-  else
-    {
-      sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3);
-      mnemonicendp = stpcpy (obuf, scratchbuf);
-      codep++;
-    }
-}
-
-/* Emit an integer point comparison for pcom<xx> instructions, 
-   rewriting the instruction to have the test inside of it.  */
-
-static void
-OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED, 
-             int sizeflag ATTRIBUTE_UNUSED)
-{
-  unsigned char byte;
-
-  static const char *const cmp_test[] = {
-    "lt",
-    "le",
-    "gt",
-    "ge",
-    "eq",
-    "ne",
-    "false",
-    "true"
-  };
-
-  FETCH_DATA (the_info, codep + 1);
-  byte = *codep & 0xff;
-
-  if (byte >= ARRAY_SIZE (cmp_test)
-      || obuf[0] != 'p'
-      || obuf[1] != 'c'
-      || obuf[2] != 'o'
-      || obuf[3] != 'm')
-    {
-      /* The instruction isn't one we know about, so just print the 
-        comparison test byte as a numeric value.  */
-      OP_I (b_mode, 0);
-    }
-
-  else
-    {
-      sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4);
-      mnemonicendp = stpcpy (obuf, scratchbuf);
-      codep++;
-    }
-}
-
 /* Display the destination register operand for instructions with
    VEX. */
 
@@ -13533,7 +12574,7 @@ OP_EX_VexReg (int bytemode, int sizeflag, int reg)
 {
   if (reg == -1 && modrm.mod != 3)
     {
-      OP_E_memory (bytemode, sizeflag, 0);
+      OP_E_memory (bytemode, sizeflag);
       return;
     }
   else
@@ -13563,28 +12604,6 @@ OP_EX_VexReg (int bytemode, int sizeflag, int reg)
   oappend (scratchbuf + intel_syntax);
 }
 
-static void
-OP_EX_VexImmW (int bytemode, int sizeflag)
-{
-  int reg = -1;
-  static unsigned char vex_imm8;
-
-  if (!vex_w_done)
-    {
-      vex_imm8 = get_vex_imm8 (sizeflag);
-      if (vex.w)
-       reg = vex_imm8 >> 4;
-      vex_w_done = 1;
-    }
-  else
-    {
-      if (!vex.w)
-       reg = vex_imm8 >> 4;
-    }
-
-  OP_EX_VexReg (bytemode, sizeflag, reg);
-}
-
 static void
 OP_EX_VexW (int bytemode, int sizeflag)
 {
@@ -13847,43 +12866,6 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
     }
 }
 
-static const struct op vpermil2_op[] =
-{
-  { STRING_COMMA_LEN ("td") },
-  { STRING_COMMA_LEN ("td") },
-  { STRING_COMMA_LEN ("mo") },
-  { STRING_COMMA_LEN ("mz") }
-};
-
-static void
-VPERMIL2_Fixup (int bytemode ATTRIBUTE_UNUSED,
-               int sizeflag ATTRIBUTE_UNUSED)
-{
-  unsigned int vpermil2_type;
-
-  FETCH_DATA (the_info, codep + 1);
-  vpermil2_type = *codep++ & 0xf;
-  if (vpermil2_type < ARRAY_SIZE (vpermil2_op))
-    {
-      char suffix [4];
-      char *p = mnemonicendp - 3;
-      suffix[0] = p[0];
-      suffix[1] = p[1];
-      suffix[2] = p[2];
-      suffix[3] = '\0';
-      sprintf (p, "%s%s", vpermil2_op[vpermil2_type].name, suffix);
-      mnemonicendp += vpermil2_op[vpermil2_type].len;
-    }
-  else
-    {
-      /* We have a reserved extension byte.  Output it directly.  */
-      scratchbuf[0] = '$';
-      print_operand_value (scratchbuf + 1, 1, vpermil2_type);
-      oappend (scratchbuf + intel_syntax);
-      scratchbuf[0] = '\0';
-    }
-}
-
 static void
 MOVBE_Fixup (int bytemode, int sizeflag)
 {
This page took 0.055293 seconds and 4 git commands to generate.