x86: flag EVEX.z set when destination is a mask register
authorJan Beulich <jbeulich@suse.com>
Tue, 4 Jul 2023 15:00:35 +0000 (17:00 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 4 Jul 2023 15:00:35 +0000 (17:00 +0200)
While only zeroing-masking is possible in this case, this still requires
EVEX.z to be clear. Introduce a "global" flag right here, to be re-used
by checks which need to live in specific operand handlers.

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

index 8defd6972e510651685c2c7e41f711cddbeffae6..efa3f58a621af91729490f4bcd41c4a5e941eb31 100644 (file)
@@ -20,4 +20,5 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    67 62 f2 7d 4f 92 01    addr16 vgatherdps \(bad\),%zmm0\{%k7\}
 [      ]*[a-f0-9]+:    62 f2 7d cf 92 04 08    vgatherdps \(%eax,%zmm1(,1)?\),%zmm0\{%k7\}\{z\}/\(bad\)
 [      ]*[a-f0-9]+:    62 f2 7d 48 92 04 08    vgatherdps \(%eax,%zmm1(,1)?\),%zmm0/\(bad\)
+[      ]*[a-f0-9]+:    62 f1 7c cf c2 c0 00    vcmpeqps %zmm0,%zmm0,%k0\{%k7\}\{z\}/\(bad\)
 #pass
index a1175929474f48b941cf49f8d16e59b5f7d6288d..0216003f347d2b4be3a6f00742bfc55afae6ae01 100644 (file)
@@ -26,3 +26,6 @@
        .insn EVEX.66.0F38.W0 0x92, (%eax,%zmm1), %zmm0{%k7}{z}
 # vgatherdps (%eax,%zmm1), %zmm0               # without actual mask register
        .insn EVEX.66.0F38.W0 0x92, (%eax,%zmm1), %zmm0
+
+       # vcmpeqps %zmm0, %zmm0, %k0{%k7} with EVEX.z set
+       .insn EVEX.0f 0xc2, $0, %zmm0, %zmm0, %k0{%k7}{z}
index 690e336c6bc0ae65c738dd4304ce3ffa9bf4e665..e440b694f1abbd8cafb91e726b00476cabc16327 100644 (file)
@@ -219,6 +219,9 @@ struct instr_info
 
   bool two_source_ops;
 
+  /* Record whether EVEX masking is used incorrectly.  */
+  bool illegal_masking;
+
   unsigned char op_ad;
   signed char op_index[MAX_OPERANDS];
   bool op_riprel[MAX_OPERANDS];
@@ -9915,12 +9918,21 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax)
                      continue;
                    }
 
+                 /* Instructions with a mask register destination allow for
+                    zeroing-masking only (if any masking at all), which is
+                    _not_ expressed by EVEX.z.  */
+                 if (ins.vex.zeroing && dp->op[0].bytemode == mask_mode)
+                   ins.illegal_masking = true;
+
                  /* S/G insns require a mask and don't allow
                     zeroing-masking.  */
                  if ((dp->op[0].bytemode == vex_vsib_d_w_dq_mode
                       || dp->op[0].bytemode == vex_vsib_q_w_dq_mode)
                      && (ins.vex.mask_register_specifier == 0
                          || ins.vex.zeroing))
+                   ins.illegal_masking = true;
+
+                 if (ins.illegal_masking)
                    oappend (&ins, "/(bad)");
                }
            }