This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[MIPS, committed] Improve error reporting for register expressions
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 19 Aug 2013 20:31:42 +0100
- Subject: [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))