[binutils-gdb/binutils-2_46-branch] x86: refine special casing of insns with MSR as immediate
Jan Beulich
jbeulich@sourceware.org
Fri Apr 17 06:33:21 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=155188ea10a78d18416b8c0f62e17da66d8385a7
commit 155188ea10a78d18416b8c0f62e17da66d8385a7
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri Apr 17 08:06:39 2026 +0200
x86: refine special casing of insns with MSR as immediate
PR gas/34028
i.op[].imms is legitimate to de-reference only when the operand actually
is an immediate. The pointer happens to be non-NULL for most other operand
kinds (i.e. a deref is UB, but would likely not fault), just not for
memory operands without displacement.
Leverage that the to-be-special-cased insns all only have just a single
immediate, and leverage further that after the immediately preceding
swapping of operands valid immediates will come first. Hence the
conditional can be adjusted to satisfy the criteria above, and no loop is
needed at all.
With the conditional changed, leverage the property also in optimize_imm()
itself, reducing the number of loop iterations.
Diff:
---
gas/config/tc-i386.c | 11 +++++------
gas/testsuite/gas/i386/x86-64-msr_imm-inval.l | 4 +++-
gas/testsuite/gas/i386/x86-64-msr_imm-inval.s | 2 ++
gas/testsuite/gas/i386/x86-64-user_msr-inval.l | 4 +++-
gas/testsuite/gas/i386/x86-64-user_msr-inval.s | 2 ++
5 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index ca4523fe2cd..0b98509e0d6 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7303,7 +7303,9 @@ i386_assemble (char *line)
&& i.imm_operands && i.operands > i.imm_operands))
swap_2_operands (0, 1);
- if (i.imm_operands)
+ /* All legitimate immediates are placed first now. Others, if any, will be
+ rejected by match_template() anyway. */
+ if (operand_type_check (i.types[0], imm))
{
/* For USER_MSR and MSR_IMM instructions, imm32 stands for the name of a
model specific register (MSR). That's an unsigned quantity, whereas all
@@ -7313,10 +7315,7 @@ i386_assemble (char *line)
if (is_cpu(current_templates.start, CpuUSER_MSR)
|| t->mnem_off == MN_rdmsr
|| t->mnem_off == MN_wrmsrns)
- {
- for (j = 0; j < i.imm_operands; j++)
- i.types[j] = smallest_imm_type (i.op[j].imms->X_add_number);
- }
+ i.types[0] = smallest_imm_type (i.op[0].imms->X_add_number);
else
optimize_imm ();
}
@@ -8520,7 +8519,7 @@ optimize_imm (void)
&& current_templates.start->mnem_off != MN_jmpabs))
guess_suffix = LONG_MNEM_SUFFIX;
- for (op = i.operands; --op >= 0;)
+ for (op = i.imm_operands; --op >= 0;)
if (operand_type_check (i.types[op], imm))
{
switch (i.op[op].imms->X_op)
diff --git a/gas/testsuite/gas/i386/x86-64-msr_imm-inval.l b/gas/testsuite/gas/i386/x86-64-msr_imm-inval.l
index 6825a145984..bbafdb47844 100644
--- a/gas/testsuite/gas/i386/x86-64-msr_imm-inval.l
+++ b/gas/testsuite/gas/i386/x86-64-msr_imm-inval.l
@@ -1,5 +1,7 @@
.* Assembler messages:
.*:5: Error: operand type mismatch for `rdmsr'
.*:6: Error: operand type mismatch for `rdmsr'
-.*:7: Error: operand type mismatch for `wrmsrns'
+.*:7: Error: operand type mismatch for `rdmsr'
.*:8: Error: operand type mismatch for `wrmsrns'
+.*:9: Error: operand type mismatch for `wrmsrns'
+.*:10: Error: operand type mismatch for `wrmsrns'
diff --git a/gas/testsuite/gas/i386/x86-64-msr_imm-inval.s b/gas/testsuite/gas/i386/x86-64-msr_imm-inval.s
index e12e5be392f..6a245bcbcf6 100644
--- a/gas/testsuite/gas/i386/x86-64-msr_imm-inval.s
+++ b/gas/testsuite/gas/i386/x86-64-msr_imm-inval.s
@@ -4,5 +4,7 @@
_start:
rdmsr $5151515151515151, %r12
rdmsr $-515151, %r12
+ rdmsr (%rax), $0
wrmsrns %r12, $5151515151515151
wrmsrns %r12, $-515151
+ wrmsrns $0, (%rax)
diff --git a/gas/testsuite/gas/i386/x86-64-user_msr-inval.l b/gas/testsuite/gas/i386/x86-64-user_msr-inval.l
index 9eb3044e16e..59383063c89 100644
--- a/gas/testsuite/gas/i386/x86-64-user_msr-inval.l
+++ b/gas/testsuite/gas/i386/x86-64-user_msr-inval.l
@@ -3,7 +3,9 @@
.*:6: Error: operand type mismatch for `urdmsr'
.*:7: Error: operand type mismatch for `urdmsr'
.*:8: Error: operand type mismatch for `urdmsr'
-.*:9: Error: operand type mismatch for `uwrmsr'
+.*:9: Error: operand type mismatch for `urdmsr'
.*:10: Error: operand type mismatch for `uwrmsr'
.*:11: Error: operand type mismatch for `uwrmsr'
.*:12: Error: operand type mismatch for `uwrmsr'
+.*:13: Error: operand type mismatch for `uwrmsr'
+.*:14: Error: operand type mismatch for `uwrmsr'
diff --git a/gas/testsuite/gas/i386/x86-64-user_msr-inval.s b/gas/testsuite/gas/i386/x86-64-user_msr-inval.s
index e7b6d6eea83..ac22391baa3 100644
--- a/gas/testsuite/gas/i386/x86-64-user_msr-inval.s
+++ b/gas/testsuite/gas/i386/x86-64-user_msr-inval.s
@@ -6,7 +6,9 @@ _start:
urdmsr $-32767, %r14
urdmsr $-2147483648, %r14
urdmsr $0x7fffffffffffffff, %r14
+ urdmsr (%rax), $0
uwrmsr %r12, $-1
uwrmsr %r12, $-32767
uwrmsr %r12, $-2147483648
uwrmsr %r12, $0x7fffffffffffffff
+ uwrmsr $0, (%rax)
More information about the Binutils-cvs
mailing list