[PATCH] x86: fix EVEX no-broadcast disassembly when W=1
Rohan Shenoy
RohanRadhesh.Shenoy@amd.com
Sat Sep 5 09:46:51 GMT 2026
For operands with no-broadcast, EVEX.b if set is invalid. The
disassembler correctly identifies this for W=0, but for the W=1 path it
fails to do this. For example, the assembler rejects
vmovdqu64 (%rcx){1to8}, %zmm1
but objdump wrongly accepts its corresponding broadcast encoding,
62 f1 fe 58 6f 09 vmovdqu64 (%rcx){1to8},%zmm1
instead of emitting {bad}.
This commit marks evex_x_nobcst_mode as non-broadcastable before the
EVEX.W-dependent path.
---
gas/testsuite/gas/i386/bad-bcast-intel.d | 1 +
gas/testsuite/gas/i386/bad-bcast.d | 2 ++
gas/testsuite/gas/i386/bad-bcast.s | 2 ++
opcodes/i386-dis.c | 3 +++
4 files changed, 8 insertions(+)
diff --git a/gas/testsuite/gas/i386/bad-bcast-intel.d b/gas/testsuite/gas/i386/bad-bcast-intel.d
index 29de3de299c..d4f50acf647 100644
--- a/gas/testsuite/gas/i386/bad-bcast-intel.d
+++ b/gas/testsuite/gas/i386/bad-bcast-intel.d
@@ -12,4 +12,5 @@ Disassembly of section .text:
[ ]*[a-f0-9]+:[ ]*66 90\s*xchg ax,ax
[ ]*[a-f0-9]+:[ ]*66 90\s*xchg ax,ax
[ ]*[a-f0-9]+:[ ]*62 c1 ff 38 2a 20\s*vcvtsi2sd xmm4,xmm0,\[eax\]{bad}
+[ ]*[a-f0-9]+:[ ]*62 f1 fe 58 6f 09\s*vmovdqu64 zmm1,\[ecx\]{bad}
#pass
diff --git a/gas/testsuite/gas/i386/bad-bcast.d b/gas/testsuite/gas/i386/bad-bcast.d
index 4f829259994..3f20c32f2c2 100644
--- a/gas/testsuite/gas/i386/bad-bcast.d
+++ b/gas/testsuite/gas/i386/bad-bcast.d
@@ -12,3 +12,5 @@ Disassembly of section .text:
+[a-f0-9]+: 66 90\s+xchg %ax,%ax
+[a-f0-9]+: 66 90\s+xchg %ax,%ax
+[a-f0-9]+: 62 c1 ff 38 2a 20\s+vcvtsi2sd \(%eax\){bad},%xmm0,%xmm4
+ +[a-f0-9]+: 62 f1 fe 58 6f 09\s+vmovdqu64 \(%ecx\){bad},%zmm1
+#pass
diff --git a/gas/testsuite/gas/i386/bad-bcast.s b/gas/testsuite/gas/i386/bad-bcast.s
index 6c55dcbbbd8..a63f1a14bbd 100644
--- a/gas/testsuite/gas/i386/bad-bcast.s
+++ b/gas/testsuite/gas/i386/bad-bcast.s
@@ -3,3 +3,5 @@
.byte 0x62, 0xc3, 0x8c, 0x1d, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90
# Invalid vcvtsi2sd with EVEX.b == 1.
.byte 0x62,0xc1,0xff,0x38,0x2a,0x20
+# Invalid vmovdqu64 with EVEX.b == 1.
+ .byte 0x62,0xf1,0xfe,0x58,0x6f,0x09
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index ec1d149d9dc..d75fe8d551d 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -12747,6 +12747,9 @@ OP_E_memory (instr_info *ins, int bytemode, int sizeflag)
{
ins->evex_used |= EVEX_b_used;
+ if (bytemode == evex_x_nobcst_mode)
+ ins->vex.no_broadcast = true;
+
/* Broadcast can only ever be valid for memory sources. */
if (ins->obufp == ins->op_out[0])
ins->vex.no_broadcast = true;
--
2.34.1
More information about the Binutils
mailing list