aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-10-20 11:12:46 +1030
committerAlan Modra <amodra@gmail.com>2018-10-20 19:46:43 +1030
commite4c2619ad1f31cf73d275b027e8c0cf9c6e9597a (patch)
tree1b93a048c0c8e91a12c2841df06446689da1c61d /gas/config
parentac85e67c053f1555def2c111962f4e68740794f9 (diff)
downloadbinutils-e4c2619ad1f31cf73d275b027e8c0cf9c6e9597a.zip
binutils-e4c2619ad1f31cf73d275b027e8c0cf9c6e9597a.tar.gz
binutils-e4c2619ad1f31cf73d275b027e8c0cf9c6e9597a.tar.bz2
PR23800, .eqv doesn't always defer expression evaluation
.eqv (and ==) ought not simplify expressions involving dot or other symbols set by .eqv. If such simplification occurs, the value of dot will be that at the assignment rather than at the place where the symbol is used. PR 23800 * expr.c (expr): Don't simplify expressions involving forward_ref symbols when mode is expr_defer. * config/tc-spu.c (spu_cons): Parse expression using normal expression evaluation if @ppu is not detected. * testsuite/gas/all/eqv-dot.d, * testsuite/gas/all/eqv-dot.s: New test. * testsuite/gas/all/gas.exp: Run it.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-spu.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gas/config/tc-spu.c b/gas/config/tc-spu.c
index 474805b..6998e2b 100644
--- a/gas/config/tc-spu.c
+++ b/gas/config/tc-spu.c
@@ -815,6 +815,11 @@ spu_cons (int nbytes)
do
{
+ char *save = input_line_pointer;
+
+ /* Use deferred_expression here so that an expression involving
+ a symbol that happens to be defined already as an spu symbol,
+ is not resolved. */
deferred_expression (&exp);
if ((exp.X_op == O_symbol
|| exp.X_op == O_constant)
@@ -829,9 +834,12 @@ spu_cons (int nbytes)
{
expressionS new_exp;
+ save = input_line_pointer;
expression (&new_exp);
if (new_exp.X_op == O_constant)
exp.X_add_number += new_exp.X_add_number;
+ else
+ input_line_pointer = save;
}
reloc = nbytes == 4 ? BFD_RELOC_SPU_PPU32 : BFD_RELOC_SPU_PPU64;
@@ -839,7 +847,14 @@ spu_cons (int nbytes)
&exp, 0, reloc);
}
else
- emit_expr (&exp, nbytes);
+ {
+ /* Don't use deferred_expression for anything else.
+ deferred_expression won't evaulate dot at the point it is
+ used. */
+ input_line_pointer = save;
+ expression (&exp);
+ emit_expr (&exp, nbytes);
+ }
}
while (*input_line_pointer++ == ',');