public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] x86: express unduly set rounding control bits in disassembly
@ 2021-07-22 13:44 Jan Beulich
  2021-07-22 13:52 ` H.J. Lu
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2021-07-22 13:44 UTC (permalink / raw)
  To: Binutils

While EVEX.L'L are indeed ignored when EVEX.b stands for just SAE,
EVEX.b itself is not ignored when an insn permits neither rounding
control nor SAE.

While changing this aspect of EVEX.b handling, also alter unduly set
embedded broadcast: Don't call BadOp(), screwing up subsequent
disassembly, but emit "{bad}" instead.

--- a/gas/testsuite/gas/i386/avx512f-nondef.d
+++ b/gas/testsuite/gas/i386/avx512f-nondef.d
@@ -10,12 +10,11 @@ Disassembly of section .text:
 0+ <.text>:
 [ 	]*[a-f0-9]+:	62 f3 d5 1f 0b f4 7b 	vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
 [ 	]*[a-f0-9]+:	62 f3 d5 5f 0b f4 7b 	vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
-[ 	]*[a-f0-9]+:	62 f2 55 1f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
-[ 	]*[a-f0-9]+:	62 c2 55 1f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 55 4f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
+[ 	]*[a-f0-9]+:	62 c2 55 4f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 55 1f 3b f4    	vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\}
 [ 	]*[a-f0-9]+:	62 f2 7e 48 31 72 7f 	vpmovdb %zmm6,0x7f0\(%edx\)
-[ 	]*[a-f0-9]+:	62                   	vpmovdb %zmm6,\(bad\)
-[ 	]*[a-f0-9]+:	f2 7e 58             	bnd jle (0x7d|7d <.text\+0x7d>)
-[ 	]*[a-f0-9]+:	31 72 7f             	xor    %esi,0x7f\(%edx\)
+[ 	]*[a-f0-9]+:	62 f2 7e 58 31 72 7f 	vpmovdb %zmm6,0x7f0\(%edx\)\{bad\}
 [ 	]*[a-f0-9]+:	62 f1 7c 88 58       	\(bad\)
 [ 	]*[a-f0-9]+:	c3                   	ret *
 [ 	]*[a-f0-9]+:	62 f2 7d 4f 92 01    	vgatherdps \(bad\),%zmm0\{%k7\}
--- a/gas/testsuite/gas/i386/avx512f-nondef.s
+++ b/gas/testsuite/gas/i386/avx512f-nondef.s
@@ -5,13 +5,15 @@
 .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b
 # vrndscalesd	{sae}, $123, %xmm4, %xmm5, %xmm6{%k7}	 # with not-null RC
 .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b
-# vpminud	%zmm4, %zmm5, %zmm6{%k7}	 # with 111 REX
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with 11 EVEX.{B,R'}
+.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with not-11 EVEX.{B,R'}
+.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with set EVEX.b bit
 .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4
-# vpminud	%zmm4, %zmm5, %zmm6{%k7}	 # with not-111 REX
-.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4
-# vpmovdb	%zmm6, 2032(%rdx) # with unset EVEX.B bit
+# vpmovdb	%zmm6, 2032(%rdx)		# with unset EVEX.b bit
 .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f
-# vpmovdb	%zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand
+# vpmovdb	%zmm6, 2032(%rdx)		# with set EVEX.b bit - we should get (bad) operand
 .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f
 # vaddps xmm0, xmm0, xmm3 # with EVEX.z set
 .byte 0x62, 0xf1, 0x7c, 0x88, 0x58, 0xc3
--- a/gas/testsuite/gas/i386/evex.d
+++ b/gas/testsuite/gas/i386/evex.d
@@ -8,14 +8,14 @@ Disassembly of section .text:
 
 0+ <_start>:
  +[a-f0-9]+:	62 f1 d6 38 2a f0    	vcvtsi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 57 38 2a f0    	vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 d7 38 2a f0    	vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 57 38 2a f0    	vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d7 38 2a f0    	vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d6 08 7b f0    	vcvtusi2ssl %eax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 57 08 7b f0    	vcvtusi2sdl %eax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d7 08 7b f0    	vcvtusi2sdl %eax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d6 38 7b f0    	vcvtusi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 57 38 7b f0    	vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 d7 38 7b f0    	vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 57 38 7b f0    	vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 d7 38 7b f0    	vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
  +[a-f0-9]+:	62 e1 7e 08 2d c0    	vcvtss2si %xmm0,%eax
  +[a-f0-9]+:	62 e1 7c 08 c2 c0 00 	vcmpeqps %xmm0,%xmm0,%k0
 #pass
--- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d
+++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d
@@ -10,10 +10,9 @@ Disassembly of section .text:
 0+ <.text>:
 [ 	]*[a-f0-9]+:	62 f3 d5 1f 0b f4 7b 	vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
 [ 	]*[a-f0-9]+:	62 f3 d5 5f 0b f4 7b 	vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
-[ 	]*[a-f0-9]+:	62 f2 55 1f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
-[ 	]*[a-f0-9]+:	62 c2 55 1f 3b f4    	vpminud %zmm12,%zmm5,%zmm22\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 55 4f 3b f4    	vpminud %zmm4,%zmm5,%zmm6\{%k7\}
+[ 	]*[a-f0-9]+:	62 c2 55 4f 3b f4    	vpminud %zmm12,%zmm5,%zmm22\{%k7\}
+[ 	]*[a-f0-9]+:	62 f2 55 1f 3b f4    	vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\}
 [ 	]*[a-f0-9]+:	62 f2 7e 48 31 72 7f 	vpmovdb %zmm6,0x7f0\(%rdx\)
-[ 	]*[a-f0-9]+:	62                   	vpmovdb %zmm6,\(bad\)
-[ 	]*[a-f0-9]+:	f2 7e 58             	bnd jle (0x7d|7d <.text\+0x7d>)
-[ 	]*[a-f0-9]+:	31 72 7f             	xor    %esi,0x7f\(%rdx\)
+[ 	]*[a-f0-9]+:	62 f2 7e 58 31 72 7f 	vpmovdb %zmm6,0x7f0\(%rdx\)\{bad\}
 #pass
--- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s
+++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s
@@ -5,11 +5,13 @@
 .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b
 # vrndscalesd	{sae}, $123, %xmm4, %xmm5, %xmm6{%k7}	 # with not-null RC
 .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b
-# vpminud	%zmm4, %zmm5, %zmm6{%k7}	 # with 111 REX
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with 11 EVEX.{B,R'}
+.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with not-11 EVEX.{B,R'}
+.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4
+# vpminud	%zmm4, %zmm5, %zmm6{%k7}	# with set EVEX.b bit
 .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4
-# vpminud	%zmm4, %zmm5, %zmm6{%k7}	 # with not-111 REX
-.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4
-# vpmovdb	%zmm6, 2032(%rdx) # with unset EVEX.B bit
+# vpmovdb	%zmm6, 2032(%rdx)		# with unset EVEX.b bit
 .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f
-# vpmovdb	%zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand
+# vpmovdb	%zmm6, 2032(%rdx)		# with set EVEX.b bit - we should get (bad) operand
 .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f
--- a/gas/testsuite/gas/i386/x86-64-evex.d
+++ b/gas/testsuite/gas/i386/x86-64-evex.d
@@ -9,13 +9,13 @@ Disassembly of section .text:
 
 0+ <_start>:
  +[a-f0-9]+:	62 f1 d6 38 2a f0    	vcvtsi2ss %rax,\{rd-sae\},%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 57 38 2a f0    	vcvtsi2sd %eax,\(bad\),%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 57 38 2a f0    	vcvtsi2sd %eax,\{rd-bad\},%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d7 38 2a f0    	vcvtsi2sd %rax,\{rd-sae\},%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d6 08 7b f0    	vcvtusi2ss %rax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 57 08 7b f0    	vcvtusi2sd %eax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d7 08 7b f0    	vcvtusi2sd %rax,%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d6 38 7b f0    	vcvtusi2ss %rax,\{rd-sae\},%xmm5,%xmm6
- +[a-f0-9]+:	62 f1 57 38 7b f0    	vcvtusi2sd %eax,\(bad\),%xmm5,%xmm6
+ +[a-f0-9]+:	62 f1 57 38 7b f0    	vcvtusi2sd %eax,\{rd-bad\},%xmm5,%xmm6
  +[a-f0-9]+:	62 f1 d7 38 7b f0    	vcvtusi2sd %rax,\{rd-sae\},%xmm5,%xmm6
  +[a-f0-9]+:	62 e1 7e 08 2d c0    	vcvtss2si %xmm0,\(bad\)
  +[a-f0-9]+:	62 e1 7c 08 c2 c0 00 	vcmpeqps %xmm0,%xmm0,\(bad\)
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -159,6 +159,11 @@ static int rex_used;
    current instruction.  */
 static int used_prefixes;
 
+/* Flags for EVEX bits which we somehow handled when printing the
+   current instruction.  */
+#define EVEX_b_used 1
+static int evex_used;
+
 /* Flags stored in PREFIXES.  */
 #define PREFIX_REPZ 1
 #define PREFIX_REPNZ 2
@@ -2524,12 +2529,12 @@ static const char *att_names_mask[] = {
   "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
 };
 
-static const char *names_rounding[] =
+static const char *const names_rounding[] =
 {
-  "{rn-sae}",
-  "{rd-sae}",
-  "{ru-sae}",
-  "{rz-sae}"
+  "{rn-",
+  "{rd-",
+  "{ru-",
+  "{rz-"
 };
 
 static const struct dis386 reg_table[][8] = {
@@ -8578,6 +8583,7 @@ ckprefix (void)
   prefixes = 0;
   used_prefixes = 0;
   rex_used = 0;
+  evex_used = 0;
   last_lock_prefix = -1;
   last_repz_prefix = -1;
   last_repnz_prefix = -1;
@@ -9661,6 +9667,21 @@ print_insn (bfd_vma pc, disassemble_info
 		    oappend ("/(bad)");
 		}
 	    }
+
+	  /* Check whether rounding control was enabled for an insn not
+	     supporting it.  */
+	  if (modrm.mod == 3 && vex.b && !(evex_used & EVEX_b_used))
+	    {
+	      for (i = 0; i < MAX_OPERANDS; ++i)
+		{
+		  obufp = op_out[i];
+		  if (*obufp)
+		    continue;
+		  oappend (names_rounding[vex.ll]);
+		  oappend ("bad}");
+		  break;
+		}
+	    }
 	}
     }
 
@@ -11316,14 +11337,6 @@ OP_E_memory (int bytemode, int sizeflag)
 
   if (vex.evex)
     {
-      /* In EVEX, if operand doesn't allow broadcast, vex.b should be 0.  */
-      if (vex.b
-	  && bytemode != x_mode
-	  && bytemode != evex_half_bcst_xmmq_mode)
-	{
-	  BadOp ();
-	  return;
-	}
       switch (bytemode)
 	{
 	case dw_mode:
@@ -11764,10 +11777,9 @@ OP_E_memory (int bytemode, int sizeflag)
 	  oappend (scratchbuf);
 	}
     }
-  if (vex.b
-      && (bytemode == x_mode
-	  || bytemode == evex_half_bcst_xmmq_mode))
+  if (vex.b)
     {
+      evex_used |= EVEX_b_used;
       if (vex.w
 	  || bytemode == evex_half_bcst_xmmq_mode)
 	{
@@ -11786,7 +11798,7 @@ OP_E_memory (int bytemode, int sizeflag)
 	      abort ();
 	    }
 	}
-      else
+      else if (bytemode == x_mode)
 	{
 	  switch (vex.length)
 	    {
@@ -11803,6 +11815,9 @@ OP_E_memory (int bytemode, int sizeflag)
 	      abort ();
 	    }
 	}
+      else
+	/* If operand doesn't allow broadcast, vex.b should be 0.  */
+	oappend ("{bad}");
     }
 }
 
@@ -13495,24 +13510,25 @@ MOVSXD_Fixup (int bytemode, int sizeflag
 static void
 OP_Rounding (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
 {
-  if (modrm.mod == 3 && vex.b)
-    switch (bytemode)
-      {
-      case evex_rounding_64_mode:
-	if (address_mode != mode_64bit || !vex.w)
-	  {
-	    oappend ("(bad)");
-	    break;
-	  }
-	/* Fall through.  */
-      case evex_rounding_mode:
-	oappend (names_rounding[vex.ll]);
-	break;
-      case evex_sae_mode:
-	oappend ("{sae}");
-	break;
-      default:
-	abort ();
-	break;
-      }
+  if (modrm.mod != 3 || !vex.b)
+    return;
+
+  switch (bytemode)
+    {
+    case evex_rounding_64_mode:
+      if (address_mode != mode_64bit || !vex.w)
+        return;
+      /* Fall through.  */
+    case evex_rounding_mode:
+      evex_used |= EVEX_b_used;
+      oappend (names_rounding[vex.ll]);
+      break;
+    case evex_sae_mode:
+      evex_used |= EVEX_b_used;
+      oappend ("{");
+      break;
+    default:
+      abort ();
+    }
+  oappend ("sae}");
 }


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

* Re: [PATCH] x86: express unduly set rounding control bits in disassembly
  2021-07-22 13:44 [PATCH] x86: express unduly set rounding control bits in disassembly Jan Beulich
@ 2021-07-22 13:52 ` H.J. Lu
  0 siblings, 0 replies; 2+ messages in thread
From: H.J. Lu @ 2021-07-22 13:52 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Binutils

On Thu, Jul 22, 2021 at 6:44 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> While EVEX.L'L are indeed ignored when EVEX.b stands for just SAE,
> EVEX.b itself is not ignored when an insn permits neither rounding
> control nor SAE.
>
> While changing this aspect of EVEX.b handling, also alter unduly set
> embedded broadcast: Don't call BadOp(), screwing up subsequent
> disassembly, but emit "{bad}" instead.
>
> --- a/gas/testsuite/gas/i386/avx512f-nondef.d
> +++ b/gas/testsuite/gas/i386/avx512f-nondef.d
> @@ -10,12 +10,11 @@ Disassembly of section .text:
>  0+ <.text>:
>  [      ]*[a-f0-9]+:    62 f3 d5 1f 0b f4 7b    vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
>  [      ]*[a-f0-9]+:    62 f3 d5 5f 0b f4 7b    vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
> -[      ]*[a-f0-9]+:    62 f2 55 1f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> -[      ]*[a-f0-9]+:    62 c2 55 1f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> +[      ]*[a-f0-9]+:    62 f2 55 4f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> +[      ]*[a-f0-9]+:    62 c2 55 4f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> +[      ]*[a-f0-9]+:    62 f2 55 1f 3b f4       vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\}
>  [      ]*[a-f0-9]+:    62 f2 7e 48 31 72 7f    vpmovdb %zmm6,0x7f0\(%edx\)
> -[      ]*[a-f0-9]+:    62                      vpmovdb %zmm6,\(bad\)
> -[      ]*[a-f0-9]+:    f2 7e 58                bnd jle (0x7d|7d <.text\+0x7d>)
> -[      ]*[a-f0-9]+:    31 72 7f                xor    %esi,0x7f\(%edx\)
> +[      ]*[a-f0-9]+:    62 f2 7e 58 31 72 7f    vpmovdb %zmm6,0x7f0\(%edx\)\{bad\}
>  [      ]*[a-f0-9]+:    62 f1 7c 88 58          \(bad\)
>  [      ]*[a-f0-9]+:    c3                      ret *
>  [      ]*[a-f0-9]+:    62 f2 7d 4f 92 01       vgatherdps \(bad\),%zmm0\{%k7\}
> --- a/gas/testsuite/gas/i386/avx512f-nondef.s
> +++ b/gas/testsuite/gas/i386/avx512f-nondef.s
> @@ -5,13 +5,15 @@
>  .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b
>  # vrndscalesd  {sae}, $123, %xmm4, %xmm5, %xmm6{%k7}    # with not-null RC
>  .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b
> -# vpminud      %zmm4, %zmm5, %zmm6{%k7}         # with 111 REX
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with 11 EVEX.{B,R'}
> +.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with not-11 EVEX.{B,R'}
> +.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with set EVEX.b bit
>  .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4
> -# vpminud      %zmm4, %zmm5, %zmm6{%k7}         # with not-111 REX
> -.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4
> -# vpmovdb      %zmm6, 2032(%rdx) # with unset EVEX.B bit
> +# vpmovdb      %zmm6, 2032(%rdx)               # with unset EVEX.b bit
>  .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f
> -# vpmovdb      %zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand
> +# vpmovdb      %zmm6, 2032(%rdx)               # with set EVEX.b bit - we should get (bad) operand
>  .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f
>  # vaddps xmm0, xmm0, xmm3 # with EVEX.z set
>  .byte 0x62, 0xf1, 0x7c, 0x88, 0x58, 0xc3
> --- a/gas/testsuite/gas/i386/evex.d
> +++ b/gas/testsuite/gas/i386/evex.d
> @@ -8,14 +8,14 @@ Disassembly of section .text:
>
>  0+ <_start>:
>   +[a-f0-9]+:   62 f1 d6 38 2a f0       vcvtsi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 57 38 2a f0       vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 d7 38 2a f0       vcvtsi2sdl %eax,\(bad\),%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 57 38 2a f0       vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 d7 38 2a f0       vcvtsi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d6 08 7b f0       vcvtusi2ssl %eax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 57 08 7b f0       vcvtusi2sdl %eax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d7 08 7b f0       vcvtusi2sdl %eax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d6 38 7b f0       vcvtusi2ssl %eax,\{rd-sae\},%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 57 38 7b f0       vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 d7 38 7b f0       vcvtusi2sdl %eax,\(bad\),%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 57 38 7b f0       vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 d7 38 7b f0       vcvtusi2sdl %eax,\{rd-bad\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 e1 7e 08 2d c0       vcvtss2si %xmm0,%eax
>   +[a-f0-9]+:   62 e1 7c 08 c2 c0 00    vcmpeqps %xmm0,%xmm0,%k0
>  #pass
> --- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d
> +++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.d
> @@ -10,10 +10,9 @@ Disassembly of section .text:
>  0+ <.text>:
>  [      ]*[a-f0-9]+:    62 f3 d5 1f 0b f4 7b    vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
>  [      ]*[a-f0-9]+:    62 f3 d5 5f 0b f4 7b    vrndscalesd \$0x7b,\{sae\},%xmm4,%xmm5,%xmm6\{%k7\}
> -[      ]*[a-f0-9]+:    62 f2 55 1f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> -[      ]*[a-f0-9]+:    62 c2 55 1f 3b f4       vpminud %zmm12,%zmm5,%zmm22\{%k7\}
> +[      ]*[a-f0-9]+:    62 f2 55 4f 3b f4       vpminud %zmm4,%zmm5,%zmm6\{%k7\}
> +[      ]*[a-f0-9]+:    62 c2 55 4f 3b f4       vpminud %zmm12,%zmm5,%zmm22\{%k7\}
> +[      ]*[a-f0-9]+:    62 f2 55 1f 3b f4       vpminud \{rn-bad\},%zmm4,%zmm5,%zmm6\{%k7\}
>  [      ]*[a-f0-9]+:    62 f2 7e 48 31 72 7f    vpmovdb %zmm6,0x7f0\(%rdx\)
> -[      ]*[a-f0-9]+:    62                      vpmovdb %zmm6,\(bad\)
> -[      ]*[a-f0-9]+:    f2 7e 58                bnd jle (0x7d|7d <.text\+0x7d>)
> -[      ]*[a-f0-9]+:    31 72 7f                xor    %esi,0x7f\(%rdx\)
> +[      ]*[a-f0-9]+:    62 f2 7e 58 31 72 7f    vpmovdb %zmm6,0x7f0\(%rdx\)\{bad\}
>  #pass
> --- a/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s
> +++ b/gas/testsuite/gas/i386/x86-64-avx512f-nondef.s
> @@ -5,11 +5,13 @@
>  .byte 0x62, 0xf3, 0xd5, 0x1f, 0x0b, 0xf4, 0x7b
>  # vrndscalesd  {sae}, $123, %xmm4, %xmm5, %xmm6{%k7}    # with not-null RC
>  .byte 0x62, 0xf3, 0xd5, 0x5f, 0x0b, 0xf4, 0x7b
> -# vpminud      %zmm4, %zmm5, %zmm6{%k7}         # with 111 REX
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with 11 EVEX.{B,R'}
> +.byte 0x62, 0xf2, 0x55, 0x4f, 0x3b, 0xf4
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with not-11 EVEX.{B,R'}
> +.byte 0x62, 0xc2, 0x55, 0x4f, 0x3b, 0xf4
> +# vpminud      %zmm4, %zmm5, %zmm6{%k7}        # with set EVEX.b bit
>  .byte 0x62, 0xf2, 0x55, 0x1f, 0x3b, 0xf4
> -# vpminud      %zmm4, %zmm5, %zmm6{%k7}         # with not-111 REX
> -.byte 0x62, 0xc2, 0x55, 0x1f, 0x3b, 0xf4
> -# vpmovdb      %zmm6, 2032(%rdx) # with unset EVEX.B bit
> +# vpmovdb      %zmm6, 2032(%rdx)               # with unset EVEX.b bit
>  .byte 0x62, 0xf2, 0x7e, 0x48, 0x31, 0x72, 0x7f
> -# vpmovdb      %zmm6, 2032(%rdx) # with set EVEX.B bit - we should get (bad) operand
> +# vpmovdb      %zmm6, 2032(%rdx)               # with set EVEX.b bit - we should get (bad) operand
>  .byte 0x62, 0xf2, 0x7e, 0x58, 0x31, 0x72, 0x7f
> --- a/gas/testsuite/gas/i386/x86-64-evex.d
> +++ b/gas/testsuite/gas/i386/x86-64-evex.d
> @@ -9,13 +9,13 @@ Disassembly of section .text:
>
>  0+ <_start>:
>   +[a-f0-9]+:   62 f1 d6 38 2a f0       vcvtsi2ss %rax,\{rd-sae\},%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 57 38 2a f0       vcvtsi2sd %eax,\(bad\),%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 57 38 2a f0       vcvtsi2sd %eax,\{rd-bad\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d7 38 2a f0       vcvtsi2sd %rax,\{rd-sae\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d6 08 7b f0       vcvtusi2ss %rax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 57 08 7b f0       vcvtusi2sd %eax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d7 08 7b f0       vcvtusi2sd %rax,%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d6 38 7b f0       vcvtusi2ss %rax,\{rd-sae\},%xmm5,%xmm6
> - +[a-f0-9]+:   62 f1 57 38 7b f0       vcvtusi2sd %eax,\(bad\),%xmm5,%xmm6
> + +[a-f0-9]+:   62 f1 57 38 7b f0       vcvtusi2sd %eax,\{rd-bad\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 f1 d7 38 7b f0       vcvtusi2sd %rax,\{rd-sae\},%xmm5,%xmm6
>   +[a-f0-9]+:   62 e1 7e 08 2d c0       vcvtss2si %xmm0,\(bad\)
>   +[a-f0-9]+:   62 e1 7c 08 c2 c0 00    vcmpeqps %xmm0,%xmm0,\(bad\)
> --- a/opcodes/i386-dis.c
> +++ b/opcodes/i386-dis.c
> @@ -159,6 +159,11 @@ static int rex_used;
>     current instruction.  */
>  static int used_prefixes;
>
> +/* Flags for EVEX bits which we somehow handled when printing the
> +   current instruction.  */
> +#define EVEX_b_used 1
> +static int evex_used;
> +
>  /* Flags stored in PREFIXES.  */
>  #define PREFIX_REPZ 1
>  #define PREFIX_REPNZ 2
> @@ -2524,12 +2529,12 @@ static const char *att_names_mask[] = {
>    "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7"
>  };
>
> -static const char *names_rounding[] =
> +static const char *const names_rounding[] =
>  {
> -  "{rn-sae}",
> -  "{rd-sae}",
> -  "{ru-sae}",
> -  "{rz-sae}"
> +  "{rn-",
> +  "{rd-",
> +  "{ru-",
> +  "{rz-"
>  };
>
>  static const struct dis386 reg_table[][8] = {
> @@ -8578,6 +8583,7 @@ ckprefix (void)
>    prefixes = 0;
>    used_prefixes = 0;
>    rex_used = 0;
> +  evex_used = 0;
>    last_lock_prefix = -1;
>    last_repz_prefix = -1;
>    last_repnz_prefix = -1;
> @@ -9661,6 +9667,21 @@ print_insn (bfd_vma pc, disassemble_info
>                     oappend ("/(bad)");
>                 }
>             }
> +
> +         /* Check whether rounding control was enabled for an insn not
> +            supporting it.  */
> +         if (modrm.mod == 3 && vex.b && !(evex_used & EVEX_b_used))
> +           {
> +             for (i = 0; i < MAX_OPERANDS; ++i)
> +               {
> +                 obufp = op_out[i];
> +                 if (*obufp)
> +                   continue;
> +                 oappend (names_rounding[vex.ll]);
> +                 oappend ("bad}");
> +                 break;
> +               }
> +           }
>         }
>      }
>
> @@ -11316,14 +11337,6 @@ OP_E_memory (int bytemode, int sizeflag)
>
>    if (vex.evex)
>      {
> -      /* In EVEX, if operand doesn't allow broadcast, vex.b should be 0.  */
> -      if (vex.b
> -         && bytemode != x_mode
> -         && bytemode != evex_half_bcst_xmmq_mode)
> -       {
> -         BadOp ();
> -         return;
> -       }
>        switch (bytemode)
>         {
>         case dw_mode:
> @@ -11764,10 +11777,9 @@ OP_E_memory (int bytemode, int sizeflag)
>           oappend (scratchbuf);
>         }
>      }
> -  if (vex.b
> -      && (bytemode == x_mode
> -         || bytemode == evex_half_bcst_xmmq_mode))
> +  if (vex.b)
>      {
> +      evex_used |= EVEX_b_used;
>        if (vex.w
>           || bytemode == evex_half_bcst_xmmq_mode)
>         {
> @@ -11786,7 +11798,7 @@ OP_E_memory (int bytemode, int sizeflag)
>               abort ();
>             }
>         }
> -      else
> +      else if (bytemode == x_mode)
>         {
>           switch (vex.length)
>             {
> @@ -11803,6 +11815,9 @@ OP_E_memory (int bytemode, int sizeflag)
>               abort ();
>             }
>         }
> +      else
> +       /* If operand doesn't allow broadcast, vex.b should be 0.  */
> +       oappend ("{bad}");
>      }
>  }
>
> @@ -13495,24 +13510,25 @@ MOVSXD_Fixup (int bytemode, int sizeflag
>  static void
>  OP_Rounding (int bytemode, int sizeflag ATTRIBUTE_UNUSED)
>  {
> -  if (modrm.mod == 3 && vex.b)
> -    switch (bytemode)
> -      {
> -      case evex_rounding_64_mode:
> -       if (address_mode != mode_64bit || !vex.w)
> -         {
> -           oappend ("(bad)");
> -           break;
> -         }
> -       /* Fall through.  */
> -      case evex_rounding_mode:
> -       oappend (names_rounding[vex.ll]);
> -       break;
> -      case evex_sae_mode:
> -       oappend ("{sae}");
> -       break;
> -      default:
> -       abort ();
> -       break;
> -      }
> +  if (modrm.mod != 3 || !vex.b)
> +    return;
> +
> +  switch (bytemode)
> +    {
> +    case evex_rounding_64_mode:
> +      if (address_mode != mode_64bit || !vex.w)
> +        return;
> +      /* Fall through.  */
> +    case evex_rounding_mode:
> +      evex_used |= EVEX_b_used;
> +      oappend (names_rounding[vex.ll]);
> +      break;
> +    case evex_sae_mode:
> +      evex_used |= EVEX_b_used;
> +      oappend ("{");
> +      break;
> +    default:
> +      abort ();
> +    }
> +  oappend ("sae}");
>  }
>

OK.

Thanks.

-- 
H.J.

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

end of thread, other threads:[~2021-07-22 13:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-22 13:44 [PATCH] x86: express unduly set rounding control bits in disassembly Jan Beulich
2021-07-22 13:52 ` 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).