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.)
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 9671c64..15f274f 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -2630,7 +2630,9 @@
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 @@
|| !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 @@
{
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 d48dd89..b068b32 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -833,6 +833,7 @@
}
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 0000000..5784949e
--- /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 0000000..493d12e
--- /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 c4d774b..5e334a0 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 77ee7d7..29da973 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'