aboutsummaryrefslogtreecommitdiff
path: root/gas/expr.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2023-03-17 10:07:05 +0100
committerJan Beulich <jbeulich@suse.com>2023-03-17 10:07:05 +0100
commit529b6c24ff2481b55123703cd25569ca8de717cc (patch)
tree3f26f2e1a1529d36b9973a580d502d87dab63880 /gas/expr.c
parent1250cd639016e5567ba8214acf8bf81e8a3ce2db (diff)
downloadfsf-binutils-gdb-529b6c24ff2481b55123703cd25569ca8de717cc.zip
fsf-binutils-gdb-529b6c24ff2481b55123703cd25569ca8de717cc.tar.gz
fsf-binutils-gdb-529b6c24ff2481b55123703cd25569ca8de717cc.tar.bz2
gas: apply md_register_arithmetic also to unary '+'
Even a unary '+' has to be considered arithmetic; at least on x86 in Intel Syntax mode otherwise bogus insn operands may be accepted. Convert this specific case to binary + (i.e. 0 + <register>). (An implication is that md_operator(,1,) would need to deal with arch- specific equivalents of unary '+' is a similar way, if such an arch- specific variant would be specified in the first place.) To avoid duplicating what make_expr_symbol() does to construct a constant-zero expression, simply make its previously local variable a file-scope static one. This way there's also no need to invoke clean_up_expression().
Diffstat (limited to 'gas/expr.c')
-rw-r--r--gas/expr.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/gas/expr.c b/gas/expr.c
index ae24c28..afb346e 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -48,15 +48,16 @@ struct expr_symbol_line {
};
static struct expr_symbol_line *expr_symbol_lines;
+
+static const expressionS zero = { .X_op = O_constant };
/* Build a dummy symbol to hold a complex expression. This is how we
build expressions up out of other expressions. The symbol is put
into the fake section expr_section. */
symbolS *
-make_expr_symbol (expressionS *expressionP)
+make_expr_symbol (const expressionS *expressionP)
{
- expressionS zero;
symbolS *symbolP;
struct expr_symbol_line *n;
@@ -73,11 +74,6 @@ make_expr_symbol (expressionS *expressionP)
as_bad (_("bignum invalid"));
else
as_bad (_("floating point number invalid"));
- zero.X_op = O_constant;
- zero.X_add_number = 0;
- zero.X_unsigned = 0;
- zero.X_extrabit = 0;
- clean_up_expression (&zero);
expressionP = &zero;
}
@@ -750,6 +746,10 @@ current_location (expressionS *expressionp)
}
}
+#ifndef md_register_arithmetic
+# define md_register_arithmetic 1
+#endif
+
/* In: Input_line_pointer points to 1st char of operand, which may
be a space.
@@ -1127,6 +1127,14 @@ operand (expressionS *expressionP, enum expr_mode mode)
expressionP->X_op = O_logical_not;
expressionP->X_add_number = 0;
}
+ else if (!md_register_arithmetic && expressionP->X_op == O_register)
+ {
+ /* Convert to binary '+'. */
+ expressionP->X_op_symbol = make_expr_symbol (expressionP);
+ expressionP->X_add_symbol = make_expr_symbol (&zero);
+ expressionP->X_add_number = 0;
+ expressionP->X_op = O_add;
+ }
}
else
as_warn (_("Unary operator %c ignored because bad operand follows"),
@@ -1891,9 +1899,6 @@ expr (int rankarg, /* Larger # is higher rank. */
}
else
#endif
-#ifndef md_register_arithmetic
-# define md_register_arithmetic 1
-#endif
if (op_left == O_add && right.X_op == O_constant
&& (md_register_arithmetic || resultP->X_op != O_register))
{