aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2017-04-10 13:12:52 +0100
committerNick Clifton <nickc@redhat.com>2017-04-10 13:12:52 +0100
commit947fa9141488c1d39303fcdaa056332d2d0b2599 (patch)
treea39cb09310958310a7bb3692a0156769e1d01472 /gas
parentbb1dd176fb6f38ae3cc30dc61ce55a7fbf9d0d7b (diff)
downloadfsf-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/ChangeLog20
-rw-r--r--gas/config/tc-xtensa.c66
-rw-r--r--gas/testsuite/gas/xtensa/all.exp2
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-first1.d12
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-first1.s3
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-first2.d15
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-first2.s3
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools.d6
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 .*
#...