x86: don't attempt to resolve equates and alike from i386_parse_name()
authorJan Beulich <jbeulich@suse.com>
Wed, 23 Mar 2022 11:28:53 +0000 (12:28 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 23 Mar 2022 11:28:53 +0000 (12:28 +0100)
PR gas/28977

Perhaps right from its introduction in 4d1bb7955a8b it was wrong for
i386_parse_name() to call parse_register(). This being a hook from the
expression parser, it shouldn't be resolving e.g. equated symbols.
That's relevant only for all other callers of parse_register().

To compensate, in Intel syntax mode check_register() needs calling;
perhaps not doing so was an oversight right when the function was
introduced. This is necessary in particular to force EVEX encoding when
VRex registers are used (but of course also to reject bad uses of
registers, i.e. fully matching what parse_register() needs it for).

gas/config/tc-i386-intel.c
gas/config/tc-i386.c
gas/testsuite/gas/i386/equ-2.l [new file with mode: 0644]
gas/testsuite/gas/i386/equ-2.s [new file with mode: 0644]
gas/testsuite/gas/i386/i386.exp

index 42f0afe0e413c26b2dadfac033798418274d4c01..d0c30ddbd5d5e671173806310272e3fcc6b57d43 100644 (file)
@@ -289,6 +289,13 @@ i386_intel_simplify_register (expressionS *e)
       return 0;
     }
 
+  if (!check_register (&i386_regtab[reg_num]))
+    {
+      as_bad (_("register '%s%s' cannot be used here"),
+             register_prefix, i386_regtab[reg_num].reg_name);
+      return 0;
+    }
+
   if (!intel_state.in_bracket)
     {
       if (i.op[this_operand].regs)
index afb8b706bda3fcd14f80abf077225bf8a44a28be..aea19aa5d883490b0839e8f72d55a8e6fdab5175 100644 (file)
@@ -13000,11 +13000,12 @@ parse_register (char *reg_string, char **end_op)
 int
 i386_parse_name (char *name, expressionS *e, char *nextcharP)
 {
-  const reg_entry *r;
+  const reg_entry *r = NULL;
   char *end = input_line_pointer;
 
   *end = *nextcharP;
-  r = parse_register (name, &input_line_pointer);
+  if (*name == REGISTER_PREFIX || allow_naked_reg)
+    r = parse_real_register (name, &input_line_pointer);
   if (r && end <= input_line_pointer)
     {
       *nextcharP = *input_line_pointer;
diff --git a/gas/testsuite/gas/i386/equ-2.l b/gas/testsuite/gas/i386/equ-2.l
new file mode 100644 (file)
index 0000000..97a24b5
--- /dev/null
@@ -0,0 +1,17 @@
+.*: Assembler messages:
+.*:8: Error: .*
+#...
+GAS LISTING .*
+
+
+[      ]*[0-9]+[       ]+# .*
+[      ]*[0-9]+[       ]+equ:
+[      ]*[0-9]+[       ]+s = %edx % %ecx
+[      ]*[0-9]+[       ]+x = s
+[      ]*[0-9]+[       ]+y = s
+[      ]*[0-9]+[       ]+z = s
+[      ]*[0-9]+[       ]*
+[      ]*[0-9]+[       ]+t = %ymm5%%%!%%%%!%%%%%%%%!%ebp%%%%%%%%%%%%%%%%%%M
+[      ]*[0-9]+[       ]+a = t
+[      ]*[0-9]+[       ]+b = t
+[      ]*[0-9]+[       ]+c = t
diff --git a/gas/testsuite/gas/i386/equ-2.s b/gas/testsuite/gas/i386/equ-2.s
new file mode 100644 (file)
index 0000000..87ec9a7
--- /dev/null
@@ -0,0 +1,11 @@
+# PR gas/28977
+equ:
+       s = %edx % %ecx
+       x = s
+       y = s
+       z = s
+
+       t = %ymm5%%%!%%%%!%%%%%%%%!%ebp%%%%%%%%%%%%%%%%%%M
+       a = t
+       b = t
+       c = t
index 3c157e9eb1e7c1fe1725bef0ddc0320089bdbc68..96356d3eb11ffd1f49c2adde510fb27fd2e459f7 100644 (file)
@@ -99,6 +99,7 @@ if [gas_32_check] then {
     run_list_test "suffix-bad"
     run_dump_test "immed32"
     run_dump_test "equ"
+    run_list_test "equ-2" "-al"
     run_list_test "equ-bad"
     run_dump_test "divide"
     run_dump_test "quoted"