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().
This commit is contained in:
Jan Beulich
2023-03-17 10:07:05 +01:00
parent 1250cd6390
commit 529b6c24ff
2 changed files with 16 additions and 11 deletions

View File

@@ -48,15 +48,16 @@ struct expr_symbol_line {
}; };
static struct expr_symbol_line *expr_symbol_lines; 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 a dummy symbol to hold a complex expression. This is how we
build expressions up out of other expressions. The symbol is put build expressions up out of other expressions. The symbol is put
into the fake section expr_section. */ into the fake section expr_section. */
symbolS * symbolS *
make_expr_symbol (expressionS *expressionP) make_expr_symbol (const expressionS *expressionP)
{ {
expressionS zero;
symbolS *symbolP; symbolS *symbolP;
struct expr_symbol_line *n; struct expr_symbol_line *n;
@@ -73,11 +74,6 @@ make_expr_symbol (expressionS *expressionP)
as_bad (_("bignum invalid")); as_bad (_("bignum invalid"));
else else
as_bad (_("floating point number invalid")); 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; 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 /* In: Input_line_pointer points to 1st char of operand, which may
be a space. be a space.
@@ -1127,6 +1127,14 @@ operand (expressionS *expressionP, enum expr_mode mode)
expressionP->X_op = O_logical_not; expressionP->X_op = O_logical_not;
expressionP->X_add_number = 0; 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 else
as_warn (_("Unary operator %c ignored because bad operand follows"), as_warn (_("Unary operator %c ignored because bad operand follows"),
@@ -1890,9 +1898,6 @@ expr (int rankarg, /* Larger # is higher rank. */
; ;
} }
else else
#endif
#ifndef md_register_arithmetic
# define md_register_arithmetic 1
#endif #endif
if (op_left == O_add && right.X_op == O_constant if (op_left == O_add && right.X_op == O_constant
&& (md_register_arithmetic || resultP->X_op != O_register)) && (md_register_arithmetic || resultP->X_op != O_register))

View File

@@ -182,7 +182,7 @@ extern void add_to_result (expressionS *, offsetT, int);
extern void subtract_from_result (expressionS *, offsetT, int); extern void subtract_from_result (expressionS *, offsetT, int);
extern segT expr (int, expressionS *, enum expr_mode); extern segT expr (int, expressionS *, enum expr_mode);
extern unsigned int get_single_number (void); 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 int expr_symbol_where (symbolS *, const char **, unsigned int *);
extern void current_location (expressionS *); extern void current_location (expressionS *);
extern symbolS *expr_build_uconstant (offsetT); extern symbolS *expr_build_uconstant (offsetT);