diff options
author | Jan Beulich <jbeulich@suse.com> | 2023-03-17 10:07:05 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2023-03-17 10:07:05 +0100 |
commit | 529b6c24ff2481b55123703cd25569ca8de717cc (patch) | |
tree | 3f26f2e1a1529d36b9973a580d502d87dab63880 /gas | |
parent | 1250cd639016e5567ba8214acf8bf81e8a3ce2db (diff) | |
download | binutils-529b6c24ff2481b55123703cd25569ca8de717cc.zip binutils-529b6c24ff2481b55123703cd25569ca8de717cc.tar.gz binutils-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')
-rw-r--r-- | gas/expr.c | 25 | ||||
-rw-r--r-- | gas/expr.h | 2 |
2 files changed, 16 insertions, 11 deletions
@@ -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)) { @@ -182,7 +182,7 @@ extern void add_to_result (expressionS *, offsetT, int); extern void subtract_from_result (expressionS *, offsetT, int); extern segT expr (int, expressionS *, enum expr_mode); extern unsigned int get_single_number (void); -extern symbolS *make_expr_symbol (expressionS * expressionP); +extern symbolS *make_expr_symbol (const expressionS * expressionP); extern int expr_symbol_where (symbolS *, const char **, unsigned int *); extern void current_location (expressionS *); extern symbolS *expr_build_uconstant (offsetT); |