x86: express unduly set rounding control bits in disassembly
authorJan Beulich <jbeulich@suse.com>
Fri, 23 Jul 2021 06:03:21 +0000 (08:03 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 23 Jul 2021 06:03:21 +0000 (08:03 +0200)
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.

gas/testsuite/gas/i386/avx512f-nondef.d
gas/testsuite/gas/i386/avx512f-nondef.s
gas/testsuite/gas/i386/evex.d
gas/testsuite/gas/i386/x86-64-avx512f-nondef.d
gas/testsuite/gas/i386/x86-64-avx512f-nondef.s
gas/testsuite/gas/i386/x86-64-evex.d
opcodes/i386-dis.c

index f19edceb6bb255cdce37c17c0437e7e0f3568fcd..07ffe60e1771ec8cbb27d740ccaf91b92f6df3c2 100644 (file)
@@ -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\}
index 676c4e0fe4bf799966a56c3a739975f3c5731bfd..96d0466624841e5f3e21fdbe51c113673b83855d 100644 (file)
@@ -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
index 367b2eb13211b650496bf9354f051d2ed529202d..4afcc6db7280e446d90c903760ebad4dd4849e47 100644 (file)
@@ -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
index bce2d80588d1443d783a936d7fd8a2f723e4f3d1..e8ddfd58870a0ce08a6861384a9359b44594cad2 100644 (file)
@@ -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
index 255d2c931f155fe88b579bb3c9979162dbeca180..952f2db76b37f81859a2dcd563bd7359ce97702e 100644 (file)
@@ -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
index 3a7b48e0bf93d7e0da36ba57113c3f4fbbe84e0b..041747db892809d9a24e0b3d476682410bfa8eab 100644 (file)
@@ -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\)
index 521d68993386d9abe3410d9de10b10e23b673a55..b25a9f324c05c0e68ef78dfcf06561f7eb60df66 100644 (file)
@@ -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 *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}");
 }