From: Jan Beulich Date: Fri, 17 Apr 2026 06:06:39 +0000 (+0200) Subject: x86: refine special casing of insns with MSR as immediate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=925926577a460ef2fc170e0261f8b207a42bc0e0;p=thirdparty%2Fbinutils-gdb.git 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 --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index bc759b2573a..fb77f43126b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -7305,7 +7305,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 @@ -7315,10 +7317,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 (); } @@ -8522,7 +8521,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)