aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2022-01-14 10:55:17 +0100
committerJan Beulich <jbeulich@suse.com>2022-01-14 10:55:17 +0100
commita364447b5ecf58a60a2ba99a5d31b984d0443152 (patch)
tree45364b2404d3198c7017704becd906124fcfc2a9 /opcodes
parent740a1e791175987e28cc39dbd11e3fc152ffc40b (diff)
downloadbinutils-a364447b5ecf58a60a2ba99a5d31b984d0443152.zip
binutils-a364447b5ecf58a60a2ba99a5d31b984d0443152.tar.gz
binutils-a364447b5ecf58a60a2ba99a5d31b984d0443152.tar.bz2
x86: record further wrong uses of EVEX.b
For one EVEX.W set does not imply EVEX.b is uniformly valid. Reject it for modes which occur for insns allowing for EVEX.W to be set (noticed with VMOV{H,L}PD and VMOVDDUP, and only in AT&T mode, but not checked whether further insns would also have been impacted; I expect e.g. VCMPSD would have had the same issue). And then the present concept of broadcast makes no sense at all when the memory operand of an insn is the destination.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/i386-dis.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index ad560b1..ffb548c 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -11899,6 +11899,11 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag)
if (ins->vex.b)
{
ins->evex_used |= EVEX_b_used;
+
+ /* Broadcast can only ever be valid for memory sources. */
+ if (ins->obufp == ins->op_out[0])
+ ins->vex.no_broadcast = 1;
+
if (!ins->vex.no_broadcast)
{
if (bytemode == xh_mode)
@@ -11923,6 +11928,9 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag)
}
}
}
+ else if (bytemode == q_mode
+ || bytemode == ymmq_mode)
+ ins->vex.no_broadcast = 1;
else if (ins->vex.w
|| bytemode == evex_half_bcst_xmmqdh_mode
|| bytemode == evex_half_bcst_xmmq_mode)