gdb/testsuite/
[binutils-gdb.git] / opcodes / i386-dis.c
index f9fae9795e7a6b2d7e155169857ac982f5a47b48..fef9185e5f20e3b64d3c2a9b582d9e217391bb14 100644 (file)
@@ -1,6 +1,6 @@
 /* Print i386 instructions for GDB, the GNU debugger.
    Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
@@ -91,6 +91,7 @@ static void OP_M (int, int);
 static void OP_VEX (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);
@@ -113,7 +114,6 @@ static void CRC32_Fixup (int, int);
 static void FXSAVE_Fixup (int, int);
 static void OP_LWPCB_E (int, int);
 static void OP_LWP_E (int, int);
-static void OP_LWP_I (int, int);
 static void OP_Vex_2src_1 (int, int);
 static void OP_Vex_2src_2 (int, int);
 
@@ -334,6 +334,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 
 #define MX { OP_MMX, 0 }
 #define XM { OP_XMM, 0 }
+#define XMScalar { OP_XMM, scalar_mode }
 #define XMM { OP_XMM, xmm_mode }
 #define EM { OP_EM, v_mode }
 #define EMS { OP_EM, v_swap_mode }
@@ -341,8 +342,11 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EMx { OP_EM, x_mode }
 #define EXw { OP_EX, w_mode }
 #define EXd { OP_EX, d_mode }
+#define EXdScalar { OP_EX, d_scalar_mode }
 #define EXdS { OP_EX, d_swap_mode }
 #define EXq { OP_EX, q_mode }
+#define EXqScalar { OP_EX, q_scalar_mode }
+#define EXqScalarS { OP_EX, q_scalar_swap_mode }
 #define EXqS { OP_EX, q_swap_mode }
 #define EXx { OP_EX, x_mode }
 #define EXxS { OP_EX, x_swap_mode }
@@ -350,6 +354,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define EXxmmq { OP_EX, xmmq_mode }
 #define EXymmq { OP_EX, ymmq_mode }
 #define EXVexWdq { OP_EX, vex_w_dq_mode }
+#define EXVexWdqScalar { OP_EX, vex_scalar_w_dq_mode }
 #define MS { OP_MS, v_mode }
 #define XS { OP_XS, v_mode }
 #define EMCq { OP_EMC, q_mode }
@@ -362,17 +367,22 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Vex_2src_2 { OP_Vex_2src_2, 0 }
 
 #define Vex { OP_VEX, vex_mode }
+#define VexScalar { OP_VEX, vex_scalar_mode }
 #define Vex128 { OP_VEX, vex128_mode }
 #define Vex256 { OP_VEX, vex256_mode }
 #define VexI4 { VEXI4_Fixup, 0}
 #define EXdVex { OP_EX_Vex, d_mode }
 #define EXdVexS { OP_EX_Vex, d_swap_mode }
+#define EXdVexScalarS { OP_EX_Vex, d_scalar_swap_mode }
 #define EXqVex { OP_EX_Vex, q_mode }
 #define EXqVexS { OP_EX_Vex, q_swap_mode }
+#define EXqVexScalarS { OP_EX_Vex, q_scalar_swap_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 XMVex { OP_XMM_Vex, 0 }
+#define XMVexScalar { OP_XMM_Vex, scalar_mode }
 #define XMVexW { OP_XMM_VexW, 0 }
 #define XMVexI4 { OP_REG_VexI4, x_mode }
 #define PCLMUL { PCLMUL_Fixup, 0 }
@@ -461,6 +471,21 @@ enum
   /* operand size depends on the VEX.W bit.  */
   vex_w_dq_mode,
 
+  /* scalar, ignore vector length.  */
+  scalar_mode,
+  /* like d_mode, ignore vector length.  */
+  d_scalar_mode,
+  /* like d_swap_mode, ignore vector length.  */
+  d_scalar_swap_mode,
+  /* like q_mode, ignore vector length.  */
+  q_scalar_mode,
+  /* like q_swap_mode, ignore vector length.  */
+  q_scalar_swap_mode,
+  /* like vex_mode, ignore vector length.  */
+  vex_scalar_mode,
+  /* like vex_w_dq_mode, ignore vector length.  */
+  vex_scalar_w_dq_mode,
+
   es_reg,
   cs_reg,
   ss_reg,
@@ -1008,6 +1033,8 @@ enum
   PREFIX_VEX_3A41,
   PREFIX_VEX_3A42,
   PREFIX_VEX_3A44,
+  PREFIX_VEX_3A48,
+  PREFIX_VEX_3A49,
   PREFIX_VEX_3A4A,
   PREFIX_VEX_3A4B,
   PREFIX_VEX_3A4C,
@@ -1546,6 +1573,8 @@ enum
   VEX_W_3A41_P_2,
   VEX_W_3A42_P_2,
   VEX_W_3A44_P_2,
+  VEX_W_3A48_P_2,
+  VEX_W_3A49_P_2,
   VEX_W_3A4A_P_2,
   VEX_W_3A4B_P_2,
   VEX_W_3A4C_P_2,
@@ -2714,8 +2743,8 @@ static const struct dis386 reg_table[][8] = {
   },
   /* REG_XOP_LWP */
   {
-    { "lwpins", { { OP_LWP_E, 0 }, Ed, { OP_LWP_I, 0 } } },
-    { "lwpval",        { { OP_LWP_E, 0 }, Ed, { OP_LWP_I, 0 } } },
+    { "lwpins", { { OP_LWP_E, 0 }, Ed, Iq } },
+    { "lwpval",        { { OP_LWP_E, 0 }, Ed, Iq } },
   },
 };
 
@@ -4437,7 +4466,6 @@ static const struct dis386 prefix_table[][4] = {
     { Bad_Opcode },
     { Bad_Opcode },
     { VEX_LEN_TABLE (VEX_LEN_3820_P_2) },
-    { Bad_Opcode },
   },
 
   /* PREFIX_VEX_3821 */
@@ -4675,7 +4703,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmadd132s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmadd132s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_389A */
@@ -4689,7 +4717,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsub132s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmsub132s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_389C */
@@ -4703,7 +4731,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmadd132s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmadd132s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_389E */
@@ -4717,7 +4745,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmsub132s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmsub132s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38A6 */
@@ -4746,7 +4774,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmadd213s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmadd213s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38AA */
@@ -4760,7 +4788,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsub213s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmsub213s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38AC */
@@ -4774,7 +4802,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmadd213s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmadd213s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38AE */
@@ -4788,7 +4816,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmsub213s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmsub213s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38B6 */
@@ -4816,7 +4844,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmadd231s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmadd231s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38BA */
@@ -4830,7 +4858,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsub231s%XW", { XM, Vex, EXVexWdq } },
+    { "vfmsub231s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38BC */
@@ -4844,7 +4872,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmadd231s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmadd231s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38BE */
@@ -4858,7 +4886,7 @@ static const struct dis386 prefix_table[][4] = {
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmsub231s%XW", { XM, Vex, EXVexWdq } },
+    { "vfnmsub231s%XW", { XMScalar, VexScalar, EXVexWdqScalar } },
   },
 
   /* PREFIX_VEX_38DB */
@@ -5064,6 +5092,20 @@ static const struct dis386 prefix_table[][4] = {
     { VEX_LEN_TABLE (VEX_LEN_3A44_P_2) },
   },
 
+  /* PREFIX_VEX_3A48 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { VEX_W_TABLE (VEX_W_3A48_P_2) },
+  },
+
+  /* PREFIX_VEX_3A49 */
+  {
+    { Bad_Opcode },
+    { Bad_Opcode },
+    { VEX_W_TABLE (VEX_W_3A49_P_2) },
+  },
+
   /* PREFIX_VEX_3A4A */
   {
     { Bad_Opcode },
@@ -7835,8 +7877,8 @@ static const struct dis386 vex_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* 48 */
-    { Bad_Opcode },
-    { Bad_Opcode },
+    { PREFIX_TABLE (PREFIX_VEX_3A48) },
+    { PREFIX_TABLE (PREFIX_VEX_3A49) },
     { PREFIX_TABLE (PREFIX_VEX_3A4A) },
     { PREFIX_TABLE (PREFIX_VEX_3A4B) },
     { PREFIX_TABLE (PREFIX_VEX_3A4C) },
@@ -8048,21 +8090,25 @@ static const struct dis386 vex_len_table[][2] = {
   /* VEX_LEN_10_P_1 */
   {
     { VEX_W_TABLE (VEX_W_10_P_1) },
+    { VEX_W_TABLE (VEX_W_10_P_1) },
   },
 
   /* VEX_LEN_10_P_3 */
   {
     { VEX_W_TABLE (VEX_W_10_P_3) },
+    { VEX_W_TABLE (VEX_W_10_P_3) },
   },
 
   /* VEX_LEN_11_P_1 */
   {
     { VEX_W_TABLE (VEX_W_11_P_1) },
+    { VEX_W_TABLE (VEX_W_11_P_1) },
   },
 
   /* VEX_LEN_11_P_3 */
   {
     { VEX_W_TABLE (VEX_W_11_P_3) },
+    { VEX_W_TABLE (VEX_W_11_P_3) },
   },
 
   /* VEX_LEN_12_P_0_M_0 */
@@ -8107,142 +8153,170 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_2A_P_1 */
   {
-    { "vcvtsi2ss%LQ",  { XM, Vex128, Ev } },
+    { "vcvtsi2ss%LQ",  { XMScalar, VexScalar, Ev } },
+    { "vcvtsi2ss%LQ",  { XMScalar, VexScalar, Ev } },
   },
 
   /* VEX_LEN_2A_P_3 */
   {
-    { "vcvtsi2sd%LQ",  { XM, Vex128, Ev } },
+    { "vcvtsi2sd%LQ",  { XMScalar, VexScalar, Ev } },
+    { "vcvtsi2sd%LQ",  { XMScalar, VexScalar, Ev } },
   },
 
   /* VEX_LEN_2C_P_1 */
   {
-    { "vcvttss2siY",   { Gv, EXd } },
+    { "vcvttss2siY",   { Gv, EXdScalar } },
+    { "vcvttss2siY",   { Gv, EXdScalar } },
   },
 
   /* VEX_LEN_2C_P_3 */
   {
-    { "vcvttsd2siY",   { Gv, EXq } },
+    { "vcvttsd2siY",   { Gv, EXqScalar } },
+    { "vcvttsd2siY",   { Gv, EXqScalar } },
   },
 
   /* VEX_LEN_2D_P_1 */
   {
-    { "vcvtss2siY",    { Gv, EXd } },
+    { "vcvtss2siY",    { Gv, EXdScalar } },
+    { "vcvtss2siY",    { Gv, EXdScalar } },
   },
 
   /* VEX_LEN_2D_P_3 */
   {
-    { "vcvtsd2siY",    { Gv, EXq } },
+    { "vcvtsd2siY",    { Gv, EXqScalar } },
+    { "vcvtsd2siY",    { Gv, EXqScalar } },
   },
 
   /* VEX_LEN_2E_P_0 */
   {
     { VEX_W_TABLE (VEX_W_2E_P_0) },
+    { VEX_W_TABLE (VEX_W_2E_P_0) },
   },
 
   /* VEX_LEN_2E_P_2 */
   {
     { VEX_W_TABLE (VEX_W_2E_P_2) },
+    { VEX_W_TABLE (VEX_W_2E_P_2) },
   },
 
   /* VEX_LEN_2F_P_0 */
   {
     { VEX_W_TABLE (VEX_W_2F_P_0) },
+    { VEX_W_TABLE (VEX_W_2F_P_0) },
   },
 
   /* VEX_LEN_2F_P_2 */
   {
     { VEX_W_TABLE (VEX_W_2F_P_2) },
+    { VEX_W_TABLE (VEX_W_2F_P_2) },
   },
 
   /* VEX_LEN_51_P_1 */
   {
     { VEX_W_TABLE (VEX_W_51_P_1) },
+    { VEX_W_TABLE (VEX_W_51_P_1) },
   },
 
   /* VEX_LEN_51_P_3 */
   {
     { VEX_W_TABLE (VEX_W_51_P_3) },
+    { VEX_W_TABLE (VEX_W_51_P_3) },
   },
 
   /* VEX_LEN_52_P_1 */
   {
     { VEX_W_TABLE (VEX_W_52_P_1) },
+    { VEX_W_TABLE (VEX_W_52_P_1) },
   },
 
   /* VEX_LEN_53_P_1 */
   {
     { VEX_W_TABLE (VEX_W_53_P_1) },
+    { VEX_W_TABLE (VEX_W_53_P_1) },
   },
 
   /* VEX_LEN_58_P_1 */
   {
     { VEX_W_TABLE (VEX_W_58_P_1) },
+    { VEX_W_TABLE (VEX_W_58_P_1) },
   },
 
   /* VEX_LEN_58_P_3 */
   {
     { VEX_W_TABLE (VEX_W_58_P_3) },
+    { VEX_W_TABLE (VEX_W_58_P_3) },
   },
 
   /* VEX_LEN_59_P_1 */
   {
     { VEX_W_TABLE (VEX_W_59_P_1) },
+    { VEX_W_TABLE (VEX_W_59_P_1) },
   },
 
   /* VEX_LEN_59_P_3 */
   {
     { VEX_W_TABLE (VEX_W_59_P_3) },
+    { VEX_W_TABLE (VEX_W_59_P_3) },
   },
 
   /* VEX_LEN_5A_P_1 */
   {
     { VEX_W_TABLE (VEX_W_5A_P_1) },
+    { VEX_W_TABLE (VEX_W_5A_P_1) },
   },
 
   /* VEX_LEN_5A_P_3 */
   {
     { VEX_W_TABLE (VEX_W_5A_P_3) },
+    { VEX_W_TABLE (VEX_W_5A_P_3) },
   },
 
   /* VEX_LEN_5C_P_1 */
   {
     { VEX_W_TABLE (VEX_W_5C_P_1) },
+    { VEX_W_TABLE (VEX_W_5C_P_1) },
   },
 
   /* VEX_LEN_5C_P_3 */
   {
     { VEX_W_TABLE (VEX_W_5C_P_3) },
+    { VEX_W_TABLE (VEX_W_5C_P_3) },
   },
 
   /* VEX_LEN_5D_P_1 */
   {
     { VEX_W_TABLE (VEX_W_5D_P_1) },
+    { VEX_W_TABLE (VEX_W_5D_P_1) },
   },
 
   /* VEX_LEN_5D_P_3 */
   {
     { VEX_W_TABLE (VEX_W_5D_P_3) },
+    { VEX_W_TABLE (VEX_W_5D_P_3) },
   },
 
   /* VEX_LEN_5E_P_1 */
   {
     { VEX_W_TABLE (VEX_W_5E_P_1) },
+    { VEX_W_TABLE (VEX_W_5E_P_1) },
   },
 
   /* VEX_LEN_5E_P_3 */
   {
     { VEX_W_TABLE (VEX_W_5E_P_3) },
+    { VEX_W_TABLE (VEX_W_5E_P_3) },
   },
 
   /* VEX_LEN_5F_P_1 */
   {
     { VEX_W_TABLE (VEX_W_5F_P_1) },
+    { VEX_W_TABLE (VEX_W_5F_P_1) },
   },
 
   /* VEX_LEN_5F_P_3 */
   {
     { VEX_W_TABLE (VEX_W_5F_P_3) },
+    { VEX_W_TABLE (VEX_W_5F_P_3) },
   },
 
   /* VEX_LEN_60_P_2 */
@@ -8317,7 +8391,8 @@ static const struct dis386 vex_len_table[][2] = {
 
   /* VEX_LEN_6E_P_2 */
   {
-    { "vmovK",         { XM, Edq } },
+    { "vmovK",         { XMScalar, Edq } },
+    { "vmovK",         { XMScalar, Edq } },
   },
 
   /* VEX_LEN_70_P_1 */
@@ -8403,11 +8478,13 @@ static const struct dis386 vex_len_table[][2] = {
   /* VEX_LEN_7E_P_1 */
   {
     { VEX_W_TABLE (VEX_W_7E_P_1) },
+    { VEX_W_TABLE (VEX_W_7E_P_1) },
   },
 
   /* VEX_LEN_7E_P_2 */
   {
-    { "vmovK",         { Edq, XM } },
+    { "vmovK",         { Edq, XMScalar } },
+    { "vmovK",         { Edq, XMScalar } },
   },
 
   /* VEX_LEN_AE_R_2_M_0 */
@@ -8423,11 +8500,13 @@ static const struct dis386 vex_len_table[][2] = {
   /* VEX_LEN_C2_P_1 */
   {
     { VEX_W_TABLE (VEX_W_C2_P_1) },
+    { VEX_W_TABLE (VEX_W_C2_P_1) },
   },
 
   /* VEX_LEN_C2_P_3 */
   {
     { VEX_W_TABLE (VEX_W_C2_P_3) },
+    { VEX_W_TABLE (VEX_W_C2_P_3) },
   },
 
   /* VEX_LEN_C4_P_2 */
@@ -8468,6 +8547,7 @@ static const struct dis386 vex_len_table[][2] = {
   /* VEX_LEN_D6_P_2 */
   {
     { VEX_W_TABLE (VEX_W_D6_P_2) },
+    { VEX_W_TABLE (VEX_W_D6_P_2) },
   },
 
   /* VEX_LEN_D7_P_2_M_1 */
@@ -8911,11 +8991,13 @@ static const struct dis386 vex_len_table[][2] = {
   /* VEX_LEN_3A0A_P_2 */
   {
     { VEX_W_TABLE (VEX_W_3A0A_P_2) },
+    { VEX_W_TABLE (VEX_W_3A0A_P_2) },
   },
 
   /* VEX_LEN_3A0B_P_2 */
   {
     { VEX_W_TABLE (VEX_W_3A0B_P_2) },
+    { VEX_W_TABLE (VEX_W_3A0B_P_2) },
   },
 
   /* VEX_LEN_3A0E_P_2 */
@@ -9080,7 +9162,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_10_P_1 */
-    { "vmovss",                { XMVex, Vex128, EXd } },
+    { "vmovss",                { XMVexScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_10_P_2 */
@@ -9088,7 +9170,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_10_P_3 */
-    { "vmovsd",                { XMVex, Vex128, EXq } },
+    { "vmovsd",                { XMVexScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_11_P_0 */
@@ -9096,7 +9178,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_11_P_1 */
-    { "vmovss",                { EXdVexS, Vex128, XM } },
+    { "vmovss",                { EXdVexScalarS, VexScalar, XMScalar } },
   },
   {
     /* VEX_W_11_P_2 */
@@ -9104,7 +9186,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_11_P_3 */
-    { "vmovsd",                { EXqVexS, Vex128, XM } },
+    { "vmovsd",                { EXqVexScalarS, VexScalar, XMScalar } },
   },
   {
     /* VEX_W_12_P_0_M_0 */
@@ -9172,19 +9254,19 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_2E_P_0 */
-    { "vucomiss",      { XM, EXd } }, 
+    { "vucomiss",      { XMScalar, EXdScalar } }, 
   },
   {
     /* VEX_W_2E_P_2 */
-    { "vucomisd",      { XM, EXq } }, 
+    { "vucomisd",      { XMScalar, EXqScalar } }, 
   },
   {
     /* VEX_W_2F_P_0 */
-    { "vcomiss",       { XM, EXd } },
+    { "vcomiss",       { XMScalar, EXdScalar } },
   },
   {
     /* VEX_W_2F_P_2 */
-    { "vcomisd",       { XM, EXq } },
+    { "vcomisd",       { XMScalar, EXqScalar } },
   },
   {
     /* VEX_W_50_M_0 */
@@ -9196,7 +9278,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_51_P_1 */
-    { "vsqrtss",       { XM, Vex128, EXd } },
+    { "vsqrtss",       { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_51_P_2  */
@@ -9204,7 +9286,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_51_P_3 */
-    { "vsqrtsd",       { XM, Vex128, EXq } },
+    { "vsqrtsd",       { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_52_P_0 */
@@ -9212,7 +9294,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_52_P_1 */
-    { "vrsqrtss",      { XM, Vex128, EXd } },
+    { "vrsqrtss",      { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_53_P_0  */
@@ -9220,7 +9302,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_53_P_1  */
-    { "vrcpss",                { XM, Vex128, EXd } },
+    { "vrcpss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_58_P_0  */
@@ -9228,7 +9310,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_58_P_1  */
-    { "vaddss",                { XM, Vex128, EXd } },
+    { "vaddss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_58_P_2  */
@@ -9236,7 +9318,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_58_P_3  */
-    { "vaddsd",                { XM, Vex128, EXq } },
+    { "vaddsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_59_P_0  */
@@ -9244,7 +9326,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_59_P_1  */
-    { "vmulss",                { XM, Vex128, EXd } },
+    { "vmulss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_59_P_2  */
@@ -9252,7 +9334,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_59_P_3  */
-    { "vmulsd",                { XM, Vex128, EXq } },
+    { "vmulsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_5A_P_0  */
@@ -9260,11 +9342,11 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5A_P_1  */
-    { "vcvtss2sd",     { XM, Vex128, EXd } },
+    { "vcvtss2sd",     { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_5A_P_3  */
-    { "vcvtsd2ss",     { XM, Vex128, EXq } },
+    { "vcvtsd2ss",     { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_5B_P_0  */
@@ -9284,7 +9366,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5C_P_1  */
-    { "vsubss",                { XM, Vex128, EXd } },
+    { "vsubss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_5C_P_2  */
@@ -9292,7 +9374,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5C_P_3  */
-    { "vsubsd",                { XM, Vex128, EXq } },
+    { "vsubsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_5D_P_0  */
@@ -9300,7 +9382,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5D_P_1  */
-    { "vminss",                { XM, Vex128, EXd } },
+    { "vminss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_5D_P_2  */
@@ -9308,7 +9390,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5D_P_3  */
-    { "vminsd",                { XM, Vex128, EXq } },
+    { "vminsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_5E_P_0  */
@@ -9316,7 +9398,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5E_P_1  */
-    { "vdivss",                { XM, Vex128, EXd } },
+    { "vdivss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_5E_P_2  */
@@ -9324,7 +9406,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5E_P_3  */
-    { "vdivsd",                { XM, Vex128, EXq } },
+    { "vdivsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_5F_P_0  */
@@ -9332,7 +9414,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5F_P_1  */
-    { "vmaxss",                { XM, Vex128, EXd } },
+    { "vmaxss",                { XMScalar, VexScalar, EXdScalar } },
   },
   {
     /* VEX_W_5F_P_2  */
@@ -9340,7 +9422,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_5F_P_3  */
-    { "vmaxsd",                { XM, Vex128, EXq } },
+    { "vmaxsd",                { XMScalar, VexScalar, EXqScalar } },
   },
   {
     /* VEX_W_60_P_2  */
@@ -9492,7 +9574,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_7E_P_1 */
-    { "vmovq",         { XM, EXq } },
+    { "vmovq",         { XMScalar, EXqScalar } },
   },
   {
     /* VEX_W_7F_P_1 */
@@ -9516,7 +9598,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_C2_P_1 */
-    { "vcmpss",                { XM, Vex128, EXd, VCMP } },
+    { "vcmpss",                { XMScalar, VexScalar, EXdScalar, VCMP } },
   },
   {
     /* VEX_W_C2_P_2 */
@@ -9524,7 +9606,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_C2_P_3 */
-    { "vcmpsd",                { XM, Vex128, EXq, VCMP } },
+    { "vcmpsd",                { XMScalar, VexScalar, EXqScalar, VCMP } },
   },
   {
     /* VEX_W_C4_P_2 */
@@ -9564,7 +9646,7 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_D6_P_2 */
-    { "vmovq",         { EXqS, XM } },
+    { "vmovq",         { EXqScalarS, XMScalar } },
   },
   {
     /* VEX_W_D7_P_2_M_1 */
@@ -9992,11 +10074,11 @@ static const struct dis386 vex_w_table[][2] = {
   },
   {
     /* VEX_W_3A0A_P_2 */
-    { "vroundss",      { XM, Vex128, EXd, Ib } },
+    { "vroundss",      { XMScalar, VexScalar, EXdScalar, Ib } },
   },
   {
     /* VEX_W_3A0B_P_2 */
-    { "vroundsd",      { XM, Vex128, EXq, Ib } },
+    { "vroundsd",      { XMScalar, VexScalar, EXqScalar, Ib } },
   },
   {
     /* VEX_W_3A0C_P_2 */
@@ -10054,6 +10136,16 @@ static const struct dis386 vex_w_table[][2] = {
     /* VEX_W_3A44_P_2 */
     { "vpclmulqdq",    { XM, Vex128, EXx, PCLMUL } },
   },
+  {
+    /* VEX_W_3A48_P_2 */
+    { "vpermil2ps",    { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } },
+    { "vpermil2ps",    { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } },
+  },
+  {
+    /* VEX_W_3A49_P_2 */
+    { "vpermil2pd",    { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } },
+    { "vpermil2pd",    { XMVexW, Vex, EXVexImmW, EXVexImmW, EXVexImmW } },
+  },
   {
     /* VEX_W_3A4A_P_2 */
     { "vblendvps",     { XM, Vex, EXx, XMVexI4 } },
@@ -10966,7 +11058,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       switch ((*codep & 0x1f))
        {
        default:
-         BadOp ();
+         dp = &bad_opcode;
+         return dp;
        case 0x8:
          vex_table_index = XOP_08;
          break;
@@ -10985,7 +11078,10 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       vex.register_specifier = (~(*codep >> 3)) & 0xf;
       if (address_mode != mode_64bit
          && vex.register_specifier > 0x7)
-       BadOp ();
+       {
+         dp = &bad_opcode;
+         return dp;
+       }
 
       vex.length = (*codep & 0x4) ? 256 : 128;
       switch ((*codep & 0x3))
@@ -11023,7 +11119,8 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       switch ((*codep & 0x1f))
        {
        default:
-         BadOp ();
+         dp = &bad_opcode;
+         return dp;
        case 0x1:
          vex_table_index = VEX_0F;
          break;
@@ -11042,7 +11139,10 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       vex.register_specifier = (~(*codep >> 3)) & 0xf;
       if (address_mode != mode_64bit
          && vex.register_specifier > 0x7)
-       BadOp ();
+       {
+         dp = &bad_opcode;
+         return dp;
+       }
 
       vex.length = (*codep & 0x4) ? 256 : 128;
       switch ((*codep & 0x3))
@@ -11084,7 +11184,10 @@ get_valid_dis386 (const struct dis386 *dp, disassemble_info *info)
       vex.register_specifier = (~(*codep >> 3)) & 0xf;
       if (address_mode != mode_64bit
          && vex.register_specifier > 0x7)
-       BadOp ();
+       {
+         dp = &bad_opcode;
+         return dp;
+       }
 
       vex.w = 0;
 
@@ -11150,7 +11253,6 @@ print_insn (bfd_vma pc, disassemble_info *info)
   int sizeflag;
   const char *p;
   struct dis_private priv;
-  unsigned char op;
   int prefix_length;
   int default_prefixes;
 
@@ -11355,8 +11457,6 @@ print_insn (bfd_vma pc, disassemble_info *info)
       return 1;
     }
 
-  op = 0;
-
   if (*codep == 0x0f)
     {
       unsigned char threebyte;
@@ -12630,11 +12730,15 @@ intel_operand_size (int bytemode, int sizeflag)
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
     case d_mode:
+    case d_scalar_mode:
+    case d_scalar_swap_mode:
     case d_swap_mode:
     case dqd_mode:
       oappend ("DWORD PTR ");
       break;
     case q_mode:
+    case q_scalar_mode:
+    case q_scalar_swap_mode:
     case q_swap_mode:
       oappend ("QWORD PTR ");
       break;
@@ -12712,6 +12816,7 @@ intel_operand_size (int bytemode, int sizeflag)
       oappend ("OWORD PTR ");
       break;
     case vex_w_dq_mode:
+    case vex_scalar_w_dq_mode:
       if (!need_vex)
        abort ();
 
@@ -13435,7 +13540,6 @@ static void
 OP_sI (int bytemode, int sizeflag)
 {
   bfd_signed_vma op;
-  bfd_signed_vma mask = -1;
 
   switch (bytemode)
     {
@@ -13444,7 +13548,6 @@ OP_sI (int bytemode, int sizeflag)
       op = *codep++;
       if ((op & 0x80) != 0)
        op -= 0x100;
-      mask = 0xffffffff;
       break;
     case v_mode:
       USED_REX (REX_W);
@@ -13455,11 +13558,9 @@ OP_sI (int bytemode, int sizeflag)
          if (sizeflag & DFLAG)
            {
              op = get32s ();
-             mask = 0xffffffff;
            }
          else
            {
-             mask = 0xffffffff;
              op = get16 ();
              if ((op & 0x8000) != 0)
                op -= 0x10000;
@@ -13469,7 +13570,6 @@ OP_sI (int bytemode, int sizeflag)
       break;
     case w_mode:
       op = get16 ();
-      mask = 0xffffffff;
       if ((op & 0x8000) != 0)
        op -= 0x10000;
       break;
@@ -13778,7 +13878,9 @@ OP_XMM (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
   USED_REX (REX_R);
   if (rex & REX_R)
     reg += 8;
-  if (need_vex && bytemode != xmm_mode)
+  if (need_vex
+      && bytemode != xmm_mode
+      && bytemode != scalar_mode)
     {
       switch (vex.length)
        {
@@ -13892,12 +13994,19 @@ OP_EX (int bytemode, int sizeflag)
   if ((sizeflag & SUFFIX_ALWAYS)
       && (bytemode == x_swap_mode
          || bytemode == d_swap_mode
-         || bytemode == q_swap_mode))
+         || bytemode == d_scalar_swap_mode 
+         || bytemode == q_swap_mode
+         || bytemode == q_scalar_swap_mode))
     swap_operand ();
 
   if (need_vex
       && bytemode != xmm_mode
-      && bytemode != xmmq_mode)
+      && bytemode != xmmq_mode
+      && bytemode != d_scalar_mode
+      && bytemode != d_scalar_swap_mode 
+      && bytemode != q_scalar_mode
+      && bytemode != q_scalar_swap_mode
+      && bytemode != vex_scalar_w_dq_mode)
     {
       switch (vex.length)
        {
@@ -14326,6 +14435,7 @@ FXSAVE_Fixup (int bytemode, int sizeflag)
 static void
 OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
+  int reg;
   const char **names;
 
   if (!need_vex)
@@ -14334,6 +14444,13 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
   if (!need_vex_reg)
     return;
 
+  reg = vex.register_specifier;
+  if (bytemode == vex_scalar_mode)
+    {
+      oappend (names_xmm[reg]);
+      return;
+    }
+
   switch (vex.length)
     {
     case 128:
@@ -14366,7 +14483,7 @@ OP_VEX (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
       abort ();
       break;
     }
-  oappend (names[vex.register_specifier]);
+  oappend (names[reg]);
 }
 
 /* Get the VEX immediate byte without moving codep.  */
@@ -14495,6 +14612,47 @@ OP_EX_VexReg (int bytemode, int sizeflag, int reg)
   oappend (names[reg]);
 }
 
+static void
+OP_EX_VexImmW (int bytemode, int sizeflag)
+{
+  int reg = -1;
+  static unsigned char vex_imm8;
+
+  if (vex_w_done == 0)
+    {
+      vex_w_done = 1;
+
+      /* Skip mod/rm byte.  */
+      MODRM_CHECK;
+      codep++;
+
+      vex_imm8 = get_vex_imm8 (sizeflag, 0);
+
+      if (vex.w)
+         reg = vex_imm8 >> 4;
+
+      OP_EX_VexReg (bytemode, sizeflag, reg);
+    }
+  else if (vex_w_done == 1)
+    {
+      vex_w_done = 2;
+
+      if (!vex.w)
+         reg = vex_imm8 >> 4;
+
+      OP_EX_VexReg (bytemode, sizeflag, reg);
+    }
+  else
+    {
+      /* Output the imm8 directly.  */
+      scratchbuf[0] = '$';
+      print_operand_value (scratchbuf + 1, 1, vex_imm8 & 0xf);
+      oappend (scratchbuf + intel_syntax);
+      scratchbuf[0] = '\0';
+      codep++;
+    }
+}
+
 static void
 OP_Vex_2src (int bytemode, int sizeflag)
 {
@@ -14821,10 +14979,8 @@ OP_LWPCB_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 
   if (vex.w)
     names = names64;
-  else if (vex.length == 256)
-    names = names32;
   else
-    names = names16;
+    names = names32;
 
   reg = modrm.rm;
   USED_REX (REX_B);
@@ -14841,20 +14997,9 @@ OP_LWP_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
 
   if (vex.w)
     names = names64;
-  else if (vex.length == 256)
-    names = names32;
   else
-    names = names16;
+    names = names32;
 
   oappend (names[vex.register_specifier]);
 }
 
-static void
-OP_LWP_I (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
-{
-  if (vex.w || vex.length == 256)
-    OP_I (q_mode, sizeflag);
-  else
-    OP_I (w_mode, sizeflag);
-}
-