* doc/binutils.texi (c++filt): Remove spurious description of
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 58e36d99c5eb32630782c22c7b77dd57464e2482..e6b80497d4d1a0fd09eadaf35c440947bc78f59d 100644 (file)
@@ -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);
@@ -93,10 +93,14 @@ static void OP_MS (int, int);
 static void OP_XS (int, int);
 static void OP_M (int, int);
 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_XMM_Vex (int, int);
+static void OP_XMM_VexW (int, int);
 static void OP_REG_VexI4 (int, int);
 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 OP_0f07 (int, int);
@@ -111,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 {
@@ -163,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;
@@ -376,11 +362,18 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Vex { OP_VEX, vex_mode }
 #define Vex128 { OP_VEX, vex128_mode }
 #define Vex256 { OP_VEX, vex256_mode }
+#define VexI4 { VEXI4_Fixup, 0}
+#define VexFMA { OP_VEX_FMA, vex_mode }
+#define Vex128FMA { OP_VEX_FMA, vex128_mode }
 #define EXdVex { OP_EX_Vex, d_mode }
 #define EXdVexS { OP_EX_Vex, d_swap_mode }
 #define EXqVex { OP_EX_Vex, q_mode }
 #define EXqVexS { OP_EX_Vex, q_swap_mode }
+#define EXVexW { OP_EX_VexW, x_mode }
+#define EXdVexW { OP_EX_VexW, d_mode }
+#define EXqVexW { OP_EX_VexW, q_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 }
@@ -514,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)
@@ -1003,14 +987,35 @@ 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_3A4A                (PREFIX_VEX_3A42 + 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_3A60                (PREFIX_VEX_3A4C + 1)
+#define PREFIX_VEX_3A5C                (PREFIX_VEX_3A4C + 1)
+#define PREFIX_VEX_3A5D                (PREFIX_VEX_3A5C + 1)
+#define PREFIX_VEX_3A5E                (PREFIX_VEX_3A5D + 1)
+#define PREFIX_VEX_3A5F                (PREFIX_VEX_3A5E + 1)
+#define PREFIX_VEX_3A60                (PREFIX_VEX_3A5F + 1)
 #define PREFIX_VEX_3A61                (PREFIX_VEX_3A60 + 1)
 #define PREFIX_VEX_3A62                (PREFIX_VEX_3A61 + 1)
 #define PREFIX_VEX_3A63                (PREFIX_VEX_3A62 + 1)
-#define PREFIX_VEX_3ADF                (PREFIX_VEX_3A63 + 1)
+#define PREFIX_VEX_3A68                (PREFIX_VEX_3A63 + 1)
+#define PREFIX_VEX_3A69                (PREFIX_VEX_3A68 + 1)
+#define PREFIX_VEX_3A6A                (PREFIX_VEX_3A69 + 1)
+#define PREFIX_VEX_3A6B                (PREFIX_VEX_3A6A + 1)
+#define PREFIX_VEX_3A6C                (PREFIX_VEX_3A6B + 1)
+#define PREFIX_VEX_3A6D                (PREFIX_VEX_3A6C + 1)
+#define PREFIX_VEX_3A6E                (PREFIX_VEX_3A6D + 1)
+#define PREFIX_VEX_3A6F                (PREFIX_VEX_3A6E + 1)
+#define PREFIX_VEX_3A78                (PREFIX_VEX_3A6F + 1)
+#define PREFIX_VEX_3A79                (PREFIX_VEX_3A78 + 1)
+#define PREFIX_VEX_3A7A                (PREFIX_VEX_3A79 + 1)
+#define PREFIX_VEX_3A7B                (PREFIX_VEX_3A7A + 1)
+#define PREFIX_VEX_3A7C                (PREFIX_VEX_3A7B + 1)
+#define PREFIX_VEX_3A7D                (PREFIX_VEX_3A7C + 1)
+#define PREFIX_VEX_3A7E                (PREFIX_VEX_3A7D + 1)
+#define PREFIX_VEX_3A7F                (PREFIX_VEX_3A7E + 1)
+#define PREFIX_VEX_3ADF                (PREFIX_VEX_3A7F + 1)
 
 #define X86_64_06              0
 #define X86_64_07              (X86_64_06 + 1)
@@ -1041,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)
@@ -1066,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)
@@ -1153,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)
@@ -1241,12 +1241,21 @@ 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)
 #define VEX_LEN_3A63_P_2       (VEX_LEN_3A62_P_2 + 1)
-#define VEX_LEN_3ADF_P_2       (VEX_LEN_3A63_P_2 + 1)
+#define VEX_LEN_3A6A_P_2       (VEX_LEN_3A63_P_2 + 1)
+#define VEX_LEN_3A6B_P_2       (VEX_LEN_3A6A_P_2 + 1)
+#define VEX_LEN_3A6E_P_2       (VEX_LEN_3A6B_P_2 + 1)
+#define VEX_LEN_3A6F_P_2       (VEX_LEN_3A6E_P_2 + 1)
+#define VEX_LEN_3A7A_P_2       (VEX_LEN_3A6F_P_2 + 1)
+#define VEX_LEN_3A7B_P_2       (VEX_LEN_3A7A_P_2 + 1)
+#define VEX_LEN_3A7E_P_2       (VEX_LEN_3A7B_P_2 + 1)
+#define VEX_LEN_3A7F_P_2       (VEX_LEN_3A7E_P_2 + 1)
+#define VEX_LEN_3ADF_P_2       (VEX_LEN_3A7F_P_2 + 1)
 
 typedef void (*op_rtn) (int bytemode, int sizeflag);
 
@@ -1312,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) },
@@ -1321,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) },
@@ -1330,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) },
@@ -1339,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) },
@@ -1348,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 */
@@ -1357,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 */
@@ -1366,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 */
@@ -1375,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 */
@@ -1642,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 */
@@ -1739,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) },
@@ -5026,6 +5035,14 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
+  /* PREFIX_VEX_3A44 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A44_P_2) },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_VEX_3A4A */
   {
     { "(bad)", { XX } },
@@ -5050,6 +5067,38 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
+  /* PREFIX_VEX_3A5C */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A5D */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A5E */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A5F */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_VEX_3A60 */
   {
     { "(bad)", { XX } },
@@ -5082,6 +5131,134 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
+  /* PREFIX_VEX_3A68 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A69 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6A */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A6A_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6B */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A6B_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6C */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6D */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6E */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A6E_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A6F */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A6F_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A78 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A79 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7A */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A7A_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7B */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A7B_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7C */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7D */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vfnmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7E */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A7E_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A7F */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A7F_P_2) },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_VEX_3ADF */
   {
     { "(bad)", { XX } },
@@ -5262,94 +5439,95 @@ 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 } } },
+    { "psignb",                { MX, EM } },
+    { "psignw",                { MX, EM } },
+    { "psignd",                { MX, EM } },
+    { "pmulhrsw",      { MX, EM } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 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 */
+    { 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 } },
-    /* 30 */
+    { "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 } },
-    /* 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 } },
@@ -5409,14 +5587,14 @@ static const struct dis386 three_byte_table[][256] = {
     { "(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 } },
-    { "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 } },
@@ -5424,17 +5602,17 @@ static const struct dis386 three_byte_table[][256] = {
     { "(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 } } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 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 } } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 98 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -5442,8 +5620,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(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 } } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* a0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -5451,7 +5629,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "pmadcsswd",     { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
+    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* a8 */
     { "(bad)",         { XX } },
@@ -5469,7 +5647,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "pmadcswd",      { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } },
+    { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* b8 */
     { "(bad)",         { XX } },
@@ -5511,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 } },
-    { "(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 } },
@@ -5535,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 } },
@@ -5553,7 +5731,7 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
   },
-  /* THREE_BYTE_0F25 */
+  /* THREE_BYTE_0F3A */
   {
     /* 00 */
     { "(bad)",         { XX } },
@@ -5565,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 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(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 } },
@@ -5592,23 +5770,23 @@ static const struct dis386 three_byte_table[][256] = {
     { "(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 } },
-    /* 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 } },
@@ -5628,919 +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 } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 48 */
     { "(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 */
-    { "(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 */
-    { PREFIX_TABLE (PREFIX_0F3A60) },
-    { PREFIX_TABLE (PREFIX_0F3A61) },
-    { PREFIX_TABLE (PREFIX_0F3A62) },
-    { PREFIX_TABLE (PREFIX_0F3A63) },
-    { "(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 } },
-    { "(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 } },
-    { PREFIX_TABLE (PREFIX_0F3ADF) },
-    /* 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_0F7A */
-  {
-    /* 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 */
-    { "frczps",                { XM, EXq } },
-    { "frczpd",                { XM, EXq } },
-    { "frczss",                { XM, EXq } },
-    { "frczsd",                { XM, EXq } },
-    { "(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 */
-    { "ptest",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(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 */
-    { "cvtph2ps",      { XM, EXd } },
-    { "cvtps2ph",      { EXd, XM } },
-    { "(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 } },
-    { "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 } },
-    { "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 } },
@@ -6679,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 } },
@@ -6717,7 +6022,8 @@ static const struct dis386 three_byte_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
   },
-  /* THREE_BYTE_0F7B */
+
+  /* THREE_BYTE_0F7A */
   {
     /* 00 */
     { "(bad)",         { XX } },
@@ -6756,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 } },
@@ -6792,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 } },
@@ -7010,6 +6316,7 @@ static const struct dis386 three_byte_table[][256] = {
   },
 };
 
+
 static const struct dis386 vex_table[][256] = {
   /* VEX_0F */
   {
@@ -7672,7 +6979,7 @@ 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 } },
@@ -7699,10 +7006,10 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_3A5C) },
+    { PREFIX_TABLE (PREFIX_VEX_3A5D) },
+    { PREFIX_TABLE (PREFIX_VEX_3A5E) },
+    { PREFIX_TABLE (PREFIX_VEX_3A5F) },
     /* 60 */
     { PREFIX_TABLE (PREFIX_VEX_3A60) },
     { PREFIX_TABLE (PREFIX_VEX_3A61) },
@@ -7712,25 +7019,16 @@ static const struct dis386 vex_table[][256] = {
     { "(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 */
+    /* 68 */
+    { PREFIX_TABLE (PREFIX_VEX_3A68) },
+    { PREFIX_TABLE (PREFIX_VEX_3A69) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6A) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6B) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6C) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6D) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6E) },
+    { PREFIX_TABLE (PREFIX_VEX_3A6F) },
+    /* 70 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7739,6 +7037,15 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* 78 */
+    { PREFIX_TABLE (PREFIX_VEX_3A78) },
+    { PREFIX_TABLE (PREFIX_VEX_3A79) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7A) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7B) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7C) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7D) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7E) },
+    { PREFIX_TABLE (PREFIX_VEX_3A7F) },
     /* 80 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7971,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 } },
@@ -8331,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 } },
@@ -8493,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 } },
@@ -9021,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 } },
@@ -9051,6 +8352,54 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
+  /* VEX_LEN_3A6A_P_2 */
+  {
+    { "vfmaddss",      { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A6B_P_2 */
+  {
+    { "vfmaddsd",      { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A6E_P_2 */
+  {
+    { "vfmsubss",      { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A6F_P_2 */
+  {
+    { "vfmsubsd",      { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A7A_P_2 */
+  {
+    { "vfnmaddss",     { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A7B_P_2 */
+  {
+    { "vfnmaddsd",     { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A7E_P_2 */
+  {
+    { "vfnmsubss",     { XMVexW, Vex128FMA, EXdVexW, EXdVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_3A7F_P_2 */
+  {
+    { "vfnmsubsd",     { XMVexW, Vex128FMA, EXqVexW, EXqVexW, VexI4 } },
+    { "(bad)",         { XX } },
+  },
+
   /* VEX_LEN_3ADF_P_2 */
   {
     { "vaeskeygenassist", { XM, EXx, Ib } },
@@ -9151,7 +8500,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_0F24 */
-    { THREE_BYTE_TABLE (THREE_BYTE_0F24) },
+    { "(bad)",         { XX } },    
     { "movL",          { Rd, Td } },
   },
   {
@@ -9356,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 } },
   },
   {
@@ -9431,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 } },
   },
   {
@@ -10042,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)
@@ -10067,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;
@@ -10181,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;
@@ -10250,6 +9608,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
     }
 
   op = 0;
+
   if (*codep == 0x0f)
     {
       unsigned char threebyte;
@@ -10731,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 */
@@ -10825,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;
@@ -10839,7 +10198,7 @@ putop (const char *template, int sizeflag)
   else                                 \
     abort ();
 
-  for (p = template; *p; p++)
+  for (p = in_template; *p; p++)
     {
       switch (*p)
        {
@@ -11606,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;
@@ -11649,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:
@@ -11756,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';
@@ -11866,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;
@@ -11875,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);
 }
 
 
@@ -12674,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;
@@ -12691,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)
@@ -13098,358 +12452,185 @@ 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).  */
+/* Display the destination register operand for instructions with
+   VEX. */
 
 static void
-OP_DREX4 (int flag_bytemode, int sizeflag)
+OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
-  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);
+  if (!need_vex)
+    abort ();
 
-  /* 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 (!need_vex_reg)
+    return;
 
-  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)
+  switch (vex.length)
     {
-    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 128:
+      switch (bytemode)
+       {
+       case vex_mode:
+       case vex128_mode:
+         break;
+       default:
+         abort ();
+         return;
+       }
 
-    case 3:
-      regs[0] = drex_reg;
-      regs[1] = modrm_reg;
-      regs[2] = modrm_regmem;
-      regs[3] = drex_reg;
+      sprintf (scratchbuf, "%%xmm%d", vex.register_specifier);
       break;
-    }
-
-  /* Print out the arguments.  */
-  for (i = 0; i < 4; i++)
-    {
-      int j = (intel_syntax) ? 3 - i : i;
-      if (i > 0)
+    case 256:
+      switch (bytemode)
        {
-         *obufp++ = ',';
-         *obufp = '\0';
+       case vex_mode:
+       case vex256_mode:
+         break;
+       default:
+         abort ();
+         return;
        }
 
-      print_drex_arg (regs[j], bytemode, sizeflag);
+      sprintf (scratchbuf, "%%ymm%d", vex.register_specifier);
+      break;
+    default:
+      abort ();
+      break;
     }
-
-  rex = rex_save;
-  rex_used = rex_used_save;
+  oappend (scratchbuf + intel_syntax);
 }
 
-/* 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.  */
+/* Get the VEX immediate byte without moving codep.  */
 
-static void
-OP_DREX3 (int flag_bytemode, int sizeflag)
+static unsigned char
+get_vex_imm8 (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;
+  int bytes_before_imm = 0;
 
-  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;
-    }
+  /* Skip mod/rm byte.   */
+  MODRM_CHECK;
+  codep++;
 
-  /* Based on the OC1/OC0 bits, lay out the arguments in the correct 
-     order.  */
-  switch (oc0)
+  if (modrm.mod != 3)
     {
-    default:
-      BadOp ();
-      return;
-
-    case 0:
-      regs[0] = modrm_regmem;
-      regs[1] = modrm_reg;
-      regs[2] = drex_reg;
-      break;
+      /* There are SIB/displacement bytes.  */
+      if ((sizeflag & AFLAG) || address_mode == mode_64bit)
+       {
+         /* 32/64 bit address mode */
+         int base = modrm.rm;
 
-    case 1:
-      regs[0] = modrm_reg;
-      regs[1] = modrm_regmem;
-      regs[2] = drex_reg;
-      break;
-    }
+         /* Check SIB byte.  */
+         if (base == 4)
+           {
+             FETCH_DATA (the_info, codep + 1);
+             base = *codep & 7;
+             bytes_before_imm++;
+           }
 
-  /* Print out the arguments.  */
-  for (i = 0; i < 3; i++)
-    {
-      int j = (intel_syntax) ? 2 - i : i;
-      if (i > 0)
-       {
-         *obufp++ = ',';
-         *obufp = '\0';
+         switch (modrm.mod)
+           {
+           case 0:
+             /* When modrm.rm == 5 or modrm.rm == 4 and base in
+                SIB == 5, there is a 4 byte displacement.  */
+             if (base != 5)
+               /* No displacement. */
+               break;
+           case 2:
+             /* 4 byte displacement.  */
+             bytes_before_imm += 4;
+             break;
+           case 1:
+             /* 1 byte displacement.  */
+             bytes_before_imm++;
+             break;
+           }
+       }
+      else
+       { /* 16 bit address mode */
+         switch (modrm.mod)
+           {
+           case 0:
+             /* When modrm.rm == 6, there is a 2 byte displacement.  */
+             if (modrm.rm != 6)
+               /* No displacement. */
+               break;
+           case 2:
+             /* 2 byte displacement.  */
+             bytes_before_imm += 2;
+             break;
+           case 1:
+             /* 1 byte displacement.  */
+             bytes_before_imm++;
+             break;
+           }
        }
-
-      print_drex_arg (regs[j], bytemode, sizeflag);
     }
 
-  rex = rex_save;
-  rex_used = rex_used_save;
+  FETCH_DATA (the_info, codep + bytes_before_imm + 1);
+  return codep [bytes_before_imm];
 }
 
-/* Emit a floating point comparison for comp<xx> instructions.  */
-
 static void
-OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED, 
-             int sizeflag ATTRIBUTE_UNUSED)
+OP_EX_VexReg (int bytemode, int sizeflag, int reg)
 {
-  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')
+  if (reg == -1 && modrm.mod != 3)
     {
-      /* The instruction isn't one we know about, so just append the 
-        extension byte as a numeric value.  */
-      OP_I (b_mode, 0);
+      OP_E_memory (bytemode, sizeflag);
+      return;
     }
-
   else
     {
-      sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3);
-      mnemonicendp = stpcpy (obuf, scratchbuf);
-      codep++;
+      if (reg == -1)
+       {
+         reg = modrm.rm;
+         USED_REX (REX_B);
+         if (rex & REX_B)
+           reg += 8;
+       }
+      else if (reg > 7 && address_mode != mode_64bit)
+       BadOp ();
     }
-}
 
-/* Emit an integer point comparison for pcom<xx> instructions, 
-   rewriting the instruction to have the test inside of it.  */
+  switch (vex.length)
+    {
+    case 128:
+      sprintf (scratchbuf, "%%xmm%d", reg);
+      break;
+    case 256:
+      sprintf (scratchbuf, "%%ymm%d", reg);
+      break;
+    default:
+      abort ();
+    }
+  oappend (scratchbuf + intel_syntax);
+}
 
 static void
-OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED, 
-             int sizeflag ATTRIBUTE_UNUSED)
+OP_EX_VexW (int bytemode, int sizeflag)
 {
-  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;
+  int reg = -1;
 
-  if (byte >= ARRAY_SIZE (cmp_test)
-      || obuf[0] != 'p'
-      || obuf[1] != 'c'
-      || obuf[2] != 'o'
-      || obuf[3] != 'm')
+  if (!vex_w_done)
     {
-      /* The instruction isn't one we know about, so just print the 
-        comparison test byte as a numeric value.  */
-      OP_I (b_mode, 0);
+      vex_w_done = 1;
+      if (vex.w)
+       reg = vex.register_specifier;
     }
-
   else
     {
-      sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4);
-      mnemonicendp = stpcpy (obuf, scratchbuf);
-      codep++;
+      if (!vex.w)
+       reg = vex.register_specifier;
     }
-}
 
-/* Display the destination register operand for instructions with
-   VEX. */
+  OP_EX_VexReg (bytemode, sizeflag, reg);
+}
 
 static void
-OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
+OP_VEX_FMA (int bytemode, int sizeflag)
 {
-  if (!need_vex)
-    abort ();
+  int reg = get_vex_imm8 (sizeflag) >> 4;
 
-  if (!need_vex_reg)
-    return;
+  if (reg > 7 && address_mode != mode_64bit)
+    BadOp ();
 
   switch (vex.length)
     {
@@ -13464,28 +12645,36 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
          return;
        }
 
-      sprintf (scratchbuf, "%%xmm%d", vex.register_specifier);
+      sprintf (scratchbuf, "%%xmm%d", reg);
       break;
     case 256:
       switch (bytemode)
        {
        case vex_mode:
-       case vex256_mode:
          break;
        default:
          abort ();
          return;
        }
 
-      sprintf (scratchbuf, "%%ymm%d", vex.register_specifier);
+      sprintf (scratchbuf, "%%ymm%d", reg);
       break;
     default:
       abort ();
-      break;
     }
   oappend (scratchbuf + intel_syntax);
 }
 
+static void
+VEXI4_Fixup (int bytemode ATTRIBUTE_UNUSED,
+            int sizeflag ATTRIBUTE_UNUSED)
+{
+  /* Skip the immediate byte and check for invalid bits.  */
+  FETCH_DATA (the_info, codep + 1);
+  if (*codep++ & 0xf)
+    BadOp ();
+}
+
 static void
 OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
@@ -13517,6 +12706,15 @@ OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
   oappend (scratchbuf + intel_syntax);
 }
 
+static void
+OP_XMM_VexW (int bytemode, int sizeflag)
+{
+  /* Turn off the REX.W bit since it is used for swapping operands
+     now.  */
+  rex &= ~REX_W;
+  OP_XMM (bytemode, sizeflag);
+}
+
 static void
 OP_EX_Vex (int bytemode, int sizeflag)
 {
This page took 0.055508 seconds and 4 git commands to generate.