[1/5] x86: re-work operand swapping for FMA4 and 4-operand XOP insns

Message ID a95eec83-8e40-fb2b-3c27-f4a201f95f24@suse.com
State New
Headers show
Series
  • x86: XOP disassembler corrections and improvements
Related show

Commit Message

Jan Beulich July 7, 2020, 4:08 p.m.
There's no need for custom operand handling here, except for the VEX.W
controlled operand swapping. The latter can be easily integrated into
OP_REG_VexI4().

opcodes/
2020-07-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-dis.c (OP_EX_VexW, EXVexW, EXdVexW, EXqVexW): Delete.
	(prefix_table, vex_len_table): Replace operands for FMA4 insns.
	(xop_table): Replace operands of 4-operand insns.
	(OP_REG_VexI4): Move VEX.W based operand swaping here.

Patch

--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -89,7 +89,6 @@  static void OP_XS (int, int);
 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);
@@ -423,9 +422,6 @@  fetch_data (struct disassemble_info *inf
 #define VexGdq { OP_VEX, dq_mode }
 #define EXdVexScalarS { OP_EX_Vex, d_scalar_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 XMVexScalar { OP_XMM_Vex, scalar_mode }
 #define XMVexW { OP_XMM_VexW, 0 }
@@ -6452,28 +6448,28 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmaddsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmaddsubps", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A5D */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmaddsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmaddsubpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A5E */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsubaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmsubaddps", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A5F */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsubaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmsubaddpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A60 */
@@ -6509,14 +6505,14 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmaddps", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A69 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmaddpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A6A */
@@ -6537,14 +6533,14 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmsubps", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A6D */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfmsubpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A6E */
@@ -6565,14 +6561,14 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmaddps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfnmaddps", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A79 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmaddpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfnmaddpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A7A */
@@ -6593,7 +6589,7 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmsubps", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfnmsubps", { XM, Vex, EXx, XMVexI4 }, 0 },
     { Bad_Opcode },
   },
 
@@ -6601,7 +6597,7 @@  static const struct dis386 prefix_table[
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vfnmsubpd", { XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vfnmsubpd", { XM, Vex, EXx, XMVexI4 }, 0 },
   },
 
   /* PREFIX_VEX_0F3A7E */
@@ -7571,9 +7567,9 @@  static const struct dis386 xop_table[][2
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmacssww", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacsswd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacssdql", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmacssww", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacsswd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacssdql", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     /* 88 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -7581,17 +7577,17 @@  static const struct dis386 xop_table[][2
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmacssdd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacssdqh", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmacssdd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacssdqh", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     /* 90 */
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmacsww", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacswd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacsdql", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmacsww", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacswd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacsdql", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     /* 98 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -7599,16 +7595,16 @@  static const struct dis386 xop_table[][2
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmacsdd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpmacsdqh", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmacsdd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpmacsdqh", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     /* a0 */
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpcmov", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
-    { "vpperm", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpcmov", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
+    { "vpperm", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmadcsswd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmadcsswd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     { Bad_Opcode },
     /* a8 */
     { Bad_Opcode },
@@ -7626,7 +7622,7 @@  static const struct dis386 xop_table[][2
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { "vpmadcswd", 	{ XMVexW, Vex, EXVexW, EXVexW }, 0 },
+    { "vpmadcswd", 	{ XM, Vex, EXx, XMVexI4 }, 0 },
     { Bad_Opcode },
     /* b8 */
     { Bad_Opcode },
@@ -9633,42 +9629,42 @@  static const struct dis386 vex_len_table
 
   /* VEX_LEN_0F3A6A_P_2 */
   {
-    { "vfmaddss",	{ XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
+    { "vfmaddss",	{ XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A6B_P_2 */
   {
-    { "vfmaddsd",	{ XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
+    { "vfmaddsd",	{ XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A6E_P_2 */
   {
-    { "vfmsubss",	{ XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
+    { "vfmsubss",	{ XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A6F_P_2 */
   {
-    { "vfmsubsd",	{ XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
+    { "vfmsubsd",	{ XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A7A_P_2 */
   {
-    { "vfnmaddss",	{ XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
+    { "vfnmaddss",	{ XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A7B_P_2 */
   {
-    { "vfnmaddsd",	{ XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
+    { "vfnmaddsd",	{ XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A7E_P_2 */
   {
-    { "vfnmsubss",	{ XMVexW, Vex128, EXdVexW, EXdVexW }, 0 },
+    { "vfnmsubss",	{ XMScalar, VexScalar, EXxmm_md, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3A7F_P_2 */
   {
-    { "vfnmsubsd",	{ XMVexW, Vex128, EXqVexW, EXqVexW }, 0 },
+    { "vfnmsubsd",	{ XMScalar, VexScalar, EXxmm_mq, XMVexI4 }, 0 },
   },
 
   /* VEX_LEN_0F3ADF_P_2 */
@@ -16101,33 +16097,6 @@  OP_Vex_2src_2 (int bytemode, int sizefla
 }
 
 static void
-OP_EX_VexW (int bytemode, int sizeflag)
-{
-  int reg = -1;
-
-  if (!vex_w_done)
-    {
-      /* Skip mod/rm byte.  */
-      MODRM_CHECK;
-      codep++;
-
-      if (vex.w)
-	reg = get_vex_imm8 (sizeflag, 0) >> 4;
-    }
-  else
-    {
-      if (!vex.w)
-	reg = get_vex_imm8 (sizeflag, 1) >> 4;
-    }
-
-  OP_EX_VexReg (bytemode, sizeflag, reg);
-
-  if (vex_w_done)
-    codep++;
-  vex_w_done = 1;
-}
-
-static void
 OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
   int reg;
@@ -16155,6 +16124,14 @@  OP_REG_VexI4 (int bytemode, int sizeflag
       abort ();
     }
   oappend (names[reg]);
+
+  if (vex.w)
+    {
+      /* Swap 3rd and 4th operands.  */
+      strcpy (scratchbuf, op_out[3]);
+      strcpy (op_out[3], op_out[2]);
+      strcpy (op_out[2], scratchbuf);
+    }
 }
 
 static void