x86: reduce AVX512-FP16 set of insns decoded through vex_w_table[]
authorJan Beulich <jbeulich@suse.com>
Fri, 14 Jan 2022 09:54:21 +0000 (10:54 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 14 Jan 2022 09:54:21 +0000 (10:54 +0100)
Like already indicated during review of the original submission, there's
really only very few insns where going through this table is easier /
cheaper than using suitable macros. Utilize %XH more and introduce
similar %XS and %XD (which subsequently can be used for further table
size reduction).

While there also switch to using oappend() in 'XH' macro processing.

opcodes/i386-dis-evex-prefix.h
opcodes/i386-dis-evex-w.h
opcodes/i386-dis-evex.h
opcodes/i386-dis.c

index 9c8156ac11ebdb9d20a3d7bf2332e059a40ac52f..64a43ce02a1958a60dd06271b52cb14c112f81c4 100644 (file)
     { "vfmsub213s%XW", { XMScalar, VexScalar, EXdq, EXxEVexR }, 0 },
     { "v4fnmaddss",    { XMScalar, VexScalar, Mxmm }, 0 },
   },
-  /* PREFIX_EVEX_0F3A08_W_0 */
+  /* PREFIX_EVEX_0F3A08 */
   {
-    { "vrndscaleph",    { XM, EXxh, EXxEVexS, Ib }, 0 },
+    { "vrndscalep%XH",  { XM, EXxh, EXxEVexS, Ib }, 0 },
     { Bad_Opcode },
-    { "vrndscaleps",    { XM, EXx, EXxEVexS, Ib }, 0 },
+    { "vrndscalep%XS",  { XM, EXx, EXxEVexS, Ib }, 0 },
   },
-  /* PREFIX_EVEX_0F3A0A_W_0 */
+  /* PREFIX_EVEX_0F3A0A */
   {
-    { "vrndscalesh",    { XMScalar, VexScalar, EXw, EXxEVexS, Ib }, 0 },
+    { "vrndscales%XH",  { XMScalar, VexScalar, EXw, EXxEVexS, Ib }, 0 },
     { Bad_Opcode },
-    { "vrndscaless",    { XMScalar, VexScalar, EXd, EXxEVexS, Ib }, 0 },
+    { "vrndscales%XS",  { XMScalar, VexScalar, EXd, EXxEVexS, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A26 */
   {
     { "vmulp%XH", { XM, Vex, EXxh, EXxEVexR }, 0 },
     { "vmuls%XH", { XMM, VexScalar, EXw, EXxEVexR }, 0 },
   },
-  /* PREFIX_EVEX_MAP5_5A_W_0 */
+  /* PREFIX_EVEX_MAP5_5A */
   {
-    { "vcvtph2pd",      { XM, EXxmmqdh, EXxEVexS }, 0 },
-    { "vcvtsh2sd",      { XMM, VexScalar, EXw, EXxEVexS }, 0 },
+    { "vcvtp%XH2pd",    { XM, EXxmmqdh, EXxEVexS }, 0 },
+    { "vcvts%XH2sd",    { XMM, VexScalar, EXw, EXxEVexS }, 0 },
+    { "vcvtp%XD2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
+    { "vcvts%XD2sh",    { XMM, VexScalar, EXq, EXxEVexR }, 0 },
   },
-  /* PREFIX_EVEX_MAP5_5A_W_1 */
+  /* PREFIX_EVEX_MAP5_5B */
   {
-    { Bad_Opcode },
-    { Bad_Opcode },
-    { "vcvtpd2ph%XZ",   { XMM, EXx, EXxEVexR }, 0 },
-    { "vcvtsd2sh",      { XMM, VexScalar, EXq, EXxEVexR }, 0 },
-  },
-  /* PREFIX_EVEX_MAP5_5B_W_0 */
-  {
-    { "vcvtdq2ph%XY",   { XMxmmq, EXx, EXxEVexR }, 0 },
-    { "vcvttph2dq",     { XM, EXxmmqh, EXxEVexS }, 0 },
-    { "vcvtph2dq",      { XM, EXxmmqh, EXxEVexR }, 0 },
-  },
-  /* PREFIX_EVEX_MAP5_5B_W_1 */
-  {
-    { "vcvtqq2ph%XZ",   { XMM, EXx, EXxEVexR }, 0 },
+    { VEX_W_TABLE (EVEX_W_MAP5_5B_P_0) },
+    { "vcvttp%XH2dq",   { XM, EXxmmqh, EXxEVexS }, 0 },
+    { "vcvtp%XH2dq",    { XM, EXxmmqh, EXxEVexR }, 0 },
   },
   /* PREFIX_EVEX_MAP5_5C */
   {
   },
   /* PREFIX_EVEX_MAP5_78 */
   {
-    { VEX_W_TABLE (EVEX_W_MAP5_78_P_0) },
+    { "vcvttp%XH2udq",  { XM, EXxmmqh, EXxEVexS }, 0 },
     { "vcvttsh2usi",    { Gdq, EXw, EXxEVexS }, 0 },
-    { VEX_W_TABLE (EVEX_W_MAP5_78_P_2) },
+    { "vcvttp%XH2uqq",  { XM, EXxmmqdh, EXxEVexS }, 0 },
   },
   /* PREFIX_EVEX_MAP5_79 */
   {
-    { VEX_W_TABLE (EVEX_W_MAP5_79_P_0) },
+    { "vcvtp%XH2udq",   { XM, EXxmmqh, EXxEVexR }, 0 },
     { "vcvtsh2usi",     { Gdq, EXw, EXxEVexR }, 0 },
-    { VEX_W_TABLE (EVEX_W_MAP5_79_P_2) },
+    { "vcvtp%XH2uqq",   { XM, EXxmmqdh, EXxEVexR }, 0 },
   },
   /* PREFIX_EVEX_MAP5_7A */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_MAP5_7A_P_2) },
+    { "vcvttp%XH2qq",   { XM, EXxmmqdh, EXxEVexS }, 0 },
     { VEX_W_TABLE (EVEX_W_MAP5_7A_P_3) },
   },
   /* PREFIX_EVEX_MAP5_7B */
   {
     { Bad_Opcode },
     { "vcvtusi2sh{%LQ|}",       { XMScalar, VexScalar, EXxEVexR, Edq }, 0 },
-    { VEX_W_TABLE (EVEX_W_MAP5_7B_P_2) },
+    { "vcvtp%XH2qq",    { XM, EXxmmqdh, EXxEVexR }, 0 },
   },
   /* PREFIX_EVEX_MAP5_7C */
   {
-    { VEX_W_TABLE (EVEX_W_MAP5_7C_P_0) },
+    { "vcvttp%XH2uw",   { XM, EXxh, EXxEVexS }, 0 },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_MAP5_7C_P_2) },
+    { "vcvttp%XH2w",    { XM, EXxh, EXxEVexS }, 0 },
   },
-  /* PREFIX_EVEX_MAP5_7D_W_0 */
+  /* PREFIX_EVEX_MAP5_7D */
   {
-    { "vcvtph2uw",      { XM, EXxh, EXxEVexR }, 0 },
-    { "vcvtw2ph",       { XM, EXxh, EXxEVexR }, 0 },
-    { "vcvtph2w",       { XM, EXxh, EXxEVexR }, 0 },
-    { "vcvtuw2ph",      { XM, EXxh, EXxEVexR }, 0 },
+    { "vcvtp%XH2uw",    { XM, EXxh, EXxEVexR }, 0 },
+    { "vcvtw2p%XH",     { XM, EXxh, EXxEVexR }, 0 },
+    { "vcvtp%XH2w",     { XM, EXxh, EXxEVexR }, 0 },
+    { "vcvtuw2p%XH",    { XM, EXxh, EXxEVexR }, 0 },
   },
   /* PREFIX_EVEX_MAP6_13 */
   {
-    { VEX_W_TABLE (EVEX_W_MAP6_13_P_0) },
+    { "vcvts%XH2ss",   { XMM, VexScalar, EXw, EXxEVexS }, 0 },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_MAP6_13_P_2) },
+    { "vcvtp%XH2psx",  { XM, EXxmmqh, EXxEVexS }, 0 },
   },
   /* PREFIX_EVEX_MAP6_56 */
   {
index 62c3d3b9afbb301232138dc5dc43cd7f71eefbd8..fc0a0791d1d5ca1b322162af5724559f12e898ac 100644 (file)
     { Bad_Opcode },
     { "vpermilpd",     { XM, EXx, Ib }, PREFIX_DATA },
   },
-  /* EVEX_W_0F3A08 */
-  {
-    { PREFIX_TABLE (PREFIX_EVEX_0F3A08_W_0) },
-  },
   /* EVEX_W_0F3A09 */
   {
     { Bad_Opcode },
     { "vrndscalepd",   { XM, EXx, EXxEVexS, Ib }, PREFIX_DATA },
   },
-  /* EVEX_W_0F3A0A */
-  {
-    { PREFIX_TABLE (PREFIX_EVEX_0F3A0A_W_0) },
-  },
   /* EVEX_W_0F3A0B */
   {
     { Bad_Opcode },
     { Bad_Opcode },
     { "vpshrdw",   { XM, Vex, EXx, Ib }, 0 },
   },
-  /* EVEX_W_MAP5_5A */
-  {
-    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A_W_0) },
-    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A_W_1) },
-  },
-  /* EVEX_W_MAP5_5B */
-  {
-    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B_W_0) },
-    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B_W_1) },
-  },
-  /* EVEX_W_MAP5_78_P_0 */
-  {
-    { "vcvttph2udq",   { XM, EXxmmqh, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_MAP5_78_P_2 */
-  {
-    { "vcvttph2uqq",   { XM, EXxmmqdh, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_MAP5_79_P_0 */
-  {
-    { "vcvtph2udq",    { XM, EXxmmqh, EXxEVexR }, 0 },
-  },
-  /* EVEX_W_MAP5_79_P_2 */
+  /* EVEX_W_MAP5_5B_P_0 */
   {
-    { "vcvtph2uqq",    { XM, EXxmmqdh, EXxEVexR }, 0 },
-  },
-  /* EVEX_W_MAP5_7A_P_2 */
-  {
-    { "vcvttph2qq",    { XM, EXxmmqdh, EXxEVexS }, 0 },
+    { "vcvtdq2ph%XY",  { XMxmmq, EXx, EXxEVexR }, 0 },
+    { "vcvtqq2ph%XZ",  { XMM, EXx, EXxEVexR }, 0 },
   },
   /* EVEX_W_MAP5_7A_P_3 */
   {
     { "vcvtudq2ph%XY", { XMxmmq, EXx, EXxEVexR }, 0 },
     { "vcvtuqq2ph%XZ", { XMM, EXx, EXxEVexR }, 0 },
   },
-  /* EVEX_W_MAP5_7B_P_2 */
-  {
-    { "vcvtph2qq",     { XM, EXxmmqdh, EXxEVexR }, 0 },
-  },
-  /* EVEX_W_MAP5_7C_P_0 */
-  {
-    { "vcvttph2uw",    { XM, EXxh, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_MAP5_7C_P_2 */
-  {
-    { "vcvttph2w",     { XM, EXxh, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_MAP5_7D */
-  {
-    { PREFIX_TABLE (PREFIX_EVEX_MAP5_7D_W_0) },
-  },
-  /* EVEX_W_MAP6_13_P_0 */
-  {
-    { "vcvtsh2ss",     { XMM, VexScalar, EXw, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_MAP6_13_P_2 */
-  {
-    { "vcvtph2psx",    { XM, EXxmmqh, EXxEVexS }, 0 },
-  },
index d79c78c17936226ce501d473ddc5f6bf443c88bd..11cc257bb2e3900e0146000940aadebb69d266f5 100644 (file)
@@ -593,9 +593,9 @@ static const struct dis386 evex_table[][256] = {
     { Bad_Opcode },
     { Bad_Opcode },
     /* 08 */
-    { VEX_W_TABLE (EVEX_W_0F3A08) },
+    { PREFIX_TABLE (PREFIX_EVEX_0F3A08) },
     { VEX_W_TABLE (EVEX_W_0F3A09) },
-    { VEX_W_TABLE (EVEX_W_0F3A0A) },
+    { PREFIX_TABLE (PREFIX_EVEX_0F3A0A) },
     { VEX_W_TABLE (EVEX_W_0F3A0B) },
     { Bad_Opcode },
     { Bad_Opcode },
@@ -976,8 +976,8 @@ static const struct dis386 evex_table[][256] = {
     /* 58 */
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_58) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_59) },
-    { VEX_W_TABLE (EVEX_W_MAP5_5A) },
-    { VEX_W_TABLE (EVEX_W_MAP5_5B) },
+    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5A) },
+    { PREFIX_TABLE (PREFIX_EVEX_MAP5_5B) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_5C) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_5D) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_5E) },
@@ -1015,7 +1015,7 @@ static const struct dis386 evex_table[][256] = {
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_7A) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_7B) },
     { PREFIX_TABLE (PREFIX_EVEX_MAP5_7C) },
-    { VEX_W_TABLE (EVEX_W_MAP5_7D) },
+    { PREFIX_TABLE (PREFIX_EVEX_MAP5_7D) },
     { "vmovw",   { Edw, XMScalar }, PREFIX_DATA },
     { Bad_Opcode },
     /* 80 */
index 4e0e1559339d32d356a875bc55b453d2250dbfb9..afc3743e4e8fa5c17d8751385c22d2379f106218 100644 (file)
@@ -1212,8 +1212,8 @@ enum
   PREFIX_EVEX_0F38AA,
   PREFIX_EVEX_0F38AB,
 
-  PREFIX_EVEX_0F3A08_W_0,
-  PREFIX_EVEX_0F3A0A_W_0,
+  PREFIX_EVEX_0F3A08,
+  PREFIX_EVEX_0F3A0A,
   PREFIX_EVEX_0F3A26,
   PREFIX_EVEX_0F3A27,
   PREFIX_EVEX_0F3A56,
@@ -1233,10 +1233,8 @@ enum
   PREFIX_EVEX_MAP5_51,
   PREFIX_EVEX_MAP5_58,
   PREFIX_EVEX_MAP5_59,
-  PREFIX_EVEX_MAP5_5A_W_0,
-  PREFIX_EVEX_MAP5_5A_W_1,
-  PREFIX_EVEX_MAP5_5B_W_0,
-  PREFIX_EVEX_MAP5_5B_W_1,
+  PREFIX_EVEX_MAP5_5A,
+  PREFIX_EVEX_MAP5_5B,
   PREFIX_EVEX_MAP5_5C,
   PREFIX_EVEX_MAP5_5D,
   PREFIX_EVEX_MAP5_5E,
@@ -1246,7 +1244,7 @@ enum
   PREFIX_EVEX_MAP5_7A,
   PREFIX_EVEX_MAP5_7B,
   PREFIX_EVEX_MAP5_7C,
-  PREFIX_EVEX_MAP5_7D_W_0,
+  PREFIX_EVEX_MAP5_7D,
 
   PREFIX_EVEX_MAP6_13,
   PREFIX_EVEX_MAP6_56,
@@ -1746,9 +1744,7 @@ enum
   EVEX_W_0F3883,
 
   EVEX_W_0F3A05,
-  EVEX_W_0F3A08,
   EVEX_W_0F3A09,
-  EVEX_W_0F3A0A,
   EVEX_W_0F3A0B,
   EVEX_W_0F3A18_L_n,
   EVEX_W_0F3A19_L_n,
@@ -1765,21 +1761,8 @@ enum
   EVEX_W_0F3A70,
   EVEX_W_0F3A72,
 
-  EVEX_W_MAP5_5A,
-  EVEX_W_MAP5_5B,
-  EVEX_W_MAP5_78_P_0,
-  EVEX_W_MAP5_78_P_2,
-  EVEX_W_MAP5_79_P_0,
-  EVEX_W_MAP5_79_P_2,
-  EVEX_W_MAP5_7A_P_2,
+  EVEX_W_MAP5_5B_P_0,
   EVEX_W_MAP5_7A_P_3,
-  EVEX_W_MAP5_7B_P_2,
-  EVEX_W_MAP5_7C_P_0,
-  EVEX_W_MAP5_7C_P_2,
-  EVEX_W_MAP5_7D,
-
-  EVEX_W_MAP6_13_P_0,
-  EVEX_W_MAP6_13_P_2,
 };
 
 typedef void (*op_rtn) (instr_info *ins, int bytemode, int sizeflag);
@@ -1840,7 +1823,9 @@ struct dis386 {
    "XZ" => print 'x', 'y', or 'z' if suffix_always is true or no
           register operands and no broadcast.
    "XW" => print 's', 'd' depending on the VEX.W bit (for FMA)
+   "XD" => print 'd' if EVEX.W=1, EVEX.W=0 is not a valid encoding
    "XH" => print 'h' if EVEX.W=0, EVEX.W=1 is not a valid encoding (for FP16)
+   "XS" => print 's' if EVEX.W=0, EVEX.W=1 is not a valid encoding
    "XV" => print "{vex3}" pseudo prefix
    "LQ" => print 'l' ('d' in Intel mode) or 'q' for memory operand, cond
           being false, or no operand at all in 64bit mode, or if suffix_always
@@ -10496,6 +10481,23 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
            }
          break;
        case 'D':
+         if (l == 1)
+           {
+             switch (last[0])
+             {
+             case 'X':
+               if (ins->vex.w)
+                 *ins->obufp++ = 'd';
+               else
+                 oappend (ins, "{bad}");
+               break;
+             default:
+               abort ();
+             }
+             break;
+           }
+         if (l)
+           abort ();
          if (ins->intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
            break;
          USED_REX (REX_W);
@@ -10582,13 +10584,7 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
              if (ins->vex.w == 0)
                *ins->obufp++ = 'h';
              else
-               {
-                 *ins->obufp++ = '{';
-                 *ins->obufp++ = 'b';
-                 *ins->obufp++ = 'a';
-                 *ins->obufp++ = 'd';
-                 *ins->obufp++ = '}';
-               }
+               oappend (ins, "{bad}");
            }
          else
            abort ();
@@ -10752,9 +10748,13 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
                      ins->used_prefixes |= (ins->prefixes & PREFIX_DATA);
                    }
                }
+             break;
            }
-         else if (l == 1 && last[0] == 'L')
+         if (l != 1)
+           abort ();
+         switch (last[0])
            {
+           case 'L':
              if (ins->address_mode == mode_64bit
                  && !(ins->prefixes & PREFIX_ADDR))
                {
@@ -10764,9 +10764,15 @@ putop (instr_info *ins, const char *in_template, int sizeflag)
                }
 
              goto case_S;
+           case 'X':
+             if (!ins->vex.w)
+               *ins->obufp++ = 's';
+             else
+               oappend (ins, "{bad}");
+             break;
+           default:
+             abort ();
            }
-         else
-           abort ();
          break;
        case 'V':
          if (l == 0)