diff options
author | Jan Beulich <jbeulich@suse.com> | 2023-07-04 17:00:35 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2023-07-04 17:00:35 +0200 |
commit | ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3 (patch) | |
tree | 7f4a8e63421cf4293e1fc9569434c64342614b33 /opcodes | |
parent | 07d618b91f50816f198abac7df116e83d47ca1be (diff) | |
download | gdb-ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3.zip gdb-ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3.tar.gz gdb-ac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3.tar.bz2 |
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.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/i386-dis.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 690e336..e440b69 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)"); } } |