[binutils-gdb] x86: flag EVEX.z set when destination is a mask register
Jan Beulich
jbeulich@sourceware.org
Tue Jul 4 15:02:34 GMT 2023
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3
commit ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3
Author: Jan Beulich <jbeulich@suse.com>
Date: Tue Jul 4 17:00:35 2023 +0200
x86: flag EVEX.z set when destination is a mask register
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.
Diff:
---
gas/testsuite/gas/i386/avx512f-nondef.d | 1 +
gas/testsuite/gas/i386/avx512f-nondef.s | 3 +++
opcodes/i386-dis.c | 12 ++++++++++++
3 files changed, 16 insertions(+)
diff --git a/gas/testsuite/gas/i386/avx512f-nondef.d b/gas/testsuite/gas/i386/avx512f-nondef.d
index 8defd6972e5..efa3f58a621 100644
--- a/gas/testsuite/gas/i386/avx512f-nondef.d
+++ b/gas/testsuite/gas/i386/avx512f-nondef.d
@@ -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
diff --git a/gas/testsuite/gas/i386/avx512f-nondef.s b/gas/testsuite/gas/i386/avx512f-nondef.s
index a1175929474..0216003f347 100644
--- a/gas/testsuite/gas/i386/avx512f-nondef.s
+++ b/gas/testsuite/gas/i386/avx512f-nondef.s
@@ -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}
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 690e336c6bc..e440b694f1a 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -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)");
}
}
More information about the Binutils-cvs
mailing list