x86: re-work operand swapping for FMA4 and 4-operand XOP insns
authorJan Beulich <jbeulich@suse.com>
Wed, 8 Jul 2020 09:02:08 +0000 (11:02 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 8 Jul 2020 09:02:08 +0000 (11:02 +0200)
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/ChangeLog
opcodes/i386-dis.c

index 07f2594661d668e24270e7cbee92edff7ac473d8..5b6949cc2050b868e1dfeeef6e89443fd4f265e4 100644 (file)
@@ -1,3 +1,10 @@
+2020-07-08  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.
+
 2020-07-07  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * arc-opc.c (insert_rbd): New function.
index 956e2c353952c98615fca52a2fa06bb789c2eebc..eb1157b6ba2eecc2eb1e6f91b8e2abdc3049e8a6 100644 (file)
@@ -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 *info, bfd_byte *addr)
 #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[][4] = {
   {
     { 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[][4] = {
   {
     { 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[][4] = {
   {
     { 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[][4] = {
   {
     { 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[][4] = {
   {
     { 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[][4] = {
   {
     { 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[][256] = {
     { 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[][256] = {
     { 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[][256] = {
     { 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[][256] = {
     { 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[][2] = {
 
   /* 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 */
@@ -16100,33 +16096,6 @@ OP_Vex_2src_2 (int bytemode, int sizeflag)
     }
 }
 
-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)
 {
@@ -16155,6 +16124,14 @@ OP_REG_VexI4 (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
       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