[10/11] x86: use %LW / %XW instead of going through vex_w_table[]

Message ID 8183300d-d10a-e920-10b4-6037b9c912e1@suse.com
State New
Headers show
Series
  • x86: disassembler size reduction and fixes
Related show

Commit Message

Jan Beulich July 3, 2020, 1:56 p.m.
Since we have these macros, there's no point having unnecessary table
depth.

VFPCLASSP{S,D} are now the first instance of using two %-prefixed
macros, which has pointed out a problem with the implementation. Instead
of using custom code in various case blocks, do the macro accumulation
centralized at the top of the main loop of putop(), and zap the
accumulated macros at the bottom of that loop once it has been
processed.

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

	* i386-dis.c (EVEX_W_0F3838_P_1,
	EVEX_W_0F3839_P_1, EVEX_W_0F3840_P_2, EVEX_W_0F3855_P_2,
	EVEX_W_0F3868_P_3, EVEX_W_0F3871_P_2, EVEX_W_0F3873_P_2,
	EVEX_W_0F3A50_P_2, EVEX_W_0F3A51_P_2, EVEX_W_0F3A56_P_2,
	EVEX_W_0F3A57_P_2, EVEX_W_0F3A66_P_2, EVEX_W_0F3A67_P_2,
	EVEX_W_0F3A71_P_2, EVEX_W_0F3A73_P_2): Delete.
	(putop): Centralize management of last[]. Delete SAVE_LAST.
	* i386-dis-evex-w.h: Move entries for opcodes 0F3838, 0F3839,
	0F3840, 0F3855, 0F3868, 0F3871, 0F3873, 0F3A50, 0F3A51, 0F3A56,
	0F3A57, 0F3A66, 0F3A67,	0F3A71, and 0F3A73 ...
	* i386-dis-evex-prefix.h: here.

Patch

--- a/opcodes/i386-dis-evex-prefix.h
+++ b/opcodes/i386-dis-evex-prefix.h
@@ -564,13 +564,13 @@ 
   /* PREFIX_EVEX_0F3838 */
   {
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3838_P_1) },
+    { "vpmovm2%LW",	{ XM, MaskR }, 0 },
     { "vpminsb",	{ XM, Vex, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F3839 */
   {
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3839_P_1) },
+    { "vpmov%LW2m",	{ XMask, EXx }, 0 },
     { "vpmins%LW",	{ XM, Vex, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F383A */
@@ -601,7 +601,7 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3840_P_2) },
+    { "vpmull%LW",	{ XM, Vex, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F3842 */
   {
@@ -699,7 +699,7 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3855_P_2) },
+    { "vpopcnt%LW",	{ XM, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F3859 */
   {
@@ -754,7 +754,7 @@ 
     { Bad_Opcode },
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3868_P_3) },
+    { "vp2intersect%LW", { XMask, Vex, EXx, EXxEVexS }, 0 },
   },
   /* PREFIX_EVEX_0F3870 */
   {
@@ -766,7 +766,7 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3871_P_2) },
+    { "vpshldv%LW",  { XM, Vex, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F3872 */
   {
@@ -779,7 +779,7 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3873_P_2) },
+    { "vpshrdv%LW",  { XM, Vex, EXx }, 0 },
   },
   /* PREFIX_EVEX_0F3875 */
   {
@@ -1251,13 +1251,13 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A50_P_2) },
+    { "vrangep%XW",	{ XM, Vex, EXx, EXxEVexS, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A51 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A51_P_2) },
+    { "vranges%XW",	{ XMScalar, VexScalar, EXVexWdqScalar, EXxEVexS, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A54 */
   {
@@ -1275,25 +1275,25 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A56_P_2) },
+    { "vreducep%XW",	{ XM, EXx, EXxEVexS, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A57 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A57_P_2) },
+    { "vreduces%XW",	{ XMScalar, VexScalar, EXVexWdqScalar, EXxEVexS, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A66 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A66_P_2) },
+    { "vfpclassp%XW%XZ",	{ XMask, EXx, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A67 */
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A67_P_2) },
+    { "vfpclasss%XW",	{ XMask, EXVexWdqScalar, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A70 */
   {
@@ -1305,7 +1305,7 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A71_P_2) },
+    { "vpshld%LW",   { XM, Vex, EXx, Ib }, 0 },
   },
   /* PREFIX_EVEX_0F3A72 */
   {
@@ -1317,5 +1317,5 @@ 
   {
     { Bad_Opcode },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F3A73_P_2) },
+    { "vpshrd%LW",   { XM, Vex, EXx, Ib }, 0 },
   },
--- a/opcodes/i386-dis-evex-w.h
+++ b/opcodes/i386-dis-evex-w.h
@@ -518,25 +518,10 @@ 
     { Bad_Opcode },
     { "vpcmpgtq",	{ XMask, Vex, EXx }, 0 },
   },
-  /* EVEX_W_0F3838_P_1 */
-  {
-    { "vpmovm2d",	{ XM, MaskR }, 0 },
-    { "vpmovm2q",	{ XM, MaskR }, 0 },
-  },
-  /* EVEX_W_0F3839_P_1 */
-  {
-    { "vpmovd2m",	{ XMask, EXx }, 0 },
-    { "vpmovq2m",	{ XMask, EXx }, 0 },
-  },
   /* EVEX_W_0F383A_P_1 */
   {
     { "vpbroadcastmw2d",	{ XM, MaskR }, 0 },
   },
-  /* EVEX_W_0F3840_P_2 */
-  {
-    { "vpmulld",	{ XM, Vex, EXx }, 0 },
-    { "vpmullq",	{ XM, Vex, EXx }, 0 },
-  },
   /* EVEX_W_0F3852_P_1 */
   {
     { "vdpbf16ps",	{ XM, Vex, EXx }, 0 },
@@ -547,11 +532,6 @@ 
     { "vpopcntb",	{ XM, EXx }, 0 },
     { "vpopcntw",	{ XM, EXx }, 0 },
   },
-  /* EVEX_W_0F3855_P_2 */
-  {
-    { "vpopcntd",	{ XM, EXx }, 0 },
-    { "vpopcntq",	{ XM, EXx }, 0 },
-  },
   /* EVEX_W_0F3859_P_2 */
   {
     { "vbroadcasti32x2",	{ XM, EXxmm_mq }, 0 },
@@ -582,21 +562,11 @@ 
     { "vpblendmb",	{ XM, Vex, EXx }, 0 },
     { "vpblendmw",	{ XM, Vex, EXx }, 0 },
   },
-  /* EVEX_W_0F3868_P_3 */
-  {
-    { "vp2intersectd", { XMask, Vex, EXx, EXxEVexS }, 0 },
-    { "vp2intersectq", { XMask, Vex, EXx, EXxEVexS }, 0 },
-  },
   /* EVEX_W_0F3870_P_2 */
   {
     { Bad_Opcode },
     { "vpshldvw",  { XM, Vex, EXx }, 0 },
   },
-  /* EVEX_W_0F3871_P_2 */
-  {
-    { "vpshldvd",  { XM, Vex, EXx }, 0 },
-    { "vpshldvq",  { XM, Vex, EXx }, 0 },
-  },
   /* EVEX_W_0F3872_P_1 */
   {
     { "vcvtneps2bf16%XY", { XMxmmq, EXx }, 0 },
@@ -612,11 +582,6 @@ 
     { "vcvtne2ps2bf16", { XM, Vex, EXx}, 0 },
     { Bad_Opcode },
   },
-  /* EVEX_W_0F3873_P_2 */
-  {
-    { "vpshrdvd",  { XM, Vex, EXx }, 0 },
-    { "vpshrdvq",  { XM, Vex, EXx }, 0 },
-  },
   /* EVEX_W_0F3875_P_2 */
   {
     { "vpermi2b",	{ XM, Vex, EXx }, 0 },
@@ -786,53 +751,13 @@ 
     { EVEX_LEN_TABLE (EVEX_LEN_0F3A43_P_2_W_0) },
     { EVEX_LEN_TABLE (EVEX_LEN_0F3A43_P_2_W_1) },
   },
-  /* EVEX_W_0F3A50_P_2 */
-  {
-    { "vrangeps",	{ XM, Vex, EXx, EXxEVexS, Ib }, 0 },
-    { "vrangepd",	{ XM, Vex, EXx, EXxEVexS, Ib }, 0 },
-  },
-  /* EVEX_W_0F3A51_P_2 */
-  {
-    { "vrangess",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexS, Ib }, 0 },
-    { "vrangesd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexS, Ib }, 0 },
-  },
-  /* EVEX_W_0F3A56_P_2 */
-  {
-    { "vreduceps",	{ XM, EXx, EXxEVexS, Ib }, 0 },
-    { "vreducepd",	{ XM, EXx, EXxEVexS, Ib }, 0 },
-  },
-  /* EVEX_W_0F3A57_P_2 */
-  {
-    { "vreducess",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexS, Ib }, 0 },
-    { "vreducesd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexS, Ib }, 0 },
-  },
-  /* EVEX_W_0F3A66_P_2 */
-  {
-    { "vfpclassps%XZ",	{ XMask, EXx, Ib }, 0 },
-    { "vfpclasspd%XZ",	{ XMask, EXx, Ib }, 0 },
-  },
-  /* EVEX_W_0F3A67_P_2 */
-  {
-    { "vfpclassss",	{ XMask, EXxmm_md, Ib }, 0 },
-    { "vfpclasssd",	{ XMask, EXxmm_mq, Ib }, 0 },
-  },
   /* EVEX_W_0F3A70_P_2 */
   {
     { Bad_Opcode },
     { "vpshldw",   { XM, Vex, EXx, Ib }, 0 },
   },
-  /* EVEX_W_0F3A71_P_2 */
-  {
-    { "vpshldd",   { XM, Vex, EXx, Ib }, 0 },
-    { "vpshldq",   { XM, Vex, EXx, Ib }, 0 },
-  },
   /* EVEX_W_0F3A72_P_2 */
   {
     { Bad_Opcode },
     { "vpshrdw",   { XM, Vex, EXx, Ib }, 0 },
   },
-  /* EVEX_W_0F3A73_P_2 */
-  {
-    { "vpshrdd",   { XM, Vex, EXx, Ib }, 0 },
-    { "vpshrdq",   { XM, Vex, EXx, Ib }, 0 },
-  },
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -2071,26 +2071,19 @@  enum
   EVEX_W_0F3835_P_1,
   EVEX_W_0F3835_P_2,
   EVEX_W_0F3837_P_2,
-  EVEX_W_0F3838_P_1,
-  EVEX_W_0F3839_P_1,
   EVEX_W_0F383A_P_1,
-  EVEX_W_0F3840_P_2,
   EVEX_W_0F3852_P_1,
   EVEX_W_0F3854_P_2,
-  EVEX_W_0F3855_P_2,
   EVEX_W_0F3859_P_2,
   EVEX_W_0F385A_P_2,
   EVEX_W_0F385B_P_2,
   EVEX_W_0F3862_P_2,
   EVEX_W_0F3863_P_2,
   EVEX_W_0F3866_P_2,
-  EVEX_W_0F3868_P_3,
   EVEX_W_0F3870_P_2,
-  EVEX_W_0F3871_P_2,
   EVEX_W_0F3872_P_1,
   EVEX_W_0F3872_P_2,
   EVEX_W_0F3872_P_3,
-  EVEX_W_0F3873_P_2,
   EVEX_W_0F3875_P_2,
   EVEX_W_0F387A_P_2,
   EVEX_W_0F387B_P_2,
@@ -2127,16 +2120,8 @@  enum
   EVEX_W_0F3A3F_P_2,
   EVEX_W_0F3A42_P_2,
   EVEX_W_0F3A43_P_2,
-  EVEX_W_0F3A50_P_2,
-  EVEX_W_0F3A51_P_2,
-  EVEX_W_0F3A56_P_2,
-  EVEX_W_0F3A57_P_2,
-  EVEX_W_0F3A66_P_2,
-  EVEX_W_0F3A67_P_2,
   EVEX_W_0F3A70_P_2,
-  EVEX_W_0F3A71_P_2,
   EVEX_W_0F3A72_P_2,
-  EVEX_W_0F3A73_P_2,
 };
 
 typedef void (*op_rtn) (int bytemode, int sizeflag);
@@ -12626,17 +12611,18 @@  putop (const char *in_template, int size
   const char *p;
   int alt = 0;
   int cond = 1;
-  unsigned int l = 0, len = 1;
+  unsigned int l = 0, len = 0;
   char last[4];
 
-#define SAVE_LAST(c)			\
-  if (l < len && l < sizeof (last))	\
-    last[l++] = c;			\
-  else					\
-    abort ();
-
   for (p = in_template; *p; p++)
     {
+      if (len > l)
+	{
+	  if (l >= sizeof (last) || !ISUPPER (*p))
+	    abort ();
+	  last[l++] = *p;
+	  continue;
+	}
       switch (*p)
 	{
 	default:
@@ -12674,7 +12660,7 @@  putop (const char *in_template, int size
 	    *obufp++ = 'b';
 	  break;
 	case 'B':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	    case_B:
 	      if (intel_syntax)
@@ -12682,16 +12668,8 @@  putop (const char *in_template, int size
 	      if (sizeflag & SUFFIX_ALWAYS)
 		*obufp++ = 'b';
 	    }
-	  else
+	  else if (l == 1 && last[0] == 'L')
 	    {
-	      if (l != 1
-		  || len != 2
-		  || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
-
 	      if (address_mode == mode_64bit
 		  && !(prefixes & PREFIX_ADDR))
 		{
@@ -12702,6 +12680,8 @@  putop (const char *in_template, int size
 
 	      goto case_B;
 	    }
+	  else
+	    abort ();
 	  break;
 	case 'C':
 	  if (intel_syntax && !alt)
@@ -12793,13 +12773,10 @@  putop (const char *in_template, int size
 	    *obufp++ = 'd';
 	  break;
 	case 'Z':
-	  if (l != 0 || len != 1)
+	  if (l != 0)
 	    {
-	      if (l != 1 || len != 2 || last[0] != 'X')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
+	      if (l != 1 || last[0] != 'X')
+		abort ();
 	      if (!need_vex || !vex.evex)
 		abort ();
 	      if (intel_syntax
@@ -12831,11 +12808,8 @@  putop (const char *in_template, int size
 	  /* Fall through.  */
 	  goto case_L;
 	case 'L':
-	  if (l != 0 || len != 1)
-	    {
-	      SAVE_LAST (*p);
-	      break;
-	    }
+	  if (l != 0)
+	    abort ();
 	case_L:
 	  if (intel_syntax)
 	    break;
@@ -12883,7 +12857,7 @@  putop (const char *in_template, int size
 	  /* Fall through.  */
 	  goto case_P;
 	case 'P':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	    case_P:
 	      if (intel_syntax)
@@ -12914,14 +12888,8 @@  putop (const char *in_template, int size
 		    }
 		}
 	    }
-	  else
+	  else if (l == 1 && last[0] == 'L')
 	    {
-	      if (l != 1 || len != 2 || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
-
 	      if ((prefixes & PREFIX_DATA)
 		  || (rex & REX_W)
 		  || (sizeflag & SUFFIX_ALWAYS))
@@ -12939,6 +12907,8 @@  putop (const char *in_template, int size
 		    }
 		}
 	    }
+	  else
+	    abort ();
 	  break;
 	case 'U':
 	  if (intel_syntax)
@@ -12953,7 +12923,7 @@  putop (const char *in_template, int size
 	  /* Fall through.  */
 	  goto case_Q;
 	case 'Q':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	    case_Q:
 	      if (intel_syntax && !alt)
@@ -12973,13 +12943,8 @@  putop (const char *in_template, int size
 		    }
 		}
 	    }
-	  else
+	  else if (l == 1 && last[0] == 'L')
 	    {
-	      if (l != 1 || len != 2 || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
 	      if ((intel_syntax && need_modrm)
 		  || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS)))
 		break;
@@ -12992,6 +12957,8 @@  putop (const char *in_template, int size
 		      || (sizeflag & SUFFIX_ALWAYS))
 		*obufp++ = intel_syntax? 'd' : 'l';
 	    }
+	  else
+	    abort ();
 	  break;
 	case 'R':
 	  USED_REX (REX_W);
@@ -13013,7 +12980,7 @@  putop (const char *in_template, int size
 	    used_prefixes |= (prefixes & PREFIX_DATA);
 	  break;
 	case 'V':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	      if (intel_syntax)
 		break;
@@ -13025,16 +12992,8 @@  putop (const char *in_template, int size
 		  break;
 		}
 	    }
-	  else
+	  else if (l == 1 && last[0] == 'L')
 	    {
-	      if (l != 1
-		  || len != 2
-		  || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
-
 	      if (rex & REX_W)
 		{
 		  *obufp++ = 'a';
@@ -13042,10 +13001,12 @@  putop (const char *in_template, int size
 		  *obufp++ = 's';
 		}
 	    }
+	  else
+	    abort ();
 	  /* Fall through.  */
 	  goto case_S;
 	case 'S':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	    case_S:
 	      if (intel_syntax)
@@ -13064,16 +13025,8 @@  putop (const char *in_template, int size
 		    }
 		}
 	    }
-	  else
+	  else if (l == 1 && last[0] == 'L')
 	    {
-	      if (l != 1
-		  || len != 2
-		  || last[0] != 'L')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
-
 	      if (address_mode == mode_64bit
 		  && !(prefixes & PREFIX_ADDR))
 		{
@@ -13084,13 +13037,12 @@  putop (const char *in_template, int size
 
 	      goto case_S;
 	    }
+	  else
+	    abort ();
 	  break;
 	case 'X':
-	  if (l != 0 || len != 1)
-	    {
-	      SAVE_LAST (*p);
-	      break;
-	    }
+	  if (l != 0)
+	    abort ();
 	  if (need_vex
 	      ? vex.prefix == DATA_PREFIX_OPCODE
 	      : prefixes & PREFIX_DATA)
@@ -13102,15 +13054,8 @@  putop (const char *in_template, int size
 	    *obufp++ = 's';
 	  break;
 	case 'Y':
-	  if (l == 0 && len == 1)
-	    abort ();
-	  else
+	  if (l == 1 && last[0] == 'X')
 	    {
-	      if (l != 1 || len != 2 || last[0] != 'X')
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
 	      if (!need_vex)
 		abort ();
 	      if (intel_syntax
@@ -13130,9 +13075,11 @@  putop (const char *in_template, int size
 		    abort ();
 		}
 	    }
+	  else
+	    abort ();
 	  break;
 	case 'W':
-	  if (l == 0 && len == 1)
+	  if (l == 0)
 	    {
 	      /* operand size flag for cwtl, cbtw */
 	      USED_REX (REX_W);
@@ -13150,23 +13097,19 @@  putop (const char *in_template, int size
 	      if (!(rex & REX_W))
 		used_prefixes |= (prefixes & PREFIX_DATA);
 	    }
-	  else
+	  else if (l == 1)
 	    {
-	      if (l != 1
-		  || len != 2
-		  || (last[0] != 'X'
-		      && last[0] != 'L'))
-		{
-		  SAVE_LAST (*p);
-		  break;
-		}
 	      if (!need_vex)
 		abort ();
 	      if (last[0] == 'X')
 		*obufp++ = vex.w ? 'd': 's';
-	      else
+	      else if (last[0] == 'L')
 		*obufp++ = vex.w ? 'q': 'd';
+	      else
+		abort ();
 	    }
+	  else
+	    abort ();
 	  break;
 	case '^':
 	  if (intel_syntax)
@@ -13201,6 +13144,9 @@  putop (const char *in_template, int size
 	    }
 	  break;
 	}
+
+      if (len == l)
+	len = l = 0;
     }
   *obufp = 0;
   mnemonicendp = obufp;