diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-04-10 13:12:52 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-04-10 13:12:52 +0100 |
commit | 947fa9141488c1d39303fcdaa056332d2d0b2599 (patch) | |
tree | a39cb09310958310a7bb3692a0156769e1d01472 /gas | |
parent | bb1dd176fb6f38ae3cc30dc61ce55a7fbf9d0d7b (diff) | |
download | fsf-binutils-gdb-947fa9141488c1d39303fcdaa056332d2d0b2599.zip fsf-binutils-gdb-947fa9141488c1d39303fcdaa056332d2d0b2599.tar.gz fsf-binutils-gdb-947fa9141488c1d39303fcdaa056332d2d0b2599.tar.bz2 |
gas: xtensa: fix incorrect code generated with auto litpools
* config/tc-xtensa.c (xtensa_maybe_create_literal_pool_frag):
Initialize lps->frag_count with auto_litpool_limit.
(xg_promote_candidate_litpool): New function.
(xtensa_move_literals): Extract candidate litpool promotion code
into separate function. Call it for all possible found
candidates.
(xtensa_switch_to_literal_fragment): Drop 'recursive' flag and
call to xtensa_mark_literal_pool_location that it guards.
Replace it with call to xtensa_maybe_create_literal_pool_frag.
Initialize pool_location with created literal pool candidate.
* testsuite/gas/xtensa/all.exp: Add new tests.
* testsuite/gas/xtensa/auto-litpools-first1.d: New test results.
* testsuite/gas/xtensa/auto-litpools-first1.s: New test.
* testsuite/gas/xtensa/auto-litpools-first2.d: New test results.
* testsuite/gas/xtensa/auto-litpools-first2.s: New test.
* testsuite/gas/xtensa/auto-litpools.d: Fix offsets changed due
to additional jump instruction.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 20 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 66 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/all.exp | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/auto-litpools-first1.d | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/auto-litpools-first1.s | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/auto-litpools-first2.d | 15 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/auto-litpools-first2.s | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/auto-litpools.d | 6 |
8 files changed, 95 insertions, 32 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ff9fca3..f7a8628 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,23 @@ +2017-04-10 Max Filippov <jcmvbkbc@gmail.com> + + * config/tc-xtensa.c (xtensa_maybe_create_literal_pool_frag): + Initialize lps->frag_count with auto_litpool_limit. + (xg_promote_candidate_litpool): New function. + (xtensa_move_literals): Extract candidate litpool promotion code + into separate function. Call it for all possible found + candidates. + (xtensa_switch_to_literal_fragment): Drop 'recursive' flag and + call to xtensa_mark_literal_pool_location that it guards. + Replace it with call to xtensa_maybe_create_literal_pool_frag. + Initialize pool_location with created literal pool candidate. + * testsuite/gas/xtensa/all.exp: Add new tests. + * testsuite/gas/xtensa/auto-litpools-first1.d: New test results. + * testsuite/gas/xtensa/auto-litpools-first1.s: New test. + * testsuite/gas/xtensa/auto-litpools-first2.d: New test results. + * testsuite/gas/xtensa/auto-litpools-first2.s: New test. + * testsuite/gas/xtensa/auto-litpools.d: Fix offsets changed due + to additional jump instruction. + 2017-04-07 Alan Modra <amodra@gmail.com> * testsuite/gas/ppc/altivec2.s: Delete E6500 vector insns. diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index c45c70d..e1efaae 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -7547,6 +7547,10 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create, lps->seg = now_seg; lps->frag_list.next = &lps->frag_list; lps->frag_list.prev = &lps->frag_list; + /* Put candidate literal pool at the beginning of every section, + so that even when section starts with literal load there's a + literal pool available. */ + lps->frag_count = auto_litpool_limit; } lps->frag_count++; @@ -11035,6 +11039,30 @@ xtensa_move_seg_list_to_beginning (seg_list *head) static void mark_literal_frags (seg_list *); static void +xg_promote_candidate_litpool (struct litpool_seg *lps, + struct litpool_frag *lp) +{ + fragS *poolbeg; + fragS *poolend; + symbolS *lsym; + char label[10 + 2 * sizeof (fragS *)]; + + poolbeg = lp->fragP; + lp->priority = 1; + poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; + poolend = poolbeg->fr_next; + gas_assert (poolend->fr_type == rs_machine_dependent && + poolend->fr_subtype == RELAX_LITERAL_POOL_END); + /* Create a local symbol pointing to the + end of the pool. */ + sprintf (label, ".L0_LT_%p", poolbeg); + lsym = (symbolS *)local_symbol_make (label, lps->seg, + 0, poolend); + poolbeg->fr_symbol = lsym; + /* Rest is done in xtensa_relax_frag. */ +} + +static void xtensa_move_literals (void) { seg_list *segment; @@ -11121,27 +11149,17 @@ xtensa_move_literals (void) /* This is still a "candidate" but the next one will be too far away, so revert to the nearest one, convert it and add the jump around. */ - fragS *poolbeg; - fragS *poolend; - symbolS *lsym; - char label[10 + 2 * sizeof (fragS *)]; lp = lpf->prev; - poolbeg = lp->fragP; - lp->priority = 1; - poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN; - poolend = poolbeg->fr_next; - gas_assert (poolend->fr_type == rs_machine_dependent && - poolend->fr_subtype == RELAX_LITERAL_POOL_END); - /* Create a local symbol pointing to the - end of the pool. */ - sprintf (label, ".L0_LT_%p", poolbeg); - lsym = (symbolS *)local_symbol_make (label, lps->seg, - 0, poolend); - poolbeg->fr_symbol = lsym; - /* Rest is done in xtensa_relax_frag. */ + break; } } } + + /* Convert candidate and add the jump around. */ + if (lp->fragP->fr_subtype == + RELAX_LITERAL_POOL_CANDIDATE_BEGIN) + xg_promote_candidate_litpool (lps, lp); + if (! litfrag->tc_frag_data.literal_frag) { /* Take earliest use of this literal to avoid @@ -11413,7 +11431,6 @@ xtensa_switch_to_literal_fragment (emit_state *result) static void xtensa_switch_to_non_abs_literal_fragment (emit_state *result) { - static bfd_boolean recursive = FALSE; fragS *pool_location = get_literal_pool_location (now_seg); segT lit_seg; bfd_boolean is_init = @@ -11423,23 +11440,14 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result) if (pool_location == NULL && !use_literal_section - && !recursive && !is_init && ! is_fini) { if (!auto_litpools) { as_bad (_("literal pool location required for text-section-literals; specify with .literal_position")); } - - /* When we mark a literal pool location, we want to put a frag in - the literal pool that points to it. But to do that, we want to - switch_to_literal_fragment. But literal sections don't have - literal pools, so their location is always null, so we would - recurse forever. This is kind of hacky, but it works. */ - - recursive = TRUE; - xtensa_mark_literal_pool_location (); - recursive = FALSE; + xtensa_maybe_create_literal_pool_frag (TRUE, TRUE); + pool_location = get_literal_pool_location (now_seg); } lit_seg = cache_literal_section (FALSE); diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp index 98041b5..1ab3827 100644 --- a/gas/testsuite/gas/xtensa/all.exp +++ b/gas/testsuite/gas/xtensa/all.exp @@ -101,6 +101,8 @@ if [istarget xtensa*-*-*] then { run_dump_test "trampoline" run_dump_test "first_frag_align" run_dump_test "auto-litpools" + run_dump_test "auto-litpools-first1" + run_dump_test "auto-litpools-first2" run_dump_test "loc" run_dump_test "init-fini-literals" } diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first1.d b/gas/testsuite/gas/xtensa/auto-litpools-first1.d new file mode 100644 index 0000000..322cdc5 --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-first1.d @@ -0,0 +1,12 @@ +#as: --auto-litpools +#objdump: -ds +#name: auto-litpools-first1 (check that literal pool is created when source starts with literal) + +.*: +file format .*xtensa.* +#... +Contents of section .text: + 0000 ........ 20170331 .* +#... +00000000 <f>: +.*0:.*j.8 .* +#... diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first1.s b/gas/testsuite/gas/xtensa/auto-litpools-first1.s new file mode 100644 index 0000000..7ac0bf8 --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-first1.s @@ -0,0 +1,3 @@ +f: + .literal .L0, 0x20170331 + l32r a2, .L0 diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first2.d b/gas/testsuite/gas/xtensa/auto-litpools-first2.d new file mode 100644 index 0000000..a6b798e --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-first2.d @@ -0,0 +1,15 @@ +#as: --auto-litpools +#objdump: -ds +#name: auto-litpools-first2 (check that literal pool with jump around is created for generated literal) + +.*: +file format .*xtensa.* +#... +Contents of section .text: + 0000 ........ ........ 20170331 .* +#... +00000000 <f>: + 0:.*addi.*a1.* + 3:.*j.*c.* +#... + c:.*l32r.*a2, 8.* +#... diff --git a/gas/testsuite/gas/xtensa/auto-litpools-first2.s b/gas/testsuite/gas/xtensa/auto-litpools-first2.s new file mode 100644 index 0000000..c097dac --- /dev/null +++ b/gas/testsuite/gas/xtensa/auto-litpools-first2.s @@ -0,0 +1,3 @@ +f: + addi a1, a1, -16 + movi a2, 0x20170331 diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d index 4d1a690..fc6f5cb 100644 --- a/gas/testsuite/gas/xtensa/auto-litpools.d +++ b/gas/testsuite/gas/xtensa/auto-litpools.d @@ -4,9 +4,9 @@ .*: +file format .*xtensa.* #... -.*4:.*l32r.a2, 0 .* +.*8:.*l32r.a2, 4 .* #... -.*3e437:.*j.3e440 .* +.*3e43b:.*j.3e444 .* #... -.*40750:.*l32r.a2, 3e43c .* +.*40754:.*l32r.a2, 3e440 .* #... |