public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments
@ 2020-06-08  7:42 Jan Beulich
  2020-06-08  7:44 ` [PATCH 1/5] x86: correct mis-named MOD_0F51 enumerator Jan Beulich
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:42 UTC (permalink / raw)
  To: binutils

1: correct mis-named MOD_0F51 enumerator
2: correct decoding of packed-FP-only AVX encodings
3: utilize X macro in EVEX decoding
4: fix {,V}MOV{L,H}PD disassembly
5: consistently print prefixes explicitly which are invalid with VEX etc

Jan

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] x86: correct mis-named MOD_0F51 enumerator
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
@ 2020-06-08  7:44 ` Jan Beulich
  2020-06-08  7:45 ` [PATCH 2/5] x86: correct decoding of packed-FP-only AVX encodings Jan Beulich
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:44 UTC (permalink / raw)
  To: binutils

This is for extension major opcode 50, so name it accordingly.

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

	* i386-dis.c (MOD_0F51): Rename to ...
	(MOD_0F50): ... this.

--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -800,7 +800,7 @@ enum
   MOD_0F2B_PREFIX_1,
   MOD_0F2B_PREFIX_2,
   MOD_0F2B_PREFIX_3,
-  MOD_0F51,
+  MOD_0F50,
   MOD_0F71_REG_2,
   MOD_0F71_REG_4,
   MOD_0F71_REG_6,
@@ -2746,7 +2746,7 @@ static const struct dis386 dis386_twobyt
   { "cmovleS",		{ Gv, Ev }, 0 },
   { "cmovgS",		{ Gv, Ev }, 0 },
   /* 50 */
-  { MOD_TABLE (MOD_0F51) },
+  { MOD_TABLE (MOD_0F50) },
   { PREFIX_TABLE (PREFIX_0F51) },
   { PREFIX_TABLE (PREFIX_0F52) },
   { PREFIX_TABLE (PREFIX_0F53) },
@@ -10384,7 +10384,7 @@ static const struct dis386 mod_table[][2
     {"movntsd",		{ Mq, XM }, PREFIX_OPCODE },
   },
   {
-    /* MOD_0F51 */
+    /* MOD_0F50 */
     { Bad_Opcode },
     { "movmskpX",	{ Gdq, XS }, PREFIX_OPCODE },
   },


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/5] x86: correct decoding of packed-FP-only AVX encodings
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
  2020-06-08  7:44 ` [PATCH 1/5] x86: correct mis-named MOD_0F51 enumerator Jan Beulich
@ 2020-06-08  7:45 ` Jan Beulich
  2020-06-08  7:45 ` [PATCH 3/5] x86: utilize X macro in EVEX decoding Jan Beulich
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:45 UTC (permalink / raw)
  To: binutils

Various AVX insns utilizing the X macro fail to reject F3/F2 embedded
prefix encodings. As the PREFIX_OPCODE attribute wasn't used by any
non-legacy-encoded insns so far, re-use it to achieve the intended
effect.

gas/
2020-06-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/prefix.s: Add bogus REP / EVEX.W prefix
	with VEX/EVEX encoding tests.
	* testsuite/gas/i386/prefix.d: Adjust expectations.

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

	* i386-dis.c (vex_table): Use PREFIX_OPCODE for vunpcklpX,
	vunpckhpX, vmovapX, vandpX, vandnpX, vorpX, vxorpX and vshufpX.
	(vex_len_table) : Likewise for vmovlpX, vmovhpX, vmovntpX, and
	vmovmskpX.
	(print_insn): Drop pointless check against bad_opcode. Split
	prefix validation into legacy and VEX-and-alike parts.
	(putop): Re-work 'X' macro handling.

---
This could in principle be used to significantly decrease table sizes
by making AVX extensions of originally MMX insns (encoded with an
embedded 66 prefix), by introducing a suitable macro and avoiding the
need for the various respective PREFIX_* enumerators / indirections.

--- a/gas/testsuite/gas/i386/prefix.d
+++ b/gas/testsuite/gas/i386/prefix.d
@@ -72,6 +72,20 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	90                   	nop
 [ 	]*[a-f0-9]+:	f2 0f c7             	\(bad\)  
 [ 	]*[a-f0-9]+:	f0 90                	lock nop
+[ 	]*[a-f0-9]+:	f3 0f 28             	repz \(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	c5 fa 28             	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	c4 e1 7b 28          	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	62 f1 fc 08 28       	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	62 f1 7e 08 28       	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	62 f1 7d 08 28       	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	62 f1 ff 08 28       	\(bad\) *
+[ 	]*[a-f0-9]+:	ff cc                	dec    %esp
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
 [ 	]*[a-f0-9]+:	62 f1 ff 18 e6 40 04 	vcvtpd2dq 0x20\(%eax\)\{1to2\},%xmm0
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
--- a/gas/testsuite/gas/i386/prefix.s
+++ b/gas/testsuite/gas/i386/prefix.s
@@ -391,6 +391,66 @@
 
 	nop
 
+	repz; movaps %xmm7, %xmm7
+	int $3
+
+# "repz" vmovaps %xmm7, %xmm7
+	.byte 0xc5
+	.byte 0xfa
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
+# "repnz" {vex3} vmovaps %xmm7, %xmm7
+	.byte 0xc4
+	.byte 0xe1
+	.byte 0x7b
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
+# "EVEX.W1" vmovaps %xmm7, %xmm7
+	.byte 0x62
+	.byte 0xf1
+	.byte 0xfc
+	.byte 0x08
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
+# "repz" vmovaps %xmm7, %xmm7
+	.byte 0x62
+	.byte 0xf1
+	.byte 0x7e
+	.byte 0x08
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
+# "EVEX.W0" vmovapd %xmm7, %xmm7
+	.byte 0x62
+	.byte 0xf1
+	.byte 0x7d
+	.byte 0x08
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
+# "repnz" vmovapd %xmm7, %xmm7
+	.byte 0x62
+	.byte 0xf1
+	.byte 0xff
+	.byte 0x08
+	.byte 0x28
+	.byte 0xff
+
+	int $3
+
 	vcvtpd2dqx 0x20(%eax),%xmm0
 	vcvtpd2dq 0x20(%eax){1to2},%xmm0
 	vcvtpd2dqx 0x20(%eax),%xmm0
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -8485,8 +8485,8 @@ static const struct dis386 vex_table[][2
     { PREFIX_TABLE (PREFIX_VEX_0F11) },
     { PREFIX_TABLE (PREFIX_VEX_0F12) },
     { MOD_TABLE (MOD_VEX_0F13) },
-    { "vunpcklpX",	{ XM, Vex, EXx }, 0 },
-    { "vunpckhpX",	{ XM, Vex, EXx }, 0 },
+    { "vunpcklpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vunpckhpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_VEX_0F16) },
     { MOD_TABLE (MOD_VEX_0F17) },
     /* 18 */
@@ -8508,8 +8508,8 @@ static const struct dis386 vex_table[][2
     { Bad_Opcode },
     { Bad_Opcode },
     /* 28 */
-    { "vmovapX",	{ XM, EXx }, 0 },
-    { "vmovapX",	{ EXxS, XM }, 0 },
+    { "vmovapX",	{ XM, EXx }, PREFIX_OPCODE },
+    { "vmovapX",	{ EXxS, XM }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_VEX_0F2A) },
     { MOD_TABLE (MOD_VEX_0F2B) },
     { PREFIX_TABLE (PREFIX_VEX_0F2C) },
@@ -8557,10 +8557,10 @@ static const struct dis386 vex_table[][2
     { PREFIX_TABLE (PREFIX_VEX_0F51) },
     { PREFIX_TABLE (PREFIX_VEX_0F52) },
     { PREFIX_TABLE (PREFIX_VEX_0F53) },
-    { "vandpX",		{ XM, Vex, EXx }, 0 },
-    { "vandnpX",	{ XM, Vex, EXx }, 0 },
-    { "vorpX",		{ XM, Vex, EXx }, 0 },
-    { "vxorpX",		{ XM, Vex, EXx }, 0 },
+    { "vandpX",		{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vandnpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vorpX",		{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vxorpX",		{ XM, Vex, EXx }, PREFIX_OPCODE },
     /* 58 */
     { PREFIX_TABLE (PREFIX_VEX_0F58) },
     { PREFIX_TABLE (PREFIX_VEX_0F59) },
@@ -8685,7 +8685,7 @@ static const struct dis386 vex_table[][2
     { Bad_Opcode },
     { PREFIX_TABLE (PREFIX_VEX_0FC4) },
     { PREFIX_TABLE (PREFIX_VEX_0FC5) },
-    { "vshufpX",	{ XM, Vex, EXx, Ib }, 0 },
+    { "vshufpX",	{ XM, Vex, EXx, Ib }, PREFIX_OPCODE },
     { Bad_Opcode },
     /* c8 */
     { Bad_Opcode },
@@ -9355,7 +9355,7 @@ static const struct dis386 vex_len_table
 
   /* VEX_LEN_0F13_M_0 */
   {
-    { "vmovlpX",	{ EXq, XM }, 0 },
+    { "vmovlpX",	{ EXq, XM }, PREFIX_OPCODE },
   },
 
   /* VEX_LEN_0F16_P_0_M_0 */
@@ -9375,7 +9375,7 @@ static const struct dis386 vex_len_table
 
   /* VEX_LEN_0F17_M_0 */
   {
-    { "vmovhpX",	{ EXq, XM }, 0 },
+    { "vmovhpX",	{ EXq, XM }, PREFIX_OPCODE },
   },
 
   /* VEX_LEN_0F41_P_0 */
@@ -10592,7 +10592,7 @@ static const struct dis386 mod_table[][2
   },
   {
     /* MOD_VEX_0F2B */
-    { "vmovntpX",	{ Mx, XM }, 0 },
+    { "vmovntpX",	{ Mx, XM }, PREFIX_OPCODE },
   },
   {
     /* MOD_VEX_W_0_0F41_P_0_LEN_1 */
@@ -10752,7 +10752,7 @@ static const struct dis386 mod_table[][2
   {
     /* MOD_VEX_0F50 */
     { Bad_Opcode },
-    { "vmovmskpX",	{ Gdq, XS }, 0 },
+    { "vmovmskpX",	{ Gdq, XS }, PREFIX_OPCODE },
   },
   {
     /* MOD_VEX_0F71_REG_2 */
@@ -12266,14 +12266,18 @@ print_insn (bfd_vma pc, disassemble_info
      PREFIX_REPZ/PREFIX_REPNZ fix, we check the PREFIX_DATA prefix
      separately.  */
   if (dp->prefix_requirement == PREFIX_OPCODE
-      && dp != &bad_opcode
-      && (((prefixes
-	    & (PREFIX_REPZ | PREFIX_REPNZ)) != 0
+      && (((need_vex
+	    ? vex.prefix == REPE_PREFIX_OPCODE
+	      || vex.prefix == REPNE_PREFIX_OPCODE
+	    : (prefixes
+	       & (PREFIX_REPZ | PREFIX_REPNZ)) != 0)
 	   && (used_prefixes
 	       & (PREFIX_REPZ | PREFIX_REPNZ)) == 0)
-	  || ((((prefixes
-		 & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
-		== PREFIX_DATA)
+	  || (((need_vex
+		? vex.prefix == DATA_PREFIX_OPCODE
+		: ((prefixes
+		    & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
+		   == PREFIX_DATA))
 	       && (used_prefixes & PREFIX_DATA) == 0))))
     {
       (*info->fprintf_func) (info->stream, "(bad)");
@@ -13230,21 +13234,15 @@ putop (const char *in_template, int size
 	      SAVE_LAST (*p);
 	      break;
 	    }
-	  if (need_vex && vex.prefix)
+	  if (need_vex
+	      ? vex.prefix == DATA_PREFIX_OPCODE
+	      : prefixes & PREFIX_DATA)
 	    {
-	      if (vex.prefix == DATA_PREFIX_OPCODE)
-		*obufp++ = 'd';
-	      else
-		*obufp++ = 's';
+	      *obufp++ = 'd';
+	      used_prefixes |= PREFIX_DATA;
 	    }
 	  else
-	    {
-	      if (prefixes & PREFIX_DATA)
-		*obufp++ = 'd';
-	      else
-		*obufp++ = 's';
-	      used_prefixes |= (prefixes & PREFIX_DATA);
-	    }
+	    *obufp++ = 's';
 	  break;
 	case 'Y':
 	  if (l == 0 && len == 1)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/5] x86: utilize X macro in EVEX decoding
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
  2020-06-08  7:44 ` [PATCH 1/5] x86: correct mis-named MOD_0F51 enumerator Jan Beulich
  2020-06-08  7:45 ` [PATCH 2/5] x86: correct decoding of packed-FP-only AVX encodings Jan Beulich
@ 2020-06-08  7:45 ` Jan Beulich
  2020-06-08  7:46 ` [PATCH 4/5] x86: fix {,V}MOV{L,H}PD disassembly Jan Beulich
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:45 UTC (permalink / raw)
  To: binutils

For major opcodes allowing only packed FP kinds of operands, i.e. the
ones where legacy and AVX decoding uses the X macro, we can do so for
AVX512 as well, by attaching to the checking logic the "EVEX.W must
match presence of embedded 66 prefix" rule. (Encodings not following
this general pattern simply may not gain the PREFIX_OPCODE attribute.)

Note that testing of the thus altered decoding has already been put in
place by "x86: correct decoding of packed-FP-only AVX encodings".

This can also be at least partly applied to scalar-FP-only insns (i.e.
V{,U}COMIS{S,D}) as well as the vector-FP forms of insns also allowing
scalar encodings (e.g. VADDP{S,D}).

Take the opportunity and also fix EVEX-encoded VMOVNTP{S,D} as well as
to-memory forms of VMOV{L,H}PS and both forms of VMOV{L,H}PD to wrongly
disassemble with only register operands.

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

	* i386-dis.c (MOD_EVEX_0F12_PREFIX_2, MOD_EVEX_0F13,
	MOD_EVEX_0F16_PREFIX_2, MOD_EVEX_0F17, MOD_EVEX_0F2B): New enumerators.
	(PREFIX_EVEX_0F13, PREFIX_EVEX_0F14, PREFIX_EVEX_0F15,
	PREFIX_EVEX_0F17, PREFIX_EVEX_0F28, PREFIX_EVEX_0F29,
	PREFIX_EVEX_0F2B, PREFIX_EVEX_0F54, PREFIX_EVEX_0F55,
	PREFIX_EVEX_0F56, PREFIX_EVEX_0F57, PREFIX_EVEX_0FC6,
	EVEX_W_0F10_P_0, EVEX_W_0F10_P_2, EVEX_W_0F11_P_0,
	EVEX_W_0F11_P_2, EVEX_W_0F12_P_0_M_0, EVEX_W_0F12_P_2,
	EVEX_W_0F13_P_0, EVEX_W_0F13_P_2, EVEX_W_0F14_P_0,
	EVEX_W_0F14_P_2, EVEX_W_0F15_P_0, EVEX_W_0F15_P_2,
	EVEX_W_0F16_P_0_M_0, EVEX_W_0F16_P_2, EVEX_W_0F17_P_0,
	EVEX_W_0F17_P_2, EVEX_W_0F28_P_0, EVEX_W_0F28_P_2,
	EVEX_W_0F29_P_0, EVEX_W_0F29_P_2, EVEX_W_0F2B_P_0,
	EVEX_W_0F2B_P_2, EVEX_W_0F2E_P_0, EVEX_W_0F2E_P_2,
	EVEX_W_0F2F_P_0, EVEX_W_0F2F_P_2, EVEX_W_0F51_P_0,
	EVEX_W_0F51_P_2, EVEX_W_0F54_P_0, EVEX_W_0F54_P_2,
	EVEX_W_0F55_P_0, EVEX_W_0F55_P_2, EVEX_W_0F56_P_0,
	EVEX_W_0F56_P_2, EVEX_W_0F57_P_0, EVEX_W_0F57_P_2,
	EVEX_W_0F58_P_0, EVEX_W_0F58_P_2, EVEX_W_0F59_P_0,
	EVEX_W_0F59_P_2, EVEX_W_0F5C_P_0, EVEX_W_0F5C_P_2,
	EVEX_W_0F5D_P_0, EVEX_W_0F5D_P_2, EVEX_W_0F5E_P_0,
	EVEX_W_0F5E_P_2, EVEX_W_0F5F_P_0, EVEX_W_0F5F_P_2,
	EVEX_W_0FC2_P_0, EVEX_W_0FC2_P_2, EVEX_W_0FC6_P_0,
	EVEX_W_0FC6_P_2): Delete.
	(print_insn): Add EVEX.W vs embedded prefix consistency check
	to prefix validation.
	* i386-dis-evex.h (evex_table): Don't further descend for
	vunpcklpX, vunpckhpX, vmovapX, vandpX, vandnpX, vorpX, vxorpX,
	and vshufpX. Continue with MOD decoding for opcodes 0F13, 0F17,
	and 0F2B.
	* i386-dis-evex-mod.h: Add/adjust vmovlpX/vmovhpX entries.
	* i386-dis-evex-prefix.h: Don't further descend for vmovupX,
	vucomisX, vcomisX, vsqrtpX, vaddpX, vmulpX, vsubpX, vminpX,
	vdivpX, vmaxpX, and vcmppX. Continue with MOD decoding for cases
	2 of PREFIX_EVEX_0F12, PREFIX_EVEX_0F16, and PREFIX_EVEX_0F29.
	Drop PREFIX_EVEX_0F13, PREFIX_EVEX_0F14, PREFIX_EVEX_0F15,
	PREFIX_EVEX_0F17, PREFIX_EVEX_0F28, PREFIX_EVEX_0F2B,
	PREFIX_EVEX_0F54, PREFIX_EVEX_0F55, PREFIX_EVEX_0F56,
	PREFIX_EVEX_0F57, and PREFIX_EVEX_0FC6 entries.
	* i386-dis-evex-w.h: Drop EVEX_W_0F10_P_0, EVEX_W_0F10_P_2,
	EVEX_W_0F11_P_0, EVEX_W_0F11_P_2, EVEX_W_0F12_P_0_M_0,
	EVEX_W_0F12_P_2, EVEX_W_0F12_P_3, EVEX_W_0F13_P_0,
	EVEX_W_0F13_P_2, EVEX_W_0F14_P_0, EVEX_W_0F14_P_2,
	EVEX_W_0F15_P_0, EVEX_W_0F15_P_2, EVEX_W_0F16_P_0_M_0,
	EVEX_W_0F16_P_2, EVEX_W_0F17_P_0, EVEX_W_0F17_P_2,
	EVEX_W_0F28_P_0, EVEX_W_0F28_P_2, EVEX_W_0F29_P_0,
	EVEX_W_0F29_P_2, EVEX_W_0F2B_P_0, EVEX_W_0F2B_P_2,
	EVEX_W_0F2E_P_0, EVEX_W_0F2E_P_2, EVEX_W_0F2F_P_0,
	EVEX_W_0F2F_P_2, EVEX_W_0F51_P_0, EVEX_W_0F51_P_2,
	EVEX_W_0F54_P_0, EVEX_W_0F54_P_2, EVEX_W_0F55_P_0,
	EVEX_W_0F55_P_2, EVEX_W_0F56_P_0, EVEX_W_0F56_P_2,
	EVEX_W_0F57_P_0, EVEX_W_0F57_P_2, EVEX_W_0F58_P_0,
	EVEX_W_0F58_P_2, EVEX_W_0F59_P_0, EVEX_W_0F59_P_2,
	EVEX_W_0F5C_P_0, EVEX_W_0F5C_P_2, EVEX_W_0F5D_P_0,
	EVEX_W_0F5D_P_2, EVEX_W_0F5E_P_0, EVEX_W_0F5E_P_2,
	EVEX_W_0F5F_P_0, EVEX_W_0F5F_P_2, EVEX_W_0FC2_P_0,
	EVEX_W_0FC2_P_2, EVEX_W_0FC6_P_0, and EVEX_W_0FC6_P_2 entries.

--- a/opcodes/i386-dis-evex-mod.h
+++ b/opcodes/i386-dis-evex-mod.h
@@ -1,14 +1,34 @@
   {
     /* MOD_EVEX_0F12_PREFIX_0 */
-    { VEX_W_TABLE (EVEX_W_0F12_P_0_M_0) },
+    { "vmovlpX",	{ XMM, Vex, EXxmm_mq }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F12_P_0_M_1) },
   },
   {
+    /* MOD_EVEX_0F12_PREFIX_2 */
+    { "vmovlpX",	{ XMM, Vex, EXxmm_mq }, PREFIX_OPCODE },
+  },
+  {
+    /* MOD_EVEX_0F13 */
+    { "vmovlpX",	{ EXxmm_mq, XMM }, PREFIX_OPCODE },
+  },
+  {
     /* MOD_EVEX_0F16_PREFIX_0 */
-    { VEX_W_TABLE (EVEX_W_0F16_P_0_M_0) },
+    { "vmovhpX",	{ XMM, Vex, EXxmm_mq }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F16_P_0_M_1) },
   },
   {
+    /* MOD_EVEX_0F16_PREFIX_2 */
+    { "vmovhpX",	{ XMM, Vex, EXxmm_mq }, PREFIX_OPCODE },
+  },
+  {
+    /* MOD_EVEX_0F17 */
+    { "vmovhpX",	{ EXxmm_mq, XMM }, PREFIX_OPCODE },
+  },
+  {
+    /* MOD_EVEX_0F2B */
+    { "vmovntpX",	{ EXx, XM }, PREFIX_OPCODE },
+  },
+  {
     /* MOD_EVEX_0F38C6_REG_1 */
     { PREFIX_TABLE (PREFIX_EVEX_0F38C6_REG_1) },
   },
--- a/opcodes/i386-dis-evex-prefix.h
+++ b/opcodes/i386-dis-evex-prefix.h
@@ -1,65 +1,29 @@
   /* PREFIX_EVEX_0F10 */
   {
-    { VEX_W_TABLE (EVEX_W_0F10_P_0) },
+    { "vmovupX",	{ XM, EXEvexXNoBcst }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F10_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F10_P_2) },
+    { "vmovupX",	{ XM, EXEvexXNoBcst }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F10_P_3) },
   },
   /* PREFIX_EVEX_0F11 */
   {
-    { VEX_W_TABLE (EVEX_W_0F11_P_0) },
+    { "vmovupX",	{ EXxS, XM }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F11_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F11_P_2) },
+    { "vmovupX",	{ EXxS, XM }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F11_P_3) },
   },
   /* PREFIX_EVEX_0F12 */
   {
     { MOD_TABLE (MOD_EVEX_0F12_PREFIX_0) },
     { VEX_W_TABLE (EVEX_W_0F12_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F12_P_2) },
+    { MOD_TABLE (MOD_EVEX_0F12_PREFIX_2) },
     { VEX_W_TABLE (EVEX_W_0F12_P_3) },
   },
-  /* PREFIX_EVEX_0F13 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F13_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F13_P_2) },
-  },
-  /* PREFIX_EVEX_0F14 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F14_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F14_P_2) },
-  },
-  /* PREFIX_EVEX_0F15 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F15_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F15_P_2) },
-  },
   /* PREFIX_EVEX_0F16 */
   {
     { MOD_TABLE (MOD_EVEX_0F16_PREFIX_0) },
     { VEX_W_TABLE (EVEX_W_0F16_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F16_P_2) },
-  },
-  /* PREFIX_EVEX_0F17 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F17_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F17_P_2) },
-  },
-  /* PREFIX_EVEX_0F28 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F28_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F28_P_2) },
-  },
-  /* PREFIX_EVEX_0F29 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F29_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F29_P_2) },
+    { MOD_TABLE (MOD_EVEX_0F16_PREFIX_2) },
   },
   /* PREFIX_EVEX_0F2A */
   {
@@ -68,12 +32,6 @@
     { Bad_Opcode },
     { VEX_W_TABLE (EVEX_W_0F2A_P_3) },
   },
-  /* PREFIX_EVEX_0F2B */
-  {
-    { VEX_W_TABLE (EVEX_W_0F2B_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F2B_P_2) },
-  },
   /* PREFIX_EVEX_0F2C */
   {
     { Bad_Opcode },
@@ -90,59 +48,35 @@
   },
   /* PREFIX_EVEX_0F2E */
   {
-    { VEX_W_TABLE (EVEX_W_0F2E_P_0) },
+    { "vucomisX",	{ XMScalar, EXxmm_md, EXxEVexS }, PREFIX_OPCODE },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F2E_P_2) },
+    { "vucomisX",	{ XMScalar, EXxmm_mq, EXxEVexS }, PREFIX_OPCODE },
   },
   /* PREFIX_EVEX_0F2F */
   {
-    { VEX_W_TABLE (EVEX_W_0F2F_P_0) },
+    { "vcomisX",	{ XMScalar, EXxmm_md, EXxEVexS }, PREFIX_OPCODE },
     { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F2F_P_2) },
+    { "vcomisX",	{ XMScalar, EXxmm_mq, EXxEVexS }, PREFIX_OPCODE },
   },
   /* PREFIX_EVEX_0F51 */
   {
-    { VEX_W_TABLE (EVEX_W_0F51_P_0) },
+    { "vsqrtpX",	{ XM, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F51_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F51_P_2) },
+    { "vsqrtpX",	{ XM, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F51_P_3) },
   },
-  /* PREFIX_EVEX_0F54 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F54_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F54_P_2) },
-  },
-  /* PREFIX_EVEX_0F55 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F55_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F55_P_2) },
-  },
-  /* PREFIX_EVEX_0F56 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F56_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F56_P_2) },
-  },
-  /* PREFIX_EVEX_0F57 */
-  {
-    { VEX_W_TABLE (EVEX_W_0F57_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0F57_P_2) },
-  },
   /* PREFIX_EVEX_0F58 */
   {
-    { VEX_W_TABLE (EVEX_W_0F58_P_0) },
+    { "vaddpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F58_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F58_P_2) },
+    { "vaddpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F58_P_3) },
   },
   /* PREFIX_EVEX_0F59 */
   {
-    { VEX_W_TABLE (EVEX_W_0F59_P_0) },
+    { "vmulpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F59_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F59_P_2) },
+    { "vmulpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F59_P_3) },
   },
   /* PREFIX_EVEX_0F5A */
@@ -160,30 +94,30 @@
   },
   /* PREFIX_EVEX_0F5C */
   {
-    { VEX_W_TABLE (EVEX_W_0F5C_P_0) },
+    { "vsubpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5C_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F5C_P_2) },
+    { "vsubpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5C_P_3) },
   },
   /* PREFIX_EVEX_0F5D */
   {
-    { VEX_W_TABLE (EVEX_W_0F5D_P_0) },
+    { "vminpX",	{ XM, Vex, EXx, EXxEVexS }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5D_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F5D_P_2) },
+    { "vminpX",	{ XM, Vex, EXx, EXxEVexS }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5D_P_3) },
   },
   /* PREFIX_EVEX_0F5E */
   {
-    { VEX_W_TABLE (EVEX_W_0F5E_P_0) },
+    { "vdivpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5E_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F5E_P_2) },
+    { "vdivpX",	{ XM, Vex, EXx, EXxEVexR }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5E_P_3) },
   },
   /* PREFIX_EVEX_0F5F */
   {
-    { VEX_W_TABLE (EVEX_W_0F5F_P_0) },
+    { "vmaxpX",	{ XM, Vex, EXx, EXxEVexS }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5F_P_1) },
-    { VEX_W_TABLE (EVEX_W_0F5F_P_2) },
+    { "vmaxpX",	{ XM, Vex, EXx, EXxEVexS }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0F5F_P_3) },
   },
   /* PREFIX_EVEX_0F60 */
@@ -423,9 +357,9 @@
   },
   /* PREFIX_EVEX_0FC2 */
   {
-    { VEX_W_TABLE (EVEX_W_0FC2_P_0) },
+    { "vcmppX",	{ XMask, Vex, EXx, EXxEVexS, VCMP }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0FC2_P_1) },
-    { VEX_W_TABLE (EVEX_W_0FC2_P_2) },
+    { "vcmppX",	{ XMask, Vex, EXx, EXxEVexS, VCMP }, PREFIX_OPCODE },
     { VEX_W_TABLE (EVEX_W_0FC2_P_3) },
   },
   /* PREFIX_EVEX_0FC4 */
@@ -440,12 +374,6 @@
     { Bad_Opcode },
     { "vpextrw",	{ Gdq, XS, Ib }, 0 },
   },
-  /* PREFIX_EVEX_0FC6 */
-  {
-    { VEX_W_TABLE (EVEX_W_0FC6_P_0) },
-    { Bad_Opcode },
-    { VEX_W_TABLE (EVEX_W_0FC6_P_2) },
-  },
   /* PREFIX_EVEX_0FD1 */
   {
     { Bad_Opcode },
--- a/opcodes/i386-dis-evex-w.h
+++ b/opcodes/i386-dis-evex-w.h
@@ -1,43 +1,21 @@
-  /* EVEX_W_0F10_P_0 */
-  {
-    { "vmovups",	{ XM, EXEvexXNoBcst }, 0 },
-  },
   /* EVEX_W_0F10_P_1 */
   {
     { "vmovss",	{ XMVexScalar, VexScalar, EXdScalar }, 0 },
   },
-  /* EVEX_W_0F10_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovupd",	{ XM, EXEvexXNoBcst }, 0 },
-  },
   /* EVEX_W_0F10_P_3 */
   {
     { Bad_Opcode },
     { "vmovsd",	{ XMVexScalar, VexScalar, EXqScalar }, 0 },
   },
-  /* EVEX_W_0F11_P_0 */
-  {
-    { "vmovups",	{ EXxS, XM }, 0 },
-  },
   /* EVEX_W_0F11_P_1 */
   {
     { "vmovss",	{ EXdVexScalarS, VexScalar, XMScalar }, 0 },
   },
-  /* EVEX_W_0F11_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovupd",	{ EXxS, XM }, 0 },
-  },
   /* EVEX_W_0F11_P_3 */
   {
     { Bad_Opcode },
     { "vmovsd",	{ EXqVexScalarS, VexScalar, XMScalar }, 0 },
   },
-  /* EVEX_W_0F12_P_0_M_0 */
-  {
-    { "vmovlps",	{ XMM, Vex, EXxmm_mq }, 0 },
-  },
   /* EVEX_W_0F12_P_0_M_1 */
   {
     { "vmovhlps",	{ XMM, Vex, EXxmm_mq }, 0 },
@@ -46,47 +24,11 @@
   {
     { "vmovsldup",	{ XM, EXEvexXNoBcst }, 0 },
   },
-  /* EVEX_W_0F12_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovlpd",	{ XMM, Vex, EXxmm_mq }, 0 },
-  },
   /* EVEX_W_0F12_P_3 */
   {
     { Bad_Opcode },
     { "vmovddup",	{ XM, EXymmq }, 0 },
   },
-  /* EVEX_W_0F13_P_0 */
-  {
-    { "vmovlps",	{ EXxmm_mq, XMM }, 0 },
-  },
-  /* EVEX_W_0F13_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovlpd",	{ EXxmm_mq, XMM }, 0 },
-  },
-  /* EVEX_W_0F14_P_0 */
-  {
-    { "vunpcklps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F14_P_2 */
-  {
-    { Bad_Opcode },
-    { "vunpcklpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F15_P_0 */
-  {
-    { "vunpckhps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F15_P_2 */
-  {
-    { Bad_Opcode },
-    { "vunpckhpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F16_P_0_M_0 */
-  {
-    { "vmovhps",	{ XMM, Vex, EXxmm_mq }, 0 },
-  },
   /* EVEX_W_0F16_P_0_M_1 */
   {
     { "vmovlhps",	{ XMM, Vex, EXx }, 0 },
@@ -95,155 +37,33 @@
   {
     { "vmovshdup",	{ XM, EXx }, 0 },
   },
-  /* EVEX_W_0F16_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovhpd",	{ XMM, Vex, EXxmm_mq }, 0 },
-  },
-  /* EVEX_W_0F17_P_0 */
-  {
-    { "vmovhps",	{ EXxmm_mq, XMM }, 0 },
-  },
-  /* EVEX_W_0F17_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovhpd",	{ EXxmm_mq, XMM }, 0 },
-  },
-  /* EVEX_W_0F28_P_0 */
-  {
-    { "vmovaps",	{ XM, EXx }, 0 },
-  },
-  /* EVEX_W_0F28_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovapd",	{ XM, EXx }, 0 },
-  },
-  /* EVEX_W_0F29_P_0 */
-  {
-    { "vmovaps",	{ EXxS, XM }, 0 },
-  },
-  /* EVEX_W_0F29_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovapd",	{ EXxS, XM }, 0 },
-  },
   /* EVEX_W_0F2A_P_3 */
   {
     { "vcvtsi2sd%LQ",	{ XMScalar, VexScalar, Ed }, 0 },
     { "vcvtsi2sd%LQ",	{ XMScalar, VexScalar, EXxEVexR64, Edq }, 0 },
   },
-  /* EVEX_W_0F2B_P_0 */
-  {
-    { "vmovntps",	{ EXx, XM }, 0 },
-  },
-  /* EVEX_W_0F2B_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmovntpd",	{ EXx, XM }, 0 },
-  },
-  /* EVEX_W_0F2E_P_0 */
-  {
-    { "vucomiss",	{ XMScalar, EXxmm_md, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_0F2E_P_2 */
-  {
-    { Bad_Opcode },
-    { "vucomisd",	{ XMScalar, EXxmm_mq, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_0F2F_P_0 */
-  {
-    { "vcomiss",	{ XMScalar, EXxmm_md, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_0F2F_P_2 */
-  {
-    { Bad_Opcode },
-    { "vcomisd",	{ XMScalar, EXxmm_mq, EXxEVexS }, 0 },
-  },
-  /* EVEX_W_0F51_P_0 */
-  {
-    { "vsqrtps",	{ XM, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F51_P_1 */
   {
     { "vsqrtss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F51_P_2 */
-  {
-    { Bad_Opcode },
-    { "vsqrtpd",	{ XM, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F51_P_3 */
   {
     { Bad_Opcode },
     { "vsqrtsd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F54_P_0 */
-  {
-    { "vandps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F54_P_2 */
-  {
-    { Bad_Opcode },
-    { "vandpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F55_P_0 */
-  {
-    { "vandnps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F55_P_2 */
-  {
-    { Bad_Opcode },
-    { "vandnpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F56_P_0 */
-  {
-    { "vorps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F56_P_2 */
-  {
-    { Bad_Opcode },
-    { "vorpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F57_P_0 */
-  {
-    { "vxorps",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F57_P_2 */
-  {
-    { Bad_Opcode },
-    { "vxorpd",	{ XM, Vex, EXx }, 0 },
-  },
-  /* EVEX_W_0F58_P_0 */
-  {
-    { "vaddps",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F58_P_1 */
   {
     { "vaddss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F58_P_2 */
-  {
-    { Bad_Opcode },
-    { "vaddpd",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F58_P_3 */
   {
     { Bad_Opcode },
     { "vaddsd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F59_P_0 */
-  {
-    { "vmulps",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F59_P_1 */
   {
     { "vmulss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F59_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmulpd",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F59_P_3 */
   {
     { Bad_Opcode },
@@ -280,73 +100,37 @@
   {
     { "vcvtps2dq",	{ XM, EXx, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F5C_P_0 */
-  {
-    { "vsubps",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F5C_P_1 */
   {
     { "vsubss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F5C_P_2 */
-  {
-    { Bad_Opcode },
-    { "vsubpd",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F5C_P_3 */
   {
     { Bad_Opcode },
     { "vsubsd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F5D_P_0 */
-  {
-    { "vminps",	{ XM, Vex, EXx, EXxEVexS }, 0 },
-  },
   /* EVEX_W_0F5D_P_1 */
   {
     { "vminss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexS }, 0 },
   },
-  /* EVEX_W_0F5D_P_2 */
-  {
-    { Bad_Opcode },
-    { "vminpd",	{ XM, Vex, EXx, EXxEVexS }, 0 },
-  },
   /* EVEX_W_0F5D_P_3 */
   {
     { Bad_Opcode },
     { "vminsd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexS }, 0 },
   },
-  /* EVEX_W_0F5E_P_0 */
-  {
-    { "vdivps",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F5E_P_1 */
   {
     { "vdivss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F5E_P_2 */
-  {
-    { Bad_Opcode },
-    { "vdivpd",	{ XM, Vex, EXx, EXxEVexR }, 0 },
-  },
   /* EVEX_W_0F5E_P_3 */
   {
     { Bad_Opcode },
     { "vdivsd",	{ XMScalar, VexScalar, EXxmm_mq, EXxEVexR }, 0 },
   },
-  /* EVEX_W_0F5F_P_0 */
-  {
-    { "vmaxps",	{ XM, Vex, EXx, EXxEVexS }, 0 },
-  },
   /* EVEX_W_0F5F_P_1 */
   {
     { "vmaxss",	{ XMScalar, VexScalar, EXxmm_md, EXxEVexS }, 0 },
   },
-  /* EVEX_W_0F5F_P_2 */
-  {
-    { Bad_Opcode },
-    { "vmaxpd",	{ XM, Vex, EXx, EXxEVexS }, 0 },
-  },
   /* EVEX_W_0F5F_P_3 */
   {
     { Bad_Opcode },
@@ -484,33 +268,15 @@
     { "vmovdqu8",	{ EXxS, XM }, 0 },
     { "vmovdqu16",	{ EXxS, XM }, 0 },
   },
-  /* EVEX_W_0FC2_P_0 */
-  {
-    { "vcmpps",	{ XMask, Vex, EXx, EXxEVexS, VCMP }, 0 },
-  },
   /* EVEX_W_0FC2_P_1 */
   {
     { "vcmpss",	{ XMask, VexScalar, EXxmm_md, EXxEVexS, VCMP }, 0 },
   },
-  /* EVEX_W_0FC2_P_2 */
-  {
-    { Bad_Opcode },
-    { "vcmppd",	{ XMask, Vex, EXx, EXxEVexS, VCMP }, 0 },
-  },
   /* EVEX_W_0FC2_P_3 */
   {
     { Bad_Opcode },
     { "vcmpsd",	{ XMask, VexScalar, EXxmm_mq, EXxEVexS, VCMP }, 0 },
   },
-  /* EVEX_W_0FC6_P_0 */
-  {
-    { "vshufps",	{ XM, Vex, EXx, Ib }, 0 },
-  },
-  /* EVEX_W_0FC6_P_2 */
-  {
-    { Bad_Opcode },
-    { "vshufpd",	{ XM, Vex, EXx, Ib }, 0 },
-  },
   /* EVEX_W_0FD2_P_2 */
   {
     { "vpsrld",	{ XM, Vex, EXxmm }, 0 },
--- a/opcodes/i386-dis-evex.h
+++ b/opcodes/i386-dis-evex.h
@@ -23,11 +23,11 @@ static const struct dis386 evex_table[][
     { PREFIX_TABLE (PREFIX_EVEX_0F10) },
     { PREFIX_TABLE (PREFIX_EVEX_0F11) },
     { PREFIX_TABLE (PREFIX_EVEX_0F12) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F13) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F14) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F15) },
+    { MOD_TABLE (MOD_EVEX_0F13) },
+    { "vunpcklpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vunpckhpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_EVEX_0F16) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F17) },
+    { MOD_TABLE (MOD_EVEX_0F17) },
     /* 18 */
     { Bad_Opcode },
     { Bad_Opcode },
@@ -47,10 +47,10 @@ static const struct dis386 evex_table[][
     { Bad_Opcode },
     { Bad_Opcode },
     /* 28 */
-    { PREFIX_TABLE (PREFIX_EVEX_0F28) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F29) },
+    { "vmovapX",	{ XM, EXx }, PREFIX_OPCODE },
+    { "vmovapX",	{ EXxS, XM }, PREFIX_OPCODE },
     { PREFIX_TABLE (PREFIX_EVEX_0F2A) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F2B) },
+    { MOD_TABLE (MOD_EVEX_0F2B) },
     { PREFIX_TABLE (PREFIX_EVEX_0F2C) },
     { PREFIX_TABLE (PREFIX_EVEX_0F2D) },
     { PREFIX_TABLE (PREFIX_EVEX_0F2E) },
@@ -96,10 +96,10 @@ static const struct dis386 evex_table[][
     { PREFIX_TABLE (PREFIX_EVEX_0F51) },
     { Bad_Opcode },
     { Bad_Opcode },
-    { PREFIX_TABLE (PREFIX_EVEX_0F54) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F55) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F56) },
-    { PREFIX_TABLE (PREFIX_EVEX_0F57) },
+    { "vandpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vandnpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vorpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
+    { "vxorpX",	{ XM, Vex, EXx }, PREFIX_OPCODE },
     /* 58 */
     { PREFIX_TABLE (PREFIX_EVEX_0F58) },
     { PREFIX_TABLE (PREFIX_EVEX_0F59) },
@@ -224,7 +224,7 @@ static const struct dis386 evex_table[][
     { Bad_Opcode },
     { PREFIX_TABLE (PREFIX_EVEX_0FC4) },
     { PREFIX_TABLE (PREFIX_EVEX_0FC5) },
-    { PREFIX_TABLE (PREFIX_EVEX_0FC6) },
+    { "vshufpX",	{ XM, Vex, EXx, Ib }, PREFIX_OPCODE },
     { Bad_Opcode },
     /* C8 */
     { Bad_Opcode },
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -930,7 +930,12 @@ enum
   MOD_VEX_W_1_0F3A33_P_2_LEN_0,
 
   MOD_EVEX_0F12_PREFIX_0,
+  MOD_EVEX_0F12_PREFIX_2,
+  MOD_EVEX_0F13,
   MOD_EVEX_0F16_PREFIX_0,
+  MOD_EVEX_0F16_PREFIX_2,
+  MOD_EVEX_0F17,
+  MOD_EVEX_0F2B,
   MOD_EVEX_0F38C6_REG_1,
   MOD_EVEX_0F38C6_REG_2,
   MOD_EVEX_0F38C6_REG_5,
@@ -1415,24 +1420,13 @@ enum
   PREFIX_EVEX_0F10,
   PREFIX_EVEX_0F11,
   PREFIX_EVEX_0F12,
-  PREFIX_EVEX_0F13,
-  PREFIX_EVEX_0F14,
-  PREFIX_EVEX_0F15,
   PREFIX_EVEX_0F16,
-  PREFIX_EVEX_0F17,
-  PREFIX_EVEX_0F28,
-  PREFIX_EVEX_0F29,
   PREFIX_EVEX_0F2A,
-  PREFIX_EVEX_0F2B,
   PREFIX_EVEX_0F2C,
   PREFIX_EVEX_0F2D,
   PREFIX_EVEX_0F2E,
   PREFIX_EVEX_0F2F,
   PREFIX_EVEX_0F51,
-  PREFIX_EVEX_0F54,
-  PREFIX_EVEX_0F55,
-  PREFIX_EVEX_0F56,
-  PREFIX_EVEX_0F57,
   PREFIX_EVEX_0F58,
   PREFIX_EVEX_0F59,
   PREFIX_EVEX_0F5A,
@@ -1482,7 +1476,6 @@ enum
   PREFIX_EVEX_0FC2,
   PREFIX_EVEX_0FC4,
   PREFIX_EVEX_0FC5,
-  PREFIX_EVEX_0FC6,
   PREFIX_EVEX_0FD1,
   PREFIX_EVEX_0FD2,
   PREFIX_EVEX_0FD3,
@@ -2040,61 +2033,21 @@ enum
   VEX_W_0F3ACE_P_2,
   VEX_W_0F3ACF_P_2,
 
-  EVEX_W_0F10_P_0,
   EVEX_W_0F10_P_1,
-  EVEX_W_0F10_P_2,
   EVEX_W_0F10_P_3,
-  EVEX_W_0F11_P_0,
   EVEX_W_0F11_P_1,
-  EVEX_W_0F11_P_2,
   EVEX_W_0F11_P_3,
-  EVEX_W_0F12_P_0_M_0,
   EVEX_W_0F12_P_0_M_1,
   EVEX_W_0F12_P_1,
-  EVEX_W_0F12_P_2,
   EVEX_W_0F12_P_3,
-  EVEX_W_0F13_P_0,
-  EVEX_W_0F13_P_2,
-  EVEX_W_0F14_P_0,
-  EVEX_W_0F14_P_2,
-  EVEX_W_0F15_P_0,
-  EVEX_W_0F15_P_2,
-  EVEX_W_0F16_P_0_M_0,
   EVEX_W_0F16_P_0_M_1,
   EVEX_W_0F16_P_1,
-  EVEX_W_0F16_P_2,
-  EVEX_W_0F17_P_0,
-  EVEX_W_0F17_P_2,
-  EVEX_W_0F28_P_0,
-  EVEX_W_0F28_P_2,
-  EVEX_W_0F29_P_0,
-  EVEX_W_0F29_P_2,
   EVEX_W_0F2A_P_3,
-  EVEX_W_0F2B_P_0,
-  EVEX_W_0F2B_P_2,
-  EVEX_W_0F2E_P_0,
-  EVEX_W_0F2E_P_2,
-  EVEX_W_0F2F_P_0,
-  EVEX_W_0F2F_P_2,
-  EVEX_W_0F51_P_0,
   EVEX_W_0F51_P_1,
-  EVEX_W_0F51_P_2,
   EVEX_W_0F51_P_3,
-  EVEX_W_0F54_P_0,
-  EVEX_W_0F54_P_2,
-  EVEX_W_0F55_P_0,
-  EVEX_W_0F55_P_2,
-  EVEX_W_0F56_P_0,
-  EVEX_W_0F56_P_2,
-  EVEX_W_0F57_P_0,
-  EVEX_W_0F57_P_2,
-  EVEX_W_0F58_P_0,
   EVEX_W_0F58_P_1,
-  EVEX_W_0F58_P_2,
   EVEX_W_0F58_P_3,
-  EVEX_W_0F59_P_0,
   EVEX_W_0F59_P_1,
-  EVEX_W_0F59_P_2,
   EVEX_W_0F59_P_3,
   EVEX_W_0F5A_P_0,
   EVEX_W_0F5A_P_1,
@@ -2103,21 +2056,13 @@ enum
   EVEX_W_0F5B_P_0,
   EVEX_W_0F5B_P_1,
   EVEX_W_0F5B_P_2,
-  EVEX_W_0F5C_P_0,
   EVEX_W_0F5C_P_1,
-  EVEX_W_0F5C_P_2,
   EVEX_W_0F5C_P_3,
-  EVEX_W_0F5D_P_0,
   EVEX_W_0F5D_P_1,
-  EVEX_W_0F5D_P_2,
   EVEX_W_0F5D_P_3,
-  EVEX_W_0F5E_P_0,
   EVEX_W_0F5E_P_1,
-  EVEX_W_0F5E_P_2,
   EVEX_W_0F5E_P_3,
-  EVEX_W_0F5F_P_0,
   EVEX_W_0F5F_P_1,
-  EVEX_W_0F5F_P_2,
   EVEX_W_0F5F_P_3,
   EVEX_W_0F62_P_2,
   EVEX_W_0F66_P_2,
@@ -2147,12 +2092,8 @@ enum
   EVEX_W_0F7F_P_1,
   EVEX_W_0F7F_P_2,
   EVEX_W_0F7F_P_3,
-  EVEX_W_0FC2_P_0,
   EVEX_W_0FC2_P_1,
-  EVEX_W_0FC2_P_2,
   EVEX_W_0FC2_P_3,
-  EVEX_W_0FC6_P_0,
-  EVEX_W_0FC6_P_2,
   EVEX_W_0FD2_P_2,
   EVEX_W_0FD3_P_2,
   EVEX_W_0FD4_P_2,
@@ -12278,7 +12219,8 @@ print_insn (bfd_vma pc, disassemble_info
 		: ((prefixes
 		    & (PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA))
 		   == PREFIX_DATA))
-	       && (used_prefixes & PREFIX_DATA) == 0))))
+	       && (used_prefixes & PREFIX_DATA) == 0))
+	  || (vex.evex && !vex.w != !(used_prefixes & PREFIX_DATA))))
     {
       (*info->fprintf_func) (info->stream, "(bad)");
       return end_codep - priv.the_buffer;


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/5] x86: fix {,V}MOV{L,H}PD disassembly
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
                   ` (2 preceding siblings ...)
  2020-06-08  7:45 ` [PATCH 3/5] x86: utilize X macro in EVEX decoding Jan Beulich
@ 2020-06-08  7:46 ` Jan Beulich
  2020-06-08  7:46 ` [PATCH 5/5] x86: consistently print prefixes explicitly which are invalid with VEX etc Jan Beulich
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:46 UTC (permalink / raw)
  To: binutils

Neither the legacy nor the VEX-encoded forms are permitted with register
operands, just like is already the case for their store forms as well as
{,V}MOV{L,H}PS.

At the same time, besides folding respective vex_len_table[] entries,
adjust adjacent related legacy mod_table[] entries:
- when the prefix was already decoded, PREFIX_OPCODE is pointless,
- limit the amount of string literals by using X consistently on all
  {,V}MOV{L,H}P{S,D} forms.

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

	* i386-dis.c (MOD_0F12_PREFIX_2, MOD_0F16_PREFIX_2,
	MOD_VEX_0F12_PREFIX_2, MOD_VEX_0F16_PREFIX_2): New enumerators.
	(VEX_LEN_0F12_P_2, VEX_LEN_0F16_P_2): Delete.
	(VEX_LEN_0F12_P_2_M_0, VEX_LEN_0F16_P_2_M_0): Define.
	(prefix_table): Decode MOD for cases 2 of opcodes 0F12, 0F16,
	VEX_0F12, and VEX_0F16.
	(vex_len_table): Use X for vmovlp* and vmovh*s. Drop
	VEX_LEN_0F12_P_2 and VEX_LEN_0F16_P_2 entries.
	(mod_table): Use X for movlpX and movhpX. Drop PREFIX_OPCODE
	from movlps and movhlps. New MOD_0F12_PREFIX_2,
	MOD_0F16_PREFIX_2, MOD_VEX_0F12_PREFIX_2, and
	MOD_VEX_0F16_PREFIX_2 entries.

--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -778,8 +778,10 @@ enum
   MOD_0F01_REG_5,
   MOD_0F01_REG_7,
   MOD_0F12_PREFIX_0,
+  MOD_0F12_PREFIX_2,
   MOD_0F13,
   MOD_0F16_PREFIX_0,
+  MOD_0F16_PREFIX_2,
   MOD_0F17,
   MOD_0F18_REG_0,
   MOD_0F18_REG_1,
@@ -842,8 +844,10 @@ enum
   MOD_C4_32BIT,
   MOD_C5_32BIT,
   MOD_VEX_0F12_PREFIX_0,
+  MOD_VEX_0F12_PREFIX_2,
   MOD_VEX_0F13,
   MOD_VEX_0F16_PREFIX_0,
+  MOD_VEX_0F16_PREFIX_2,
   MOD_VEX_0F17,
   MOD_VEX_0F2B,
   MOD_VEX_W_0_0F41_P_0_LEN_1,
@@ -1799,11 +1803,11 @@ enum
 {
   VEX_LEN_0F12_P_0_M_0 = 0,
   VEX_LEN_0F12_P_0_M_1,
-  VEX_LEN_0F12_P_2,
+#define VEX_LEN_0F12_P_2_M_0 VEX_LEN_0F12_P_0_M_0
   VEX_LEN_0F13_M_0,
   VEX_LEN_0F16_P_0_M_0,
   VEX_LEN_0F16_P_0_M_1,
-  VEX_LEN_0F16_P_2,
+#define VEX_LEN_0F16_P_2_M_0 VEX_LEN_0F16_P_0_M_0
   VEX_LEN_0F17_M_0,
   VEX_LEN_0F41_P_0,
   VEX_LEN_0F41_P_2,
@@ -3643,7 +3647,7 @@ static const struct dis386 prefix_table[
   {
     { MOD_TABLE (MOD_0F12_PREFIX_0) },
     { "movsldup", { XM, EXx }, PREFIX_OPCODE },
-    { "movlpd",	{ XM, EXq }, PREFIX_OPCODE },
+    { MOD_TABLE (MOD_0F12_PREFIX_2) },
     { "movddup", { XM, EXq }, PREFIX_OPCODE },
   },
 
@@ -3651,7 +3655,7 @@ static const struct dis386 prefix_table[
   {
     { MOD_TABLE (MOD_0F16_PREFIX_0) },
     { "movshdup", { XM, EXx }, PREFIX_OPCODE },
-    { "movhpd",	{ XM, EXq }, PREFIX_OPCODE },
+    { MOD_TABLE (MOD_0F16_PREFIX_2) },
   },
 
   /* PREFIX_0F1A */
@@ -4648,7 +4652,7 @@ static const struct dis386 prefix_table[
   {
     { MOD_TABLE (MOD_VEX_0F12_PREFIX_0) },
     { "vmovsldup",	{ XM, EXx }, 0 },
-    { VEX_LEN_TABLE (VEX_LEN_0F12_P_2) },
+    { MOD_TABLE (MOD_VEX_0F12_PREFIX_2) },
     { "vmovddup",	{ XM, EXymmq }, 0 },
   },
 
@@ -4656,7 +4660,7 @@ static const struct dis386 prefix_table[
   {
     { MOD_TABLE (MOD_VEX_0F16_PREFIX_0) },
     { "vmovshdup",	{ XM, EXx }, 0 },
-    { VEX_LEN_TABLE (VEX_LEN_0F16_P_2) },
+    { MOD_TABLE (MOD_VEX_0F16_PREFIX_2) },
   },
 
   /* PREFIX_VEX_0F2A */
@@ -9279,9 +9283,9 @@ static const struct dis386 vex_table[][2
 #include "i386-dis-evex.h"
 
 static const struct dis386 vex_len_table[][2] = {
-  /* VEX_LEN_0F12_P_0_M_0 */
+  /* VEX_LEN_0F12_P_0_M_0 / VEX_LEN_0F12_P_2_M_0 */
   {
-    { "vmovlps",	{ XM, Vex128, EXq }, 0 },
+    { "vmovlpX",	{ XM, Vex128, EXq }, 0 },
   },
 
   /* VEX_LEN_0F12_P_0_M_1 */
@@ -9289,19 +9293,14 @@ static const struct dis386 vex_len_table
     { "vmovhlps",	{ XM, Vex128, EXq }, 0 },
   },
 
-  /* VEX_LEN_0F12_P_2 */
-  {
-    { "vmovlpd",	{ XM, Vex128, EXq }, 0 },
-  },
-
   /* VEX_LEN_0F13_M_0 */
   {
     { "vmovlpX",	{ EXq, XM }, PREFIX_OPCODE },
   },
 
-  /* VEX_LEN_0F16_P_0_M_0 */
+  /* VEX_LEN_0F16_P_0_M_0 / VEX_LEN_0F16_P_2_M_0 */
   {
-    { "vmovhps",	{ XM, Vex128, EXq }, 0 },
+    { "vmovhpX",	{ XM, Vex128, EXq }, 0 },
   },
 
   /* VEX_LEN_0F16_P_0_M_1 */
@@ -9309,11 +9308,6 @@ static const struct dis386 vex_len_table
     { "vmovlhps",	{ XM, Vex128, EXq }, 0 },
   },
 
-  /* VEX_LEN_0F16_P_2 */
-  {
-    { "vmovhpd",	{ XM, Vex128, EXq }, 0 },
-  },
-
   /* VEX_LEN_0F17_M_0 */
   {
     { "vmovhpX",	{ EXq, XM }, PREFIX_OPCODE },
@@ -10225,8 +10219,12 @@ static const struct dis386 mod_table[][2
   },
   {
     /* MOD_0F12_PREFIX_0 */
-    { "movlps",		{ XM, EXq }, PREFIX_OPCODE },
-    { "movhlps",	{ XM, EXq }, PREFIX_OPCODE },
+    { "movlpX",		{ XM, EXq }, 0 },
+    { "movhlps",	{ XM, EXq }, 0 },
+  },
+  {
+    /* MOD_0F12_PREFIX_2 */
+    { "movlpX",	{ XM, EXq }, 0 },
   },
   {
     /* MOD_0F13 */
@@ -10234,10 +10232,14 @@ static const struct dis386 mod_table[][2
   },
   {
     /* MOD_0F16_PREFIX_0 */
-    { "movhps",		{ XM, EXq }, 0 },
+    { "movhpX",		{ XM, EXq }, 0 },
     { "movlhps",	{ XM, EXq }, 0 },
   },
   {
+    /* MOD_0F16_PREFIX_2 */
+    { "movhpX",	{ XM, EXq }, 0 },
+  },
+  {
     /* MOD_0F17 */
     { "movhpX",		{ EXq, XM }, PREFIX_OPCODE },
   },
@@ -10519,6 +10521,10 @@ static const struct dis386 mod_table[][2
     { VEX_LEN_TABLE (VEX_LEN_0F12_P_0_M_1) },
   },
   {
+    /* MOD_VEX_0F12_PREFIX_2 */
+    { VEX_LEN_TABLE (VEX_LEN_0F12_P_2_M_0) },
+  },
+  {
     /* MOD_VEX_0F13 */
     { VEX_LEN_TABLE (VEX_LEN_0F13_M_0) },
   },
@@ -10528,6 +10534,10 @@ static const struct dis386 mod_table[][2
     { VEX_LEN_TABLE (VEX_LEN_0F16_P_0_M_1) },
   },
   {
+    /* MOD_VEX_0F16_PREFIX_2 */
+    { VEX_LEN_TABLE (VEX_LEN_0F16_P_2_M_0) },
+  },
+  {
     /* MOD_VEX_0F17 */
     { VEX_LEN_TABLE (VEX_LEN_0F17_M_0) },
   },


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/5] x86: consistently print prefixes explicitly which are invalid with VEX etc
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
                   ` (3 preceding siblings ...)
  2020-06-08  7:46 ` [PATCH 4/5] x86: fix {,V}MOV{L,H}PD disassembly Jan Beulich
@ 2020-06-08  7:46 ` Jan Beulich
  2020-06-08  7:48 ` Jan Beulich
  2020-06-08 11:45 ` [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments H.J. Lu
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:46 UTC (permalink / raw)
  To: binutils

All of data size, rep, lock, and rex prefixes are invalid with VEX- and
alike encoded insns. Make sure they get printed explicitly in all cases,
to signal the anomaly. With this, do away with "rex_ignored" - if there
is a rex prefix, we want to print it anyway for VEX etc (and there's
nothing "ignored" about it in the first place - such an instruction will
raise #UD).

gas/
2020-06-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/prefix.s: Add bogus prefix-with-VEX/EVEX
	encoding tests.
	* testsuite/gas/i386/prefix.d: Adjust expectations.

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

	* i386-dis.c (rex_ignored): Delete.
	(ckprefix): Drop rex_ignored initialization.
	(get_valid_dis386): Drop setting of rex_ignored.
	(print_insn): Drop checking of rex_ignored. Don't record data
	size prefix as used with VEX-and-alike encodings.

--- a/gas/testsuite/gas/i386/prefix.d
+++ b/gas/testsuite/gas/i386/prefix.d
@@ -86,8 +86,11 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	ff cc                	dec    %esp
 [ 	]*[a-f0-9]+:	62 f1 ff 08 28       	\(bad\) *
 [ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	66 c5 f8 28 c0       	data16 vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f3 c4 e1 78 28 c0    	repz vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f2 c5 f8 28 c0       	repnz vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f0 62 f1 7c 08 28 c0 	lock vmovaps %xmm0,%xmm0
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
 [ 	]*[a-f0-9]+:	62 f1 ff 18 e6 40 04 	vcvtpd2dq 0x20\(%eax\)\{1to2\},%xmm0
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
-	...
 #pass
--- a/gas/testsuite/gas/i386/prefix.s
+++ b/gas/testsuite/gas/i386/prefix.s
@@ -451,6 +451,11 @@
 
 	int $3
 
+	.byte 0x66; vmovaps %xmm0, %xmm0
+	repz; {vex3} vmovaps %xmm0, %xmm0
+	repnz; vmovaps %xmm0, %xmm0
+	lock; {evex} vmovaps %xmm0, %xmm0
+
 	vcvtpd2dqx 0x20(%eax),%xmm0
 	vcvtpd2dq 0x20(%eax){1to2},%xmm0
 	vcvtpd2dqx 0x20(%eax),%xmm0
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -153,8 +153,6 @@ static int prefixes;
 static int rex;
 /* Bits of REX we've already used.  */
 static int rex_used;
-/* REX bits in original REX prefix ignored.  */
-static int rex_ignored;
 /* Mark parts used in the REX prefix.  When we are testing for
    empty prefix (for 8bit register REX extension), just mask it
    out.  Otherwise test for REX bit is excuse for existence of REX
@@ -11057,7 +11055,6 @@ ckprefix (void)
 {
   int newrex, i, length;
   rex = 0;
-  rex_ignored = 0;
   prefixes = 0;
   used_prefixes = 0;
   rex_used = 0;
@@ -11517,8 +11514,6 @@ get_valid_dis386 (const struct dis386 *d
 
     case USE_XOP_8F_TABLE:
       FETCH_DATA (info, codep + 3);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = ~(*codep >> 5) & 0x7;
 
       /* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm".  */
@@ -11580,8 +11575,6 @@ get_valid_dis386 (const struct dis386 *d
     case USE_VEX_C4_TABLE:
       /* VEX prefix.  */
       FETCH_DATA (info, codep + 3);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = ~(*codep >> 5) & 0x7;
       switch ((*codep & 0x1f))
 	{
@@ -11647,8 +11640,6 @@ get_valid_dis386 (const struct dis386 *d
     case USE_VEX_C5_TABLE:
       /* VEX prefix.  */
       FETCH_DATA (info, codep + 2);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = (*codep & 0x80) ? 0 : REX_R;
 
       /* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
@@ -11697,8 +11688,6 @@ get_valid_dis386 (const struct dis386 *d
       /* EVEX prefix.  */
       vex.evex = 1;
       FETCH_DATA (info, codep + 4);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       /* The first byte after 0x62.  */
       rex = ~(*codep >> 5) & 0x7;
       vex.r = *codep & 0x10;
@@ -12179,7 +12168,7 @@ print_insn (bfd_vma pc, disassemble_info
     }
 
   /* Check if the REX prefix is used.  */
-  if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0)
+  if ((rex ^ rex_used) == 0 && !need_vex && last_rex_prefix >= 0)
     all_prefixes[last_rex_prefix] = 0;
 
   /* Check if the SEG prefix is used.  */
@@ -12195,7 +12184,8 @@ print_insn (bfd_vma pc, disassemble_info
 
   /* Check if the DATA prefix is used.  */
   if ((prefixes & PREFIX_DATA) != 0
-      && (used_prefixes & PREFIX_DATA) != 0)
+      && (used_prefixes & PREFIX_DATA) != 0
+      && !need_vex)
     all_prefixes[last_data_prefix] = 0;
 
   /* Print the extra prefixes.  */


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/5] x86: consistently print prefixes explicitly which are invalid with VEX etc
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
                   ` (4 preceding siblings ...)
  2020-06-08  7:46 ` [PATCH 5/5] x86: consistently print prefixes explicitly which are invalid with VEX etc Jan Beulich
@ 2020-06-08  7:48 ` Jan Beulich
  2020-06-08 11:45 ` [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments H.J. Lu
  6 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2020-06-08  7:48 UTC (permalink / raw)
  To: binutils

(re-sending with HJ Cc-ed; sorry for the duplicate on the list)

All of data size, rep, lock, and rex prefixes are invalid with VEX- and
alike encoded insns. Make sure they get printed explicitly in all cases,
to signal the anomaly. With this, do away with "rex_ignored" - if there
is a rex prefix, we want to print it anyway for VEX etc (and there's
nothing "ignored" about it in the first place - such an instruction will
raise #UD).

gas/
2020-06-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/prefix.s: Add bogus prefix-with-VEX/EVEX
	encoding tests.
	* testsuite/gas/i386/prefix.d: Adjust expectations.

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

	* i386-dis.c (rex_ignored): Delete.
	(ckprefix): Drop rex_ignored initialization.
	(get_valid_dis386): Drop setting of rex_ignored.
	(print_insn): Drop checking of rex_ignored. Don't record data
	size prefix as used with VEX-and-alike encodings.

--- a/gas/testsuite/gas/i386/prefix.d
+++ b/gas/testsuite/gas/i386/prefix.d
@@ -86,8 +86,11 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	ff cc                	dec    %esp
 [ 	]*[a-f0-9]+:	62 f1 ff 08 28       	\(bad\) *
 [ 	]*[a-f0-9]+:	ff cc                	dec    %esp
+[ 	]*[a-f0-9]+:	66 c5 f8 28 c0       	data16 vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f3 c4 e1 78 28 c0    	repz vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f2 c5 f8 28 c0       	repnz vmovaps %xmm0,%xmm0
+[ 	]*[a-f0-9]+:	f0 62 f1 7c 08 28 c0 	lock vmovaps %xmm0,%xmm0
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
 [ 	]*[a-f0-9]+:	62 f1 ff 18 e6 40 04 	vcvtpd2dq 0x20\(%eax\)\{1to2\},%xmm0
 [ 	]*[a-f0-9]+:	c5 fb e6 40 20       	vcvtpd2dqx 0x20\(%eax\),%xmm0
-	...
 #pass
--- a/gas/testsuite/gas/i386/prefix.s
+++ b/gas/testsuite/gas/i386/prefix.s
@@ -451,6 +451,11 @@
 
 	int $3
 
+	.byte 0x66; vmovaps %xmm0, %xmm0
+	repz; {vex3} vmovaps %xmm0, %xmm0
+	repnz; vmovaps %xmm0, %xmm0
+	lock; {evex} vmovaps %xmm0, %xmm0
+
 	vcvtpd2dqx 0x20(%eax),%xmm0
 	vcvtpd2dq 0x20(%eax){1to2},%xmm0
 	vcvtpd2dqx 0x20(%eax),%xmm0
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -153,8 +153,6 @@ static int prefixes;
 static int rex;
 /* Bits of REX we've already used.  */
 static int rex_used;
-/* REX bits in original REX prefix ignored.  */
-static int rex_ignored;
 /* Mark parts used in the REX prefix.  When we are testing for
    empty prefix (for 8bit register REX extension), just mask it
    out.  Otherwise test for REX bit is excuse for existence of REX
@@ -11057,7 +11055,6 @@ ckprefix (void)
 {
   int newrex, i, length;
   rex = 0;
-  rex_ignored = 0;
   prefixes = 0;
   used_prefixes = 0;
   rex_used = 0;
@@ -11517,8 +11514,6 @@ get_valid_dis386 (const struct dis386 *d
 
     case USE_XOP_8F_TABLE:
       FETCH_DATA (info, codep + 3);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = ~(*codep >> 5) & 0x7;
 
       /* VEX_TABLE_INDEX is the mmmmm part of the XOP byte 1 "RCB.mmmmm".  */
@@ -11580,8 +11575,6 @@ get_valid_dis386 (const struct dis386 *d
     case USE_VEX_C4_TABLE:
       /* VEX prefix.  */
       FETCH_DATA (info, codep + 3);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = ~(*codep >> 5) & 0x7;
       switch ((*codep & 0x1f))
 	{
@@ -11647,8 +11640,6 @@ get_valid_dis386 (const struct dis386 *d
     case USE_VEX_C5_TABLE:
       /* VEX prefix.  */
       FETCH_DATA (info, codep + 2);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       rex = (*codep & 0x80) ? 0 : REX_R;
 
       /* For the 2-byte VEX prefix in 32-bit mode, the highest bit in
@@ -11697,8 +11688,6 @@ get_valid_dis386 (const struct dis386 *d
       /* EVEX prefix.  */
       vex.evex = 1;
       FETCH_DATA (info, codep + 4);
-      /* All bits in the REX prefix are ignored.  */
-      rex_ignored = rex;
       /* The first byte after 0x62.  */
       rex = ~(*codep >> 5) & 0x7;
       vex.r = *codep & 0x10;
@@ -12179,7 +12168,7 @@ print_insn (bfd_vma pc, disassemble_info
     }
 
   /* Check if the REX prefix is used.  */
-  if (rex_ignored == 0 && (rex ^ rex_used) == 0 && last_rex_prefix >= 0)
+  if ((rex ^ rex_used) == 0 && !need_vex && last_rex_prefix >= 0)
     all_prefixes[last_rex_prefix] = 0;
 
   /* Check if the SEG prefix is used.  */
@@ -12195,7 +12184,8 @@ print_insn (bfd_vma pc, disassemble_info
 
   /* Check if the DATA prefix is used.  */
   if ((prefixes & PREFIX_DATA) != 0
-      && (used_prefixes & PREFIX_DATA) != 0)
+      && (used_prefixes & PREFIX_DATA) != 0
+      && !need_vex)
     all_prefixes[last_data_prefix] = 0;
 
   /* Print the extra prefixes.  */


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments
  2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
                   ` (5 preceding siblings ...)
  2020-06-08  7:48 ` Jan Beulich
@ 2020-06-08 11:45 ` H.J. Lu
  6 siblings, 0 replies; 8+ messages in thread
From: H.J. Lu @ 2020-06-08 11:45 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

On Mon, Jun 8, 2020 at 12:42 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> 1: correct mis-named MOD_0F51 enumerator
> 2: correct decoding of packed-FP-only AVX encodings
> 3: utilize X macro in EVEX decoding
> 4: fix {,V}MOV{L,H}PD disassembly
> 5: consistently print prefixes explicitly which are invalid with VEX etc

OK.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-06-08 11:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-08  7:42 [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments Jan Beulich
2020-06-08  7:44 ` [PATCH 1/5] x86: correct mis-named MOD_0F51 enumerator Jan Beulich
2020-06-08  7:45 ` [PATCH 2/5] x86: correct decoding of packed-FP-only AVX encodings Jan Beulich
2020-06-08  7:45 ` [PATCH 3/5] x86: utilize X macro in EVEX decoding Jan Beulich
2020-06-08  7:46 ` [PATCH 4/5] x86: fix {,V}MOV{L,H}PD disassembly Jan Beulich
2020-06-08  7:46 ` [PATCH 5/5] x86: consistently print prefixes explicitly which are invalid with VEX etc Jan Beulich
2020-06-08  7:48 ` Jan Beulich
2020-06-08 11:45 ` [PATCH 0/5] x86: (mainly) insn prefix decoding adjustments H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).