aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2023-07-04 17:00:35 +0200
committerJan Beulich <jbeulich@suse.com>2023-07-04 17:00:35 +0200
commitac500f1772cfd5b1cf92acfa3ea4e7c43fab4fe3 (patch)
tree7f4a8e63421cf4293e1fc9569434c64342614b33 /opcodes
parent07d618b91f50816f198abac7df116e83d47ca1be (diff)
downloadgdb-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.c12
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)");
}
}