diff --git a/gas/ChangeLog b/gas/ChangeLog index 0ae0206dd4..71dd3b85bc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2018-10-20 Alan Modra + + 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. + 2018-10-19 Tamar Christina * testsuite/gas/arm/undefined-insn-arm.d: Widen pe skip. diff --git a/gas/config/tc-spu.c b/gas/config/tc-spu.c index 474805bc26..6998e2b891 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++ == ','); diff --git a/gas/expr.c b/gas/expr.c index 074e0b3f0b..bacfa4e9e8 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -1838,6 +1838,13 @@ expr (int rankarg, /* Larger # is higher rank. */ right.X_op_symbol = NULL; } + if (mode == expr_defer + && ((resultP->X_add_symbol != NULL + && S_IS_FORWARD_REF (resultP->X_add_symbol)) + || (right.X_add_symbol != NULL + && S_IS_FORWARD_REF (right.X_add_symbol)))) + goto general; + /* Optimize common cases. */ #ifdef md_optimize_expr if (md_optimize_expr (resultP, op_left, &right)) diff --git a/gas/testsuite/gas/all/eqv-dot.d b/gas/testsuite/gas/all/eqv-dot.d new file mode 100644 index 0000000000..154530348e --- /dev/null +++ b/gas/testsuite/gas/all/eqv-dot.d @@ -0,0 +1,12 @@ +#objdump: -s -j .data +#name: eqv involving dot +# bfin doesn't support 'symbol = expression' +# tic4x has 4 octets per byte +#notarget: bfin-*-* tic4x-*-* + +.*: .* + +Contents of section \.data: + 0000 (0+00 0+01 0+02 0+0c|000+ 010+ 020+ 0c0+) .* + 0010 (0+10 0+14 0+10 0+1c|100+ 140+ 100+ 1c0+) .* +#pass diff --git a/gas/testsuite/gas/all/eqv-dot.s b/gas/testsuite/gas/all/eqv-dot.s new file mode 100644 index 0000000000..cd8cb9198b --- /dev/null +++ b/gas/testsuite/gas/all/eqv-dot.s @@ -0,0 +1,8 @@ + .data +x: .long 0, 1, 2, . - x + y = . - x + z == . - x + .long y + .long z + .long y + .long z diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp index c1237f9054..74988a1297 100644 --- a/gas/testsuite/gas/all/gas.exp +++ b/gas/testsuite/gas/all/gas.exp @@ -91,6 +91,7 @@ case $target_triplet in { gas_test "eqv-ok.s" "" "" ".eqv support" gas_test_error "eqv-bad.s" "" ".eqv for symbol already set" +run_dump_test eqv-dot if { ![istarget "bfin-*-*"] } then { gas_test "assign-ok.s" "" "" "== assignment support"