This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[MIPS, committed] Improve error reporting for register expressions


When a register is used instead of an immediate, we generally report
the error:

    register value used as expression

This patch reports the error earlier using set_insn_error*, so that
we quote the instruction as well.  Also, I think "operand N must
be an immediate expression" is a better error message for cases where
something other than an expression was found, including plain registers
with nothing to mark them out as expressions.

Tested on various targets and applied.

Richard


gas/
	* config/tc-mips.c (match_expression):  Report uses of registers here.
	Add a "must be an immediate expression" error.  Handle elided offsets
	here rather than...
	(match_int_operand): ...here.

gas/testsuite/
	* gas/mips/octeon-ill.l: Adjust expected output.
	* gas/mips/lui-1.l, gas/mips/lui-1.s: Add more cases.

Index: gas/config/tc-mips.c
===================================================================
--- gas/config/tc-mips.c	2013-08-19 19:13:29.107324456 +0100
+++ gas/config/tc-mips.c	2013-08-19 19:13:31.074341893 +0100
@@ -4325,37 +4325,38 @@ match_char (struct mips_arg_info *arg, c
 match_expression (struct mips_arg_info *arg, expressionS *value,
 		  bfd_reloc_code_real_type *r)
 {
-  if (arg->token->type == OT_INTEGER)
+  /* If the next token is a '(' that was parsed as being part of a base
+     expression, assume we have an elided offset.  The later match will fail
+     if this turns out to be wrong.  */
+  if (arg->token->type == OT_CHAR && arg->token->u.ch == '(')
     {
-      *value = arg->token->u.integer.value;
-      memcpy (r, arg->token->u.integer.relocs, 3 * sizeof (*r));
-      ++arg->token;
+      value->X_op = O_constant;
+      value->X_add_number = 0;
+      r[0] = r[1] = r[2] = BFD_RELOC_UNUSED;
       return TRUE;
     }
 
-  /* Error-reporting is more consistent if we treat registers as O_register
-     rather than rejecting them outright.  "$1", "($1)" and "(($1))" are
-     then handled in the same way.  */
-  if (arg->token->type == OT_REG)
+  /* Reject register-based expressions such as "0+$2" and "(($2))".
+     For plain registers the default error seems more appropriate.  */
+  if (arg->token->type == OT_INTEGER
+      && arg->token->u.integer.value.X_op == O_register)
     {
-      value->X_add_number = arg->token->u.regno;
-      ++arg->token;
+      set_insn_error (arg->argnum, _("register value used as expression"));
+      return FALSE;
     }
-  else if (arg->token[0].type == OT_CHAR
-	   && arg->token[0].u.ch == '('
-	   && arg->token[1].type == OT_REG
-	   && arg->token[2].type == OT_CHAR
-	   && arg->token[2].u.ch == ')')
+
+  if (arg->token->type == OT_INTEGER)
     {
-      value->X_add_number = arg->token[1].u.regno;
-      arg->token += 3;
+      *value = arg->token->u.integer.value;
+      memcpy (r, arg->token->u.integer.relocs, 3 * sizeof (*r));
+      ++arg->token;
+      return TRUE;
     }
-  else
-    return FALSE;
 
-  value->X_op = O_register;
-  r[0] = r[1] = r[2] = BFD_RELOC_UNUSED;
-  return TRUE;
+  set_insn_error_i
+    (arg->argnum, _("operand %d must be an immediate expression"),
+     arg->argnum);
+  return FALSE;
 }
 
 /* Try to get a constant expression from the next tokens in ARG.  Consume
@@ -4561,15 +4562,11 @@ match_int_operand (struct mips_arg_info
   if (arg->lax_max)
     max_val = ((1 << operand_base->size) - 1) << operand->shift;
 
-  if (arg->token->type == OT_CHAR && arg->token->u.ch == '(')
-    /* Assume we have an elided offset.  The later match will fail
-       if this turns out to be wrong.  */
-    sval = 0;
-  else if (operand_base->lsb == 0
-	   && operand_base->size == 16
-	   && operand->shift == 0
-	   && operand->bias == 0
-	   && (operand->max_val == 32767 || operand->max_val == 65535))
+  if (operand_base->lsb == 0
+      && operand_base->size == 16
+      && operand->shift == 0
+      && operand->bias == 0
+      && (operand->max_val == 32767 || operand->max_val == 65535))
     {
       /* The operand can be relocated.  */
       if (!match_expression (arg, &offset_expr, offset_reloc))
Index: gas/testsuite/gas/mips/octeon-ill.l
===================================================================
--- gas/testsuite/gas/mips/octeon-ill.l	2013-08-19 19:13:29.128324643 +0100
+++ gas/testsuite/gas/mips/octeon-ill.l	2013-08-19 19:13:31.076341911 +0100
@@ -30,10 +30,10 @@
 .*:43: Error: Opcode not supported on this processor.*
 .*:45: Error: operand 2 out of range `dmfc2 \$2,0x10000'
 .*:46: Error: operand 2 out of range `dmtc2 \$2,0x12345'
-.*:47: Error: operand 2 must be constant `dmfc2 \$9,\$12'
-.*:48: Error: operand 2 must be constant `dmfc2 \$4,\$15,4'
-.*:49: Error: operand 2 must be constant `dmtc2 \$16,\$8'
-.*:50: Error: operand 2 must be constant `dmtc2 \$22,\$7,\$4'
+.*:47: Error: operand 2 must be an immediate expression `dmfc2 \$9,\$12'
+.*:48: Error: operand 2 must be an immediate expression `dmfc2 \$4,\$15,4'
+.*:49: Error: operand 2 must be an immediate expression `dmtc2 \$16,\$8'
+.*:50: Error: operand 2 must be an immediate expression `dmtc2 \$22,\$7,\$4'
 .*:52: Error: operand 3 out of range `exts \$26,26,32'
 .*:54: Error: operand 3 out of range `exts32 \$7,\$21,32,10'
 .*:55: Error: operand 4 out of range `exts32 \$31,\$13,3,29'
Index: gas/testsuite/gas/mips/lui-1.l
===================================================================
--- gas/testsuite/gas/mips/lui-1.l	2013-08-19 19:13:29.125324616 +0100
+++ gas/testsuite/gas/mips/lui-1.l	2013-08-19 19:13:31.075341902 +0100
@@ -2,4 +2,7 @@
 .*\.s:5: Error: operand 2 out of range `lui \$2,-1'
 .*\.s:6: Error: operand 2 out of range `lui \$2,65536'
 .*\.s:7: Error: bignum invalid
-.*\.s:8: Error: register value used as expression
+.*\.s:8: Error: operand 2 must be an immediate expression `lui \$2,\$3'
+.*\.s:9: Error: Illegal operands `lui \$2,\(\$3\)'
+.*\.s:10: Error: register value used as expression `lui \$2,0\+\$3'
+.*\.s:11: Error: register value used as expression `lui \$2,\(\(\$3\)\)'
Index: gas/testsuite/gas/mips/lui-1.s
===================================================================
--- gas/testsuite/gas/mips/lui-1.s	2013-08-19 18:37:18.609108103 +0100
+++ gas/testsuite/gas/mips/lui-1.s	2013-08-19 19:13:31.075341902 +0100
@@ -6,3 +6,6 @@ foo:
 	lui	$2, 65536
 	lui	$2, 0x10000000000000000
 	lui	$2, $3
+	lui	$2, ($3)
+	lui	$2, 0+$3
+	lui	$2, (($3))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]