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.
This commit is contained in:
Max Filippov 2017-04-10 13:12:52 +01:00 committed by Nick Clifton
parent bb1dd176fb
commit 947fa91414
8 changed files with 95 additions and 32 deletions

View File

@ -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.

View File

@ -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++;
@ -11034,6 +11038,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)
{
@ -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);

View File

@ -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"
}

View File

@ -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 .*
#...

View File

@ -0,0 +1,3 @@
f:
.literal .L0, 0x20170331
l32r a2, .L0

View File

@ -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.*
#...

View File

@ -0,0 +1,3 @@
f:
addi a1, a1, -16
movi a2, 0x20170331

View File

@ -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 .*
#...