From 73e50a730694575b3e15e1fdbf35a802888c0aa1 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 16 May 2025 10:26:45 +0200 Subject: [PATCH] x86: improve matching diagnostics Many times in the past I was puzzled by seeing "operand size mismatch" when really "operand type mismatch" would be far more appropriate. As it turns out, there were at least two flaws: In the single operand case we didn't propagate i.error to match_template()'s local specific_error when noticing a type mismatch. And then operand_size_match() was too eager in invoking match_mem_size(): Especially the Unspecified attribute can get in the way there when the expected operand isn't a memory one (and hence Unspecified would not be set in the operand template, whereas it's uniformly set for memory operands in AT&T syntax). (In the x86-64-lkgs-inval testcase the particular error for the two bogus Intel syntax forms doesn't really matter; all we ought to care about there isthat there is _some_ error.) --- gas/config/tc-i386.c | 13 ++++++++++--- gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/inval-type.l | 6 ++++++ gas/testsuite/gas/i386/inval-type.s | 10 ++++++++++ .../gas/i386/x86-64-apx-pushp-popp-inval.l | 4 ++-- gas/testsuite/gas/i386/x86-64-lkgs-inval.l | 4 ++-- 6 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/i386/inval-type.l create mode 100644 gas/testsuite/gas/i386/inval-type.s diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 9671c642178..15f274f6e5b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2630,7 +2630,9 @@ operand_size_match (const insn_template *t) break; } - if ((i.flags[j] & Operand_Mem) && !match_mem_size (t, j, j)) + if ((i.flags[j] & Operand_Mem) + && operand_type_check (t->operand_types[j], anymem) + && !match_mem_size (t, j, j)) { match = 0; break; @@ -2667,7 +2669,9 @@ operand_size_match (const insn_template *t) || !match_simd_size (t, j, given))) return match; - if ((i.flags[given] & Operand_Mem) && !match_mem_size (t, j, given)) + if ((i.flags[given] & Operand_Mem) + && operand_type_check (t->operand_types[j], anymem) + && !match_mem_size (t, j, given)) return match; } @@ -9363,7 +9367,10 @@ match_template (char mnem_suffix) { case 1: if (!operand_type_match (overlap0, i.types[0])) - continue; + { + specific_error = progress (i.error); + continue; + } /* Allow the ModR/M encoding to be requested by using the {load} or {store} pseudo prefix on an applicable insn. */ diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index d48dd8902f9..b068b327af3 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -833,6 +833,7 @@ if {![istarget "i*86-*-elfiamcu"] && [gas_64_check]} then { } run_list_test "string-bad" "" run_list_test "reg-bad" "" +run_list_test "inval-type" run_list_test "space1" "-al" if {![istarget "i*86-*-elfiamcu"]} then { run_list_test "xmmword" diff --git a/gas/testsuite/gas/i386/inval-type.l b/gas/testsuite/gas/i386/inval-type.l new file mode 100644 index 00000000000..5784949e0f9 --- /dev/null +++ b/gas/testsuite/gas/i386/inval-type.l @@ -0,0 +1,6 @@ +.*: Assembler messages: +.*: Error: operand type mismatch for .bsf. +.*: Error: operand type mismatch for .bswap. +.*: Error: operand type mismatch for .bswap. +.*: Error: operand type mismatch for .movntdqa. +.*: Error: operand type mismatch for .movntdq. diff --git a/gas/testsuite/gas/i386/inval-type.s b/gas/testsuite/gas/i386/inval-type.s new file mode 100644 index 00000000000..493d12e5a6c --- /dev/null +++ b/gas/testsuite/gas/i386/inval-type.s @@ -0,0 +1,10 @@ + .text + +# All the following should yield "operand type mismatch" (or something yet more +# specific), but _not_ "operand size mismatch". + + bsf %eax, (%eax) + bswap %mm0 + bswapl %xmm0 + movntdqa %xmm0, (%eax) + movntdq (%eax), %xmm0 diff --git a/gas/testsuite/gas/i386/x86-64-apx-pushp-popp-inval.l b/gas/testsuite/gas/i386/x86-64-apx-pushp-popp-inval.l index c4d774b9673..5e334a015a5 100644 --- a/gas/testsuite/gas/i386/x86-64-apx-pushp-popp-inval.l +++ b/gas/testsuite/gas/i386/x86-64-apx-pushp-popp-inval.l @@ -1,5 +1,5 @@ .* Assembler messages: .*:4: Error: operand size mismatch for `pushp' .*:5: Error: operand size mismatch for `popp' -.*:6: Error: operand size mismatch for `pushp' -.*:7: Error: operand size mismatch for `popp' +.*:6: Error: operand type mismatch for `pushp' +.*:7: Error: operand type mismatch for `popp' diff --git a/gas/testsuite/gas/i386/x86-64-lkgs-inval.l b/gas/testsuite/gas/i386/x86-64-lkgs-inval.l index 77ee7d7c8b9..29da973d348 100644 --- a/gas/testsuite/gas/i386/x86-64-lkgs-inval.l +++ b/gas/testsuite/gas/i386/x86-64-lkgs-inval.l @@ -5,5 +5,5 @@ .*:8: Error: invalid instruction suffix for `lkgs' .*:11: Error: invalid instruction suffix for `lkgs' .*:12: Error: invalid instruction suffix for `lkgs' -.*:13: Error: invalid instruction suffix for `lkgs' -.*:14: Error: invalid instruction suffix for `lkgs' +.*:13: Error: .* for `lkgs' +.*:14: Error: .* for `lkgs' -- 2.39.5