gas/
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
index 087c449f4808e15a3a97f53b89be60ed25a657c3..83de1f72536647dc4ab517e9954dcd3a49ad4bc6 100644 (file)
@@ -1,6 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
@@ -92,18 +93,12 @@ 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_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);
 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);
@@ -121,6 +116,7 @@ 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 {
   /* Points to first byte not fetched.  */
@@ -238,7 +234,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define XX { NULL, 0 }
 
 #define Eb { OP_E, b_mode }
+#define EbS { OP_E, b_swap_mode }
 #define Ev { OP_E, v_mode }
+#define EvS { OP_E, v_swap_mode }
 #define Ed { OP_E, d_mode }
 #define Edq { OP_E, dq_mode }
 #define Edqw { OP_E, dqw_mode }
@@ -254,6 +252,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Ma { OP_M, a_mode }
 #define Mb { OP_M, b_mode }
 #define Md { OP_M, d_mode }
+#define Mo { OP_M, o_mode }
 #define Mp { OP_M, f_mode }            /* 32 or 48 bit memory operand for LDS, LES etc */
 #define Mq { OP_M, q_mode }
 #define Mx { OP_M, x_mode }
@@ -352,15 +351,20 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define XM { OP_XMM, 0 }
 #define XMM { OP_XMM, xmm_mode }
 #define EM { OP_EM, v_mode }
+#define EMS { OP_EM, v_swap_mode }
 #define EMd { OP_EM, d_mode }
 #define EMx { OP_EM, x_mode }
 #define EXw { OP_EX, w_mode }
 #define EXd { OP_EX, d_mode }
+#define EXdS { OP_EX, d_swap_mode }
 #define EXq { OP_EX, q_mode }
+#define EXqS { OP_EX, q_swap_mode }
 #define EXx { OP_EX, x_mode }
+#define EXxS { OP_EX, x_swap_mode }
 #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 }
@@ -372,22 +376,15 @@ 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 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 EXqVexS { OP_EX_Vex, q_swap_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 }
@@ -409,20 +406,30 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 
 /* byte operand */
 #define b_mode                 1
+/* byte operand with operand swapped */
+#define b_swap_mode            (b_mode + 1)
 /* operand size depends on prefixes */
-#define v_mode                 (b_mode + 1)
+#define v_mode                 (b_swap_mode + 1)
+/* operand size depends on prefixes with operand swapped */
+#define v_swap_mode            (v_mode + 1)
 /* word operand */
-#define w_mode                 (v_mode + 1)
+#define w_mode                 (v_swap_mode + 1)
 /* double word operand  */
 #define d_mode                 (w_mode + 1)
+/* double word operand with operand swapped */
+#define d_swap_mode            (d_mode + 1)
 /* quad word operand */
-#define q_mode                 (d_mode + 1)
+#define q_mode                 (d_swap_mode + 1)
+/* quad word operand with operand swapped */
+#define q_swap_mode            (q_mode + 1)
 /* ten-byte operand */
-#define t_mode                 (q_mode + 1)
+#define t_mode                 (q_swap_mode + 1)
 /* 16-byte XMM or 32-byte YMM operand */
 #define x_mode                 (t_mode + 1)
+/* 16-byte XMM or 32-byte YMM operand with operand swapped */
+#define x_swap_mode            (x_mode + 1)
 /* 16-byte XMM operand */
-#define xmm_mode               (x_mode + 1)
+#define xmm_mode               (x_swap_mode + 1)
 /* 16-byte XMM or quad word operand */
 #define xmmq_mode              (xmm_mode + 1)
 /* 32-byte YMM or quad word operand */
@@ -456,8 +463,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)
@@ -745,7 +754,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define PREFIX_0F383F          (PREFIX_0F383E + 1)
 #define PREFIX_0F3840          (PREFIX_0F383F + 1)
 #define PREFIX_0F3841          (PREFIX_0F3840 + 1)
-#define PREFIX_0F38DB          (PREFIX_0F3841 + 1)
+#define PREFIX_0F3880          (PREFIX_0F3841 + 1)
+#define PREFIX_0F3881          (PREFIX_0F3880 + 1)
+#define PREFIX_0F38DB          (PREFIX_0F3881 + 1)
 #define PREFIX_0F38DC          (PREFIX_0F38DB + 1)
 #define PREFIX_0F38DD          (PREFIX_0F38DC + 1)
 #define PREFIX_0F38DE          (PREFIX_0F38DD + 1)
@@ -934,7 +945,42 @@ 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_3A04                (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)
+#define PREFIX_VEX_38DF                (PREFIX_VEX_38DE + 1)
+#define PREFIX_VEX_3A04                (PREFIX_VEX_38DF + 1)
 #define PREFIX_VEX_3A05                (PREFIX_VEX_3A04 + 1)
 #define PREFIX_VEX_3A06                (PREFIX_VEX_3A05 + 1)
 #define PREFIX_VEX_3A08                (PREFIX_VEX_3A06 + 1)
@@ -957,35 +1003,15 @@ 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)
-#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_3A60                (PREFIX_VEX_3A4C + 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_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_3A63 + 1)
 
 #define X86_64_06              0
 #define X86_64_07              (X86_64_06 + 1)
@@ -1041,8 +1067,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)
@@ -1128,8 +1153,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)
@@ -1195,7 +1219,12 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define VEX_LEN_383F_P_2       (VEX_LEN_383E_P_2 + 1)
 #define VEX_LEN_3840_P_2       (VEX_LEN_383F_P_2 + 1)
 #define VEX_LEN_3841_P_2       (VEX_LEN_3840_P_2 + 1)
-#define VEX_LEN_3A06_P_2       (VEX_LEN_3841_P_2 + 1)
+#define VEX_LEN_38DB_P_2       (VEX_LEN_3841_P_2 + 1)
+#define VEX_LEN_38DC_P_2       (VEX_LEN_38DB_P_2 + 1)
+#define VEX_LEN_38DD_P_2       (VEX_LEN_38DC_P_2 + 1)
+#define VEX_LEN_38DE_P_2       (VEX_LEN_38DD_P_2 + 1)
+#define VEX_LEN_38DF_P_2       (VEX_LEN_38DE_P_2 + 1)
+#define VEX_LEN_3A06_P_2       (VEX_LEN_38DF_P_2 + 1)
 #define VEX_LEN_3A0A_P_2       (VEX_LEN_3A06_P_2 + 1)
 #define VEX_LEN_3A0B_P_2       (VEX_LEN_3A0A_P_2 + 1)
 #define VEX_LEN_3A0E_P_2       (VEX_LEN_3A0B_P_2 + 1)
@@ -1211,19 +1240,13 @@ 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_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_3A63_P_2 + 1)
 
 typedef void (*op_rtn) (int bytemode, int sizeflag);
 
@@ -1275,6 +1298,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
 
@@ -1288,8 +1312,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) },
@@ -1297,8 +1321,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) },
@@ -1306,8 +1330,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) },
@@ -1315,8 +1339,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) },
@@ -1324,8 +1348,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 */
@@ -1333,8 +1357,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 */
@@ -1342,8 +1366,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 */
@@ -1351,8 +1375,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 */
@@ -1441,8 +1465,8 @@ static const struct dis386 dis386[] = {
   /* 88 */
   { "movB",            { Eb, Gb } },
   { "movS",            { Ev, Gv } },
-  { "movB",            { Gb, Eb } },
-  { "movS",            { Gv, Ev } },
+  { "movB",            { Gb, EbS } },
+  { "movS",            { Gv, EvS } },
   { "movD",            { Sv, Sw } },
   { MOD_TABLE (MOD_8D) },
   { "movD",            { Sw, Sv } },
@@ -1513,8 +1537,8 @@ static const struct dis386 dis386[] = {
   /* c8 */
   { "enterT",          { Iw, Ib } },
   { "leaveT",          { XX } },
-  { "lretP",           { Iw } },
-  { "lretP",           { XX } },
+  { "Jret{|f}P",       { Iw } },
+  { "Jret{|f}P",       { XX } },
   { "int3",            { XX } },
   { "int",             { Ib } },
   { X86_64_TABLE (X86_64_CE) },
@@ -1623,7 +1647,7 @@ static const struct dis386 dis386_twobyte[] = {
   { "(bad)",           { XX } },
   /* 28 */
   { "movapX",          { XM, EXx } },
-  { "movapX",          { EXx, XM } },
+  { "movapX",          { EXxS, XM } },
   { PREFIX_TABLE (PREFIX_0F2A) },
   { PREFIX_TABLE (PREFIX_0F2B) },
   { PREFIX_TABLE (PREFIX_0F2C) },
@@ -1649,23 +1673,23 @@ static const struct dis386 dis386_twobyte[] = {
   { "(bad)",           { XX } },
   { "(bad)",           { XX } },
   /* 40 */
-  { "cmovo",           { Gv, Ev } },
-  { "cmovno",          { Gv, Ev } },
-  { "cmovb",           { Gv, Ev } },
-  { "cmovae",          { Gv, Ev } },
-  { "cmove",           { Gv, Ev } },
-  { "cmovne",          { Gv, Ev } },
-  { "cmovbe",          { Gv, Ev } },
-  { "cmova",           { Gv, Ev } },
+  { "cmovoS",          { Gv, Ev } },
+  { "cmovnoS",         { Gv, Ev } },
+  { "cmovbS",          { Gv, Ev } },
+  { "cmovaeS",         { Gv, Ev } },
+  { "cmoveS",          { Gv, Ev } },
+  { "cmovneS",         { Gv, Ev } },
+  { "cmovbeS",         { Gv, Ev } },
+  { "cmovaS",          { Gv, Ev } },
   /* 48 */
-  { "cmovs",           { Gv, Ev } },
-  { "cmovns",          { Gv, Ev } },
-  { "cmovp",           { Gv, Ev } },
-  { "cmovnp",          { Gv, Ev } },
-  { "cmovl",           { Gv, Ev } },
-  { "cmovge",          { Gv, Ev } },
-  { "cmovle",          { Gv, Ev } },
-  { "cmovg",           { Gv, Ev } },
+  { "cmovsS",          { Gv, Ev } },
+  { "cmovnsS",         { Gv, Ev } },
+  { "cmovpS",          { Gv, Ev } },
+  { "cmovnpS",         { Gv, Ev } },
+  { "cmovlS",          { Gv, Ev } },
+  { "cmovgeS",         { Gv, Ev } },
+  { "cmovleS",         { Gv, Ev } },
+  { "cmovgS",          { Gv, Ev } },
   /* 50 */
   { MOD_TABLE (MOD_0F51) },
   { PREFIX_TABLE (PREFIX_0F51) },
@@ -1914,6 +1938,7 @@ static const unsigned char twobyte_has_modrm[256] = {
 
 static char obuf[100];
 static char *obufp;
+static char *mnemonicendp;
 static char scratchbuf[100];
 static unsigned char *start_codep;
 static unsigned char *insn_codep;
@@ -1944,6 +1969,12 @@ static unsigned char need_vex;
 static unsigned char need_vex_reg;
 static unsigned char vex_w_done;
 
+struct op
+  {
+    const char *name;
+    unsigned int len;
+  };
+
 /* If we are accessing mod/rm/reg without need_modrm set, then the
    values are stale.  Hitting this abort likely indicates that you
    need to update onebyte_has_modrm or twobyte_has_modrm.  */
@@ -2389,10 +2420,10 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0F11 */
   {
-    { "movups",        { EXx, XM } },
-    { "movss", { EXd, XM } },
-    { "movupd",        { EXx, XM } },
-    { "movsd", { EXq, XM } },
+    { "movups",        { EXxS, XM } },
+    { "movss", { EXdS, XM } },
+    { "movupd",        { EXxS, XM } },
+    { "movsd", { EXqS, XM } },
   },
 
   /* PREFIX_0F12 */
@@ -2661,9 +2692,9 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0F7F */
   {
-    { "movq",  { EM, MX } },
-    { "movdqu",        { EXx, XM } },
-    { "movdqa",        { EXx, XM } },
+    { "movq",  { EMS, MX } },
+    { "movdqu",        { EXxS, XM } },
+    { "movdqa",        { EXxS, XM } },
     { "(bad)", { XX } },
   },
 
@@ -2719,7 +2750,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { "(bad)", { XX } },
     { "movq2dq",{ XM, MS } },
-    { "movq",  { EXq, XM } },
+    { "movq",  { EXqS, XM } },
     { "movdq2q",{ MX, XS } },
   },
 
@@ -3003,6 +3034,22 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
+  /* PREFIX_0F3880 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "invept",        { Gm, Mo } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_0F3881 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "invvpid", { Gm, Mo } },
+    { "(bad)", { XX } },
+  },
+
   /* PREFIX_0F38DB */
   {
     { "(bad)", { XX } },
@@ -3045,17 +3092,17 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_0F38F0 */
   {
+    { "movbeS",        { Gv, { MOVBE_Fixup, v_mode } } },
     { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
+    { "movbeS",        { Gv, { MOVBE_Fixup, v_mode } } },
     { "crc32", { Gdq, { CRC32_Fixup, b_mode } } },     
   },
 
   /* PREFIX_0F38F1 */
   {
+    { "movbeS",        { { MOVBE_Fixup, v_mode }, Gv } },
     { "(bad)", { XX } },
-    { "(bad)", { XX } },
-    { "(bad)", { XX } },
+    { "movbeS",        { { MOVBE_Fixup, v_mode }, Gv } },
     { "crc32", { Gdq, { CRC32_Fixup, v_mode } } },     
   },
 
@@ -3253,9 +3300,9 @@ static const struct dis386 prefix_table[][4] = {
 
   /* PREFIX_VEX_11 */
   {
-    { "vmovups", { EXx, XM } },
+    { "vmovups", { EXxS, XM } },
     { VEX_LEN_TABLE (VEX_LEN_11_P_1) },
-    { "vmovupd", { EXx, XM } },
+    { "vmovupd", { EXxS, XM } },
     { VEX_LEN_TABLE (VEX_LEN_11_P_3) },
   },
 
@@ -3678,8 +3725,8 @@ static const struct dis386 prefix_table[][4] = {
   /* PREFIX_VEX_7F */
   {
     { "(bad)", { XX } },
-    { "vmovdqu", { EXx, XM } },
-    { "vmovdqa", { EXx, XM } },
+    { "vmovdqu", { EXxS, XM } },
+    { "vmovdqa", { EXxS, XM } },
     { "(bad)", { XX } },
   },
 
@@ -4515,419 +4562,539 @@ static const struct dis386 prefix_table[][4] = {
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A04 */
+  /* PREFIX_VEX_3896 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vpermilps", { XM, EXx, Ib } },
+    { "vfmaddsub132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A05 */
+  /* PREFIX_VEX_3897 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vpermilpd", { XM, EXx, Ib } },
+    { "vfmsubadd132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A06 */
+  /* PREFIX_VEX_3898 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A06_P_2) },
+    { "vfmadd132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A08 */
+  /* PREFIX_VEX_3899 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vroundps", { XM, EXx, Ib } },
+    { "vfmadd132s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A09 */
+  /* PREFIX_VEX_389A */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vroundpd", { XM, EXx, Ib } },
+    { "vfmsub132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0A */
+  /* PREFIX_VEX_389B */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A0A_P_2) },
+    { "vfmsub132s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0B */
+  /* PREFIX_VEX_389C */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A0B_P_2) },
+    { "vfnmadd132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0C */
+  /* PREFIX_VEX_389D */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vblendps", { XM, Vex, EXx, Ib } },
+    { "vfnmadd132s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0D */
+  /* PREFIX_VEX_389E */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vblendpd", { XM, Vex, EXx, Ib } },
+    { "vfnmsub132p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0E */
+  /* PREFIX_VEX_389F */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A0E_P_2) },
+    { "vfnmsub132s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A0F */
+  /* PREFIX_VEX_38A6 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A0F_P_2) },
+    { "vfmaddsub213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A14 */
+  /* PREFIX_VEX_38A7 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A14_P_2) },
+    { "vfmsubadd213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A15 */
+  /* PREFIX_VEX_38A8 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A15_P_2) },
+    { "vfmadd213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A16 */
+  /* PREFIX_VEX_38A9 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A16_P_2) },
+    { "vfmadd213s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A17 */
+  /* PREFIX_VEX_38AA */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A17_P_2) },
+    { "vfmsub213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A18 */
+  /* PREFIX_VEX_38AB */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A18_P_2) },
+    { "vfmsub213s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A19 */
+  /* PREFIX_VEX_38AC */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A19_P_2) },
+    { "vfnmadd213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A20 */
+  /* PREFIX_VEX_38AD */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A20_P_2) },
+    { "vfnmadd213s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A21 */
+  /* PREFIX_VEX_38AE */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A21_P_2) },
+    { "vfnmsub213p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A22 */
+  /* PREFIX_VEX_38AF */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A22_P_2) },
+    { "vfnmsub213s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A40 */
+  /* PREFIX_VEX_38B6 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vdpps", { XM, Vex, EXx, Ib } },
+    { "vfmaddsub231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A41 */
+  /* PREFIX_VEX_38B7 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A41_P_2) },
+    { "vfmsubadd231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A42 */
+  /* PREFIX_VEX_38B8 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A42_P_2) },
+    { "vfmadd231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A48 */
+  /* PREFIX_VEX_38B9 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vpermil2ps", { XMVexW, Vex, EXVexImmW, EXVexImmW, VPERMIL2 } },
+    { "vfmadd231s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A49 */
+  /* PREFIX_VEX_38BA */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vpermil2pd", { XMVexW, Vex, EXVexImmW, EXVexImmW, VPERMIL2 } },
+    { "vfmsub231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A4A */
+  /* PREFIX_VEX_38BB */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vblendvps", { XM, Vex, EXx, XMVexI4 } },
+    { "vfmsub231s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A4B */
+  /* PREFIX_VEX_38BC */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vblendvpd", { XM, Vex, EXx, XMVexI4 } },
+    { "vfnmadd231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A4C */
+  /* PREFIX_VEX_38BD */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A4C_P_2) },
+    { "vfnmadd231s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A5C */
+  /* PREFIX_VEX_38BE */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmaddsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "vfnmsub231p%XW", { XM, Vex, EXx } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A5D */
+  /* PREFIX_VEX_38BF */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmaddsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "vfnmsub231s%XW", { XM, Vex, EXVexWdq } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A5E */
+  /* PREFIX_VEX_38DB */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmsubaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_38DB_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A5F */
+  /* PREFIX_VEX_38DC */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmsubaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_38DC_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A60 */
+  /* PREFIX_VEX_38DD */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A60_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_38DD_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A61 */
+  /* PREFIX_VEX_38DE */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A61_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_38DE_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A62 */
+  /* PREFIX_VEX_38DF */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A62_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_38DF_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A63 */
+  /* PREFIX_VEX_3A04 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A63_P_2) },
+    { "vpermilps", { XM, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A05 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vpermilpd", { XM, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A06 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A06_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A08 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vroundps", { XM, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A09 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vroundpd", { XM, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0A */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A0A_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0B */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A0B_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0C */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vblendps", { XM, Vex, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0D */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { "vblendpd", { XM, Vex, EXx, Ib } },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0E */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A0E_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A0F */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A0F_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A14 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A14_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A15 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A15_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A16 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A16_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A17 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A17_P_2) },
+    { "(bad)", { XX } },
+  },
+
+  /* PREFIX_VEX_3A18 */
+  {
+    { "(bad)", { XX } },
+    { "(bad)", { XX } },
+    { VEX_LEN_TABLE (VEX_LEN_3A18_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A68 */
+  /* PREFIX_VEX_3A19 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A19_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A69 */
+  /* PREFIX_VEX_3A20 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A20_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6A */
+  /* PREFIX_VEX_3A21 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A6A_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A21_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6B */
+  /* PREFIX_VEX_3A22 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A6B_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A22_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6C */
+  /* PREFIX_VEX_3A40 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "vdpps", { XM, Vex, EXx, Ib } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6D */
+  /* PREFIX_VEX_3A41 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A41_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6E */
+  /* PREFIX_VEX_3A42 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A6E_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A42_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A6F */
+  /* PREFIX_VEX_3A44 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A6F_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A44_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A78 */
+  /* PREFIX_VEX_3A4A */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfnmaddps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "vblendvps", { XM, Vex, EXx, XMVexI4 } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A79 */
+  /* PREFIX_VEX_3A4B */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfnmaddpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { "vblendvpd", { XM, Vex, EXx, XMVexI4 } },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7A */
+  /* PREFIX_VEX_3A4C */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A7A_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A4C_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7B */
+  /* PREFIX_VEX_3A60 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A7B_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A60_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7C */
+  /* PREFIX_VEX_3A61 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfnmsubps", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A61_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7D */
+  /* PREFIX_VEX_3A62 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { "vfnmsubpd", { XMVexW, VexFMA, EXVexW, EXVexW, VexI4 } },
+    { VEX_LEN_TABLE (VEX_LEN_3A62_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7E */
+  /* PREFIX_VEX_3A63 */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A7E_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3A63_P_2) },
     { "(bad)", { XX } },
   },
 
-  /* PREFIX_VEX_3A7F */
+  /* PREFIX_VEX_3ADF */
   {
     { "(bad)", { XX } },
     { "(bad)", { XX } },
-    { VEX_LEN_TABLE (VEX_LEN_3A7F_P_2) },
+    { VEX_LEN_TABLE (VEX_LEN_3ADF_P_2) },
     { "(bad)", { XX } },
   },
 };
@@ -5832,8 +5999,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 } },
@@ -6901,7 +7068,7 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     /* 28 */
     { "vmovapX",       { XM, EXx } },
-    { "vmovapX",       { EXx, XM } },
+    { "vmovapX",       { EXxS, XM } },
     { PREFIX_TABLE (PREFIX_VEX_2A) },
     { MOD_TABLE (MOD_VEX_2B) },
     { PREFIX_TABLE (PREFIX_VEX_2C) },
@@ -7314,55 +7481,90 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(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 } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
-    /* a0 */
+    { 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 } },
-    /* a8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* c8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* b0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* d0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* b8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
+    /* d8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* c0 */
     { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_38DB) },
+    { PREFIX_TABLE (PREFIX_VEX_38DC) },
+    { PREFIX_TABLE (PREFIX_VEX_38DD) },
+    { PREFIX_TABLE (PREFIX_VEX_38DE) },
+    { PREFIX_TABLE (PREFIX_VEX_38DF) },
+    /* e0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7370,8 +7572,8 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* c8 */
     { "(bad)",         { XX } },
+    /* e8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7379,8 +7581,8 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    /* d0 */
     { "(bad)",         { XX } },
+    /* f0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7388,43 +7590,8 @@ static const struct dis386 vex_table[][256] = {
     { "(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 */
+    /* f8 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7513,13 +7680,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) },
@@ -7540,10 +7707,10 @@ static const struct dis386 vex_table[][256] = {
     { "(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) },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 60 */
     { PREFIX_TABLE (PREFIX_VEX_3A60) },
     { PREFIX_TABLE (PREFIX_VEX_3A61) },
@@ -7554,14 +7721,14 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     /* 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) },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 70 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7572,14 +7739,14 @@ static const struct dis386 vex_table[][256] = {
     { "(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) },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
+    { "(bad)",         { XX } },
     /* 80 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7687,7 +7854,7 @@ static const struct dis386 vex_table[][256] = {
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
-    { "(bad)",         { XX } },
+    { PREFIX_TABLE (PREFIX_VEX_3ADF) },
     /* e0 */
     { "(bad)",         { XX } },
     { "(bad)",         { XX } },
@@ -7742,13 +7909,13 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_11_P_1 */
   {
-    { "vmovss",                { EXdVex, Vex128, XM } },
+    { "vmovss",                { EXdVexS, Vex128, XM } },
     { "(bad)",         { XX } },
   },
 
   /* VEX_LEN_11_P_3 */
   {
-    { "vmovsd",                { EXqVex, Vex128, XM } },
+    { "vmovsd",                { EXqVexS, Vex128, XM } },
     { "(bad)",         { XX } },
   },
 
@@ -7812,12 +7979,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 } },
@@ -8240,7 +8401,7 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_D6_P_2 */
   {
-    { "vmovq",         { EXq, XM } },
+    { "vmovq",         { EXqS, XM } },
     { "(bad)",         { XX } },
   },
 
@@ -8334,12 +8495,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 } },
@@ -8736,6 +8891,36 @@ static const struct dis386 vex_len_table[][2] = {
     { "(bad)",         { XX } },
   },
 
+  /* VEX_LEN_38DB_P_2 */
+  {
+    { "vaesimc",       { XM, EXx } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_38DC_P_2 */
+  {
+    { "vaesenc",       { XM, Vex128, EXx } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_38DD_P_2 */
+  {
+    { "vaesenclast",   { XM, Vex128, EXx } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_38DE_P_2 */
+  {
+    { "vaesdec",       { XM, Vex128, EXx } },
+    { "(bad)",         { XX } },
+  },
+
+  /* VEX_LEN_38DF_P_2 */
+  {
+    { "vaesdeclast",   { XM, Vex128, EXx } },
+    { "(bad)",         { XX } },
+  },
+
   /* VEX_LEN_3A06_P_2 */
   {
     { "(bad)",         { XX } },
@@ -8832,6 +9017,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 } },
@@ -8862,51 +9053,9 @@ 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 */
+  /* VEX_LEN_3ADF_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 } },
+    { "vaeskeygenassist", { XM, EXx, Ib } },
     { "(bad)",         { XX } },
   },
 };
@@ -9209,7 +9358,7 @@ static const struct dis386 mod_table[][2] = {
   },
   {
     /* MOD_VEX_2B */
-    { VEX_LEN_TABLE (VEX_LEN_2B_M_0) },
+    { "vmovntpX",      { Mx, XM } },
     { "(bad)",         { XX } },
   },
   {
@@ -9284,7 +9433,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 } },
   },
   {
@@ -10242,7 +10391,7 @@ print_insn (bfd_vma pc, disassemble_info *info)
   if (prefix_obuf[0] != 0)
     (*info->fprintf_func) (info->stream, "%s", prefix_obuf);
 
-  obufp = obuf + strlen (obuf);
+  obufp = mnemonicendp;
   for (i = strlen (obuf) + strlen (prefix_obuf); i < 6; i++)
     oappend (" ");
   oappend (" ");
@@ -10599,6 +10748,14 @@ static char *fgrps[][8] = {
   },
 };
 
+static void
+swap_operand (void)
+{
+  mnemonicendp[0] = '.';
+  mnemonicendp[1] = 's';
+  mnemonicendp += 2;
+}
+
 static void
 OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED,
               int sizeflag ATTRIBUTE_UNUSED)
@@ -11046,36 +11203,49 @@ case_Q:
                }
            }
          break;
-         /* implicit operand size 'l' for i386 or 'q' for x86-64 */
        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;
     }
   *obufp = 0;
+  mnemonicendp = obufp;
   return 0;
 }
 
 static void
 oappend (const char *s)
 {
-  strcpy (obufp, s);
-  obufp += strlen (s);
+  obufp = stpcpy (obufp, s);
 }
 
 static void
@@ -11214,7 +11384,7 @@ print_displacement (char *buf, bfd_vma disp)
   buf[j++] = '0';
   buf[j++] = 'x';
 
-  sprintf_vma (tmp, val);
+  sprintf_vma (tmp, (bfd_vma) val);
   for (i = 0; tmp[i] == '0'; i++)
     continue;
   if (tmp[i] == '\0')
@@ -11228,6 +11398,7 @@ intel_operand_size (int bytemode, int sizeflag)
   switch (bytemode)
     {
     case b_mode:
+    case b_swap_mode:
     case dqb_mode:
       oappend ("BYTE PTR ");
       break;
@@ -11244,6 +11415,7 @@ intel_operand_size (int bytemode, int sizeflag)
        }
       /* FALLTHRU */
     case v_mode:
+    case v_swap_mode:
     case dq_mode:
       USED_REX (REX_W);
       if (rex & REX_W)
@@ -11269,10 +11441,12 @@ intel_operand_size (int bytemode, int sizeflag)
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     case d_mode:
+    case d_swap_mode:
     case dqd_mode:
       oappend ("DWORD PTR ");
       break;
     case q_mode:
+    case q_swap_mode:
       oappend ("QWORD PTR ");
       break;
     case m_mode:
@@ -11292,6 +11466,7 @@ intel_operand_size (int bytemode, int sizeflag)
       oappend ("TBYTE PTR ");
       break;
     case x_mode:
+    case x_swap_mode:
       if (need_vex)
        {
          switch (vex.length)
@@ -11347,6 +11522,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;
     }
@@ -11362,9 +11546,14 @@ OP_E_register (int bytemode, int sizeflag)
   if ((rex & REX_B))
     reg += 8;
 
+  if ((sizeflag & SUFFIX_ALWAYS)
+      && (bytemode == b_swap_mode || bytemode == v_swap_mode))
+    swap_operand ();
+
   switch (bytemode)
     {
     case b_mode:
+    case b_swap_mode:
       USED_REX (0);
       if (rex)
        names = names8rex;
@@ -11393,6 +11582,7 @@ OP_E_register (int bytemode, int sizeflag)
       bytemode = v_mode;
       /* FALLTHRU */
     case v_mode:
+    case v_swap_mode:
     case dq_mode:
     case dqb_mode:
     case dqd_mode:
@@ -11400,7 +11590,9 @@ OP_E_register (int bytemode, int sizeflag)
       USED_REX (REX_W);
       if (rex & REX_W)
        names = names64;
-      else if ((sizeflag & DFLAG) || bytemode != v_mode)
+      else if ((sizeflag & DFLAG) 
+              || (bytemode != v_mode
+                  && bytemode != v_swap_mode))
        names = names32;
       else
        names = names16;
@@ -12412,7 +12604,8 @@ OP_EM (int bytemode, int sizeflag)
 {
   if (modrm.mod != 3)
     {
-      if (intel_syntax && bytemode == v_mode)
+      if (intel_syntax
+         && (bytemode == v_mode || bytemode == v_swap_mode))
        {
          bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
          used_prefixes |= (prefixes & PREFIX_DATA);
@@ -12421,6 +12614,9 @@ OP_EM (int bytemode, int sizeflag)
       return;
     }
 
+  if ((sizeflag & SUFFIX_ALWAYS) && bytemode == v_swap_mode)
+    swap_operand ();
+
   /* Skip mod/rm byte.  */
   MODRM_CHECK;
   codep++;
@@ -12491,6 +12687,12 @@ OP_EX (int bytemode, int sizeflag)
   else
     add = 0;
 
+  if ((sizeflag & SUFFIX_ALWAYS)
+      && (bytemode == x_swap_mode
+         || bytemode == d_swap_mode
+         || bytemode == q_swap_mode))
+    swap_operand ();
+
   /* Skip mod/rm byte.  */
   MODRM_CHECK;
   codep++;
@@ -12653,7 +12855,7 @@ OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
   /* AMD 3DNow! instructions are specified by an opcode suffix in the
      place where an 8-bit immediate would normally go.  ie. the last
      byte of the instruction.  */
-  obufp = obuf + strlen (obuf);
+  obufp = mnemonicendp;
   mnemonic = Suffix3DNow[*codep++ & 0xff];
   if (mnemonic)
     oappend (mnemonic);
@@ -12667,17 +12869,19 @@ OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
       op_out[1][0] = '\0';
       BadOp ();
     }
+  mnemonicendp = obufp;
 }
 
-static const char *simd_cmp_op[] = {
-  "eq",
-  "lt",
-  "le",
-  "unord",
-  "neq",
-  "nlt",
-  "nle",
-  "ord"
+static struct op simd_cmp_op[] =
+{
+  { STRING_COMMA_LEN ("eq") },
+  { STRING_COMMA_LEN ("lt") },
+  { STRING_COMMA_LEN ("le") },
+  { STRING_COMMA_LEN ("unord") },
+  { STRING_COMMA_LEN ("neq") },
+  { STRING_COMMA_LEN ("nlt") },
+  { STRING_COMMA_LEN ("nle") },
+  { STRING_COMMA_LEN ("ord") }
 };
 
 static void
@@ -12690,11 +12894,12 @@ CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
   if (cmp_type < ARRAY_SIZE (simd_cmp_op))
     {
       char suffix [3];
-      char *p = obuf + strlen (obuf) - 2;
+      char *p = mnemonicendp - 2;
       suffix[0] = p[0];
       suffix[1] = p[1];
       suffix[2] = '\0';
-      sprintf (p, "%s%s", simd_cmp_op[cmp_type], suffix);
+      sprintf (p, "%s%s", simd_cmp_op[cmp_type].name, suffix);
+      mnemonicendp += simd_cmp_op[cmp_type].len;
     }
   else
     {
@@ -12798,8 +13003,8 @@ CMPXCHG8B_Fixup (int bytemode, int sizeflag)
   if (rex & REX_W)
     {
       /* Change cmpxchg8b to cmpxchg16b.  */
-      char *p = obuf + strlen (obuf) - 2;
-      strcpy (p, "16b");
+      char *p = mnemonicendp - 2;
+      mnemonicendp = stpcpy (p, "16b");
       bytemode = o_mode;
     }
   OP_M (bytemode, sizeflag);
@@ -12831,19 +13036,19 @@ static void
 CRC32_Fixup (int bytemode, int sizeflag)
 {
   /* Add proper suffix to "crc32".  */
-  char *p = obuf + strlen (obuf);
+  char *p = mnemonicendp;
 
   switch (bytemode)
     {
     case b_mode:
       if (intel_syntax)
-       break;
+       goto skip;
 
       *p++ = 'b';
       break;
     case v_mode:
       if (intel_syntax)
-       break;
+       goto skip;
 
       USED_REX (REX_W);
       if (rex & REX_W)
@@ -12858,8 +13063,10 @@ CRC32_Fixup (int bytemode, int sizeflag)
       oappend (INTERNAL_DISASSEMBLER_ERROR);
       break;
     }
+  mnemonicendp = p;
   *p = '\0';
 
+skip:
   if (modrm.mod == 3)
     {
       int add;
@@ -13187,7 +13394,7 @@ OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED,
   else
     {
       sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3);
-      strcpy (obuf, scratchbuf);
+      mnemonicendp = stpcpy (obuf, scratchbuf);
       codep++;
     }
 }
@@ -13229,7 +13436,7 @@ OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED,
   else
     {
       sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4);
-      strcpy (obuf, scratchbuf);
+      mnemonicendp = stpcpy (obuf, scratchbuf);
       codep++;
     }
 }
@@ -13281,204 +13488,6 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
   oappend (scratchbuf + intel_syntax);
 }
 
-/* Get the VEX immediate byte without moving codep.  */
-
-static unsigned char
-get_vex_imm8 (int sizeflag)
-{
-  int bytes_before_imm = 0;
-
-  /* Skip mod/rm byte.   */
-  MODRM_CHECK;
-  codep++;
-
-  if (modrm.mod != 3)
-    {
-      /* There are SIB/displacement bytes.  */
-      if ((sizeflag & AFLAG) || address_mode == mode_64bit)
-       {
-         /* 32/64 bit address mode */
-         int base = modrm.rm;
-
-         /* Check SIB byte.  */
-         if (base == 4)
-           {
-             FETCH_DATA (the_info, codep + 1);
-             base = *codep & 7;
-             bytes_before_imm++;
-           }
-
-         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;
-           }
-       }
-    }
-
-  FETCH_DATA (the_info, codep + bytes_before_imm + 1);
-  return codep [bytes_before_imm];
-}
-
-static void
-OP_EX_VexReg (int bytemode, int sizeflag, int reg)
-{
-  if (reg == -1 && modrm.mod != 3)
-    {
-      OP_E_memory (bytemode, sizeflag, 0);
-      return;
-    }
-  else
-    {
-      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 ();
-    }
-
-  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_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)
-{
-  int reg = -1;
-
-  if (!vex_w_done)
-    {
-      vex_w_done = 1;
-      if (vex.w)
-       reg = vex.register_specifier;
-    }
-  else
-    {
-      if (!vex.w)
-       reg = vex.register_specifier;
-    }
-
-  OP_EX_VexReg (bytemode, sizeflag, reg);
-}
-
-static void
-OP_VEX_FMA (int bytemode, int sizeflag)
-{
-  int reg = get_vex_imm8 (sizeflag) >> 4;
-
-  if (reg > 7 && address_mode != mode_64bit)
-    BadOp ();
-
-  switch (vex.length)
-    {
-    case 128:
-      switch (bytemode)
-       {
-       case vex_mode:
-       case vex128_mode:
-         break;
-       default:
-         abort ();
-         return;
-       }
-
-      sprintf (scratchbuf, "%%xmm%d", reg);
-      break;
-    case 256:
-      switch (bytemode)
-       {
-       case vex_mode:
-         break;
-       default:
-         abort ();
-         return;
-       }
-
-      sprintf (scratchbuf, "%%ymm%d", reg);
-      break;
-    default:
-      abort ();
-    }
-  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)
 {
@@ -13510,15 +13519,6 @@ 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)
 {
@@ -13549,49 +13549,50 @@ VZERO_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
   switch (vex.length)
     {
     case 128:
-      strcpy (obuf, "vzeroupper");
+      mnemonicendp = stpcpy (obuf, "vzeroupper");
       break;
     case 256:
-      strcpy (obuf, "vzeroall");
+      mnemonicendp = stpcpy (obuf, "vzeroall");
       break;
     default:
       abort ();
     }
 }
 
-static const char *vex_cmp_op[] = {
-  "eq",
-  "lt",
-  "le",
-  "unord",
-  "neq",
-  "nlt",
-  "nle",
-  "ord",
-  "eq_uq",
-  "nge",
-  "ngt",
-  "false",
-  "neq_oq",
-  "ge",
-  "gt",
-  "true",
-  "eq_os",
-  "lt_oq",
-  "le_oq",
-  "unord_s",
-  "neq_us",
-  "nlt_uq",
-  "nle_uq",
-  "ord_s",
-  "eq_us",
-  "nge_uq",
-  "ngt_uq",
-  "false_os",
-  "neq_os",
-  "ge_oq",
-  "gt_oq",
-  "true_us"
+static struct op vex_cmp_op[] =
+{
+  { STRING_COMMA_LEN ("eq") },
+  { STRING_COMMA_LEN ("lt") },
+  { STRING_COMMA_LEN ("le") },
+  { STRING_COMMA_LEN ("unord") },
+  { STRING_COMMA_LEN ("neq") },
+  { STRING_COMMA_LEN ("nlt") },
+  { STRING_COMMA_LEN ("nle") },
+  { STRING_COMMA_LEN ("ord") },
+  { STRING_COMMA_LEN ("eq_uq") },
+  { STRING_COMMA_LEN ("nge") },
+  { STRING_COMMA_LEN ("ngt") },
+  { STRING_COMMA_LEN ("false") },
+  { STRING_COMMA_LEN ("neq_oq") },
+  { STRING_COMMA_LEN ("ge") },
+  { STRING_COMMA_LEN ("gt") },
+  { STRING_COMMA_LEN ("true") },
+  { STRING_COMMA_LEN ("eq_os") },
+  { STRING_COMMA_LEN ("lt_oq") },
+  { STRING_COMMA_LEN ("le_oq") },
+  { STRING_COMMA_LEN ("unord_s") },
+  { STRING_COMMA_LEN ("neq_us") },
+  { STRING_COMMA_LEN ("nlt_uq") },
+  { STRING_COMMA_LEN ("nle_uq") },
+  { STRING_COMMA_LEN ("ord_s") },
+  { STRING_COMMA_LEN ("eq_us") },
+  { STRING_COMMA_LEN ("nge_uq") },
+  { STRING_COMMA_LEN ("ngt_uq") },
+  { STRING_COMMA_LEN ("false_os") },
+  { STRING_COMMA_LEN ("neq_os") },
+  { STRING_COMMA_LEN ("ge_oq") },
+  { STRING_COMMA_LEN ("gt_oq") },
+  { STRING_COMMA_LEN ("true_us") },
 };
 
 static void
@@ -13604,11 +13605,12 @@ VCMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
   if (cmp_type < ARRAY_SIZE (vex_cmp_op))
     {
       char suffix [3];
-      char *p = obuf + strlen (obuf) - 2;
+      char *p = mnemonicendp - 2;
       suffix[0] = p[0];
       suffix[1] = p[1];
       suffix[2] = '\0';
-      sprintf (p, "%s%s", vex_cmp_op[cmp_type], suffix);
+      sprintf (p, "%s%s", vex_cmp_op[cmp_type].name, suffix);
+      mnemonicendp += vex_cmp_op[cmp_type].len;
     }
   else
     {
@@ -13620,11 +13622,12 @@ VCMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
     }
 }
 
-static const char *pclmul_op[] = {
-  "lql",
-  "hql",
-  "lqh",
-  "hqh"
+static const struct op pclmul_op[] =
+{
+  { STRING_COMMA_LEN ("lql") },
+  { STRING_COMMA_LEN ("hql") },
+  { STRING_COMMA_LEN ("lqh") },
+  { STRING_COMMA_LEN ("hqh") }
 };
 
 static void
@@ -13649,12 +13652,13 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
   if (pclmul_type < ARRAY_SIZE (pclmul_op))
     {
       char suffix [4];
-      char *p = obuf + strlen (obuf) - 3;
+      char *p = mnemonicendp - 3;
       suffix[0] = p[0];
       suffix[1] = p[1];
       suffix[2] = p[2];
       suffix[3] = '\0';
-      sprintf (p, "%s%s", pclmul_op[pclmul_type], suffix);
+      sprintf (p, "%s%s", pclmul_op[pclmul_type].name, suffix);
+      mnemonicendp += pclmul_op[pclmul_type].len;
     }
   else
     {
@@ -13666,37 +13670,37 @@ PCLMUL_Fixup (int bytemode ATTRIBUTE_UNUSED,
     }
 }
 
-static const char *vpermil2_op[] = {
-  "td",
-  "td",
-  "mo",
-  "mz"
-};
-
 static void
-VPERMIL2_Fixup (int bytemode ATTRIBUTE_UNUSED,
-               int sizeflag ATTRIBUTE_UNUSED)
+MOVBE_Fixup (int bytemode, int sizeflag)
 {
-  unsigned int vpermil2_type;
+  /* Add proper suffix to "movbe".  */
+  char *p = mnemonicendp;
 
-  FETCH_DATA (the_info, codep + 1);
-  vpermil2_type = *codep++ & 0xf;
-  if (vpermil2_type < ARRAY_SIZE (vpermil2_op))
-    {
-      char suffix [4];
-      char *p = obuf + strlen (obuf) - 3;
-      suffix[0] = p[0];
-      suffix[1] = p[1];
-      suffix[2] = p[2];
-      suffix[3] = '\0';
-      sprintf (p, "%s%s", vpermil2_op[vpermil2_type], suffix);
-    }
-  else
+  switch (bytemode)
     {
-      /* 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';
+    case v_mode:
+      if (intel_syntax)
+       goto skip;
+
+      USED_REX (REX_W);
+      if (sizeflag & SUFFIX_ALWAYS)
+       {
+         if (rex & REX_W)
+           *p++ = 'q';
+         else if (sizeflag & DFLAG)
+           *p++ = 'l';
+         else
+           *p++ = 'w';
+       }
+      used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
+    default:
+      oappend (INTERNAL_DISASSEMBLER_ERROR);
+      break;
     }
+  mnemonicendp = p;
+  *p = '\0';
+
+skip:
+  OP_M (bytemode, sizeflag);
 }
This page took 0.062876 seconds and 4 git commands to generate.