]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: improve matching diagnostics
authorJan Beulich <jbeulich@suse.com>
Fri, 16 May 2025 08:26:45 +0000 (10:26 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 16 May 2025 08:26:45 +0000 (10:26 +0200)
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
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/inval-type.l [new file with mode: 0644]
gas/testsuite/gas/i386/inval-type.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-apx-pushp-popp-inval.l
gas/testsuite/gas/i386/x86-64-lkgs-inval.l

index 9671c64217866a49c43a89f9a1b9f1d46e5259f8..15f274f6e5bd4eb2dd1b4ef8f2666fd4f0880e89 100644 (file)
@@ -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.  */
index d48dd8902f910a7b3f6292b7ddec340e7bd3e250..b068b327af3bddbdf6217bda5aec5f72286d931b 100644 (file)
@@ -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 (file)
index 0000000..5784949
--- /dev/null
@@ -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 (file)
index 0000000..493d12e
--- /dev/null
@@ -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
index c4d774b967335932f9b9a01d6998f3dbca0d3813..5e334a015a5a58684ba80e99978bca5200b063e7 100644 (file)
@@ -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'
index 77ee7d7c8b94b1a9eaf195aad1386211e10c18cf..29da973d3484898263a713dfd623d1f6e00e8e8a 100644 (file)
@@ -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'