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:
parent
bb1dd176fb
commit
947fa91414
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
}
|
||||
|
12
gas/testsuite/gas/xtensa/auto-litpools-first1.d
Normal file
12
gas/testsuite/gas/xtensa/auto-litpools-first1.d
Normal 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 .*
|
||||
#...
|
3
gas/testsuite/gas/xtensa/auto-litpools-first1.s
Normal file
3
gas/testsuite/gas/xtensa/auto-litpools-first1.s
Normal file
@ -0,0 +1,3 @@
|
||||
f:
|
||||
.literal .L0, 0x20170331
|
||||
l32r a2, .L0
|
15
gas/testsuite/gas/xtensa/auto-litpools-first2.d
Normal file
15
gas/testsuite/gas/xtensa/auto-litpools-first2.d
Normal 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.*
|
||||
#...
|
3
gas/testsuite/gas/xtensa/auto-litpools-first2.s
Normal file
3
gas/testsuite/gas/xtensa/auto-litpools-first2.s
Normal file
@ -0,0 +1,3 @@
|
||||
f:
|
||||
addi a1, a1, -16
|
||||
movi a2, 0x20170331
|
@ -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 .*
|
||||
#...
|
||||
|
Loading…
Reference in New Issue
Block a user