[07/12] x86: correct EVEX.V' handling outside of 64-bit mode

Message ID c4536dab-de2e-5f06-34c6-ab1580809370@suse.com
State New
Headers show
Series
  • x86: disassembler fixes and some consolidation
Related show

Commit Message

Luis Machado via Binutils July 21, 2021, 10:21 a.m.
Unlike the high bit of VEX.vvvv / EVEX.vvvv, EVEX.V' is not ignored
outside of 64-bit. Oddly enough there already are tests for these cases,
but their expectations were wrong. (This may have been based on an old
SDM version, where the restriction wasn't properly spelled out.)

Patch

--- a/gas/testsuite/gas/i386/noextreg.d
+++ b/gas/testsuite/gas/i386/noextreg.d
@@ -13,14 +13,14 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	62 f1 7d 08 db c0    	vpandd %xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	62 d1 7d 08 db c0    	vpandd %xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	62 f1 3d 08 db c0    	vpandd %xmm0,%xmm0,%xmm0
-[ 	]*[a-f0-9]+:	62 f1 7d 00 db c0    	vpandd %xmm0,%xmm0,%xmm0
+[ 	]*[a-f0-9]+:	62 f1 7d 00 db c0    	vpandd %xmm0,\(bad\),%xmm0
 [ 	]*[a-f0-9]+:	c4 e3 79 4c c0 00    	vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	c4 c3 79 4c c0 00    	vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	c4 e3 39 4c c0 00    	vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	c4 e3 79 4c c0 80    	vpblendvb %xmm0,%xmm0,%xmm0,%xmm0
 [ 	]*[a-f0-9]+:	62 f2 7d 0f 90 0c 00 	vpgatherdd \(%eax,%xmm0,1\),%xmm1\{%k7\}
 [ 	]*[a-f0-9]+:	62 d2 7d 0f 90 0c 00 	vpgatherdd \(%eax,%xmm0,1\),%xmm1\{%k7\}
-[ 	]*[a-f0-9]+:	62 f2 7d 07 90 0c 00 	vpgatherdd \(%eax,%xmm0,1\),%xmm1\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 7d 07 90 0c 00 	vpgatherdd \(%eax,\(bad\),1\),%xmm1\{%k7\}
 [ 	]*[a-f0-9]+:	c4 e2 78 f2 00       	andn   \(%eax\),%eax,%eax
 [ 	]*[a-f0-9]+:	c4 e2 38 f2 00       	andn   \(%eax\),%eax,%eax
 [ 	]*[a-f0-9]+:	c4 c2 78 f2 00       	andn   \(%eax\),%eax,%eax
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -9316,7 +9316,6 @@  get_valid_dis386 (const struct dis386 *d
 	  /* In 16/32-bit mode silently ignore following bits.  */
 	  rex &= ~REX_B;
 	  vex.r = 1;
-	  vex.v = 1;
 	}
 
       need_vex = 1;
@@ -11718,8 +11717,13 @@  OP_E_memory (int bytemode, int sizeflag)
 		      *obufp = '\0';
 		    }
 		  if (haveindex)
-		    oappend (address_mode == mode_64bit && !addr32flag
-			     ? indexes64[vindex] : indexes32[vindex]);
+		    {
+		      if (address_mode == mode_64bit || vindex < 16)
+			oappend (address_mode == mode_64bit && !addr32flag
+				 ? indexes64[vindex] : indexes32[vindex]);
+		      else
+			oappend ("(bad)");
+		    }
 		  else
 		    oappend (address_mode == mode_64bit && !addr32flag
 			     ? index64 : index32);
@@ -13256,7 +13260,15 @@  OP_VEX (int bytemode, int sizeflag ATTRI
   reg = vex.register_specifier;
   vex.register_specifier = 0;
   if (address_mode != mode_64bit)
-    reg &= 7;
+    {
+      if (vex.evex && !vex.v)
+	{
+	  oappend ("(bad)");
+	  return;
+	}
+
+      reg &= 7;
+    }
   else if (vex.evex && !vex.v)
     reg += 16;