aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2018-02-08 10:28:52 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2018-02-20 11:49:48 -0800
commitcd665a945eccba1406696c65ac7eebb12a355446 (patch)
treea3982708d2d39792d56384e59144d9143d8d91c4 /gas
parent7104e59bece90e387d70f617eb7ed4c34087283d (diff)
downloadgdb-cd665a945eccba1406696c65ac7eebb12a355446.zip
gdb-cd665a945eccba1406696c65ac7eebb12a355446.tar.gz
gdb-cd665a945eccba1406696c65ac7eebb12a355446.tar.bz2
gas: xtensa: limit size of auto litpools
Literal movement code may grow auto litpool so big that it won't be possible to jump around it. Limit the size of auto litpools by 1/2 of the jump range. gas/ 2018-02-20 Max Filippov <jcmvbkbc@gmail.com> * config/tc-xtensa.c (struct litpool_frag): Add new field literal_count. (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS) (MAX_POOL_LITERALS): New macro definitions. (auto_litpool_limit): Initialize to 0. (md_parse_option): Set auto_litpool_limit in the presence of --auto-litpools option. (xtensa_maybe_create_literal_pool_frag): Zero-initialize literal_count field. (xg_find_litpool): New function. Make sure that found literal pool size is within the limit. (xtensa_move_literals): Extract literal pool search code into the new function. * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test. * testsuite/gas/xtensa/auto-litpools-2.d: New file. * testsuite/gas/xtensa/auto-litpools-2.s: New file. * testsuite/gas/xtensa/auto-litpools.d: Fix up changed addresses. * testsuite/gas/xtensa/auto-litpools.s: Change literal value so that objdump doesn't get out of sync.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog23
-rw-r--r--gas/config/tc-xtensa.c119
-rw-r--r--gas/testsuite/gas/xtensa/all.exp1
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-2.d6
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools-2.s9
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools.d4
-rw-r--r--gas/testsuite/gas/xtensa/auto-litpools.s2
7 files changed, 119 insertions, 45 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 19fb02f..3ce6995 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,26 @@
+2018-02-20 Max Filippov <jcmvbkbc@gmail.com>
+
+ * config/tc-xtensa.c (struct litpool_frag): Add new field
+ literal_count.
+ (MAX_AUTO_POOL_LITERALS, MAX_EXPLICIT_POOL_LITERALS)
+ (MAX_POOL_LITERALS): New macro definitions.
+ (auto_litpool_limit): Initialize to 0.
+ (md_parse_option): Set auto_litpool_limit in the presence of
+ --auto-litpools option.
+ (xtensa_maybe_create_literal_pool_frag): Zero-initialize
+ literal_count field.
+ (xg_find_litpool): New function. Make sure that found literal
+ pool size is within the limit.
+ (xtensa_move_literals): Extract literal pool search code into
+ the new function.
+ * testsuite/gas/xtensa/all.exp: Add auto-litpools-2 test.
+ * testsuite/gas/xtensa/auto-litpools-2.d: New file.
+ * testsuite/gas/xtensa/auto-litpools-2.s: New file.
+ * testsuite/gas/xtensa/auto-litpools.d: Fix up changed
+ addresses.
+ * testsuite/gas/xtensa/auto-litpools.s: Change literal value so
+ that objdump doesn't get out of sync.
+
2018-02-20 Thomas Preud'homme <thomas.preudhomme@arm.com>
* doc/c-arm.texi (.arch_extension): Mention extensions it accepts are
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c
index b522447..4db7ef5 100644
--- a/gas/config/tc-xtensa.c
+++ b/gas/config/tc-xtensa.c
@@ -438,6 +438,7 @@ struct litpool_frag
addressT addr;
short priority; /* 1, 2, or 3 -- 1 is highest */
short original_priority;
+ int literal_count;
};
/* Map a segment to its litpool_frag list. */
@@ -451,6 +452,14 @@ struct litpool_seg
static struct litpool_seg litpool_seg_list;
+/* Limit maximal size of auto litpool by half of the j range. */
+#define MAX_AUTO_POOL_LITERALS 16384
+
+/* Limit maximal size of explicit literal pool by l32r range. */
+#define MAX_EXPLICIT_POOL_LITERALS 65536
+
+#define MAX_POOL_LITERALS \
+ (auto_litpools ? MAX_AUTO_POOL_LITERALS : MAX_EXPLICIT_POOL_LITERALS)
/* Directive functions. */
@@ -488,7 +497,7 @@ static int init_trampoline_frag (fragS *);
static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset);
static void xtensa_maybe_create_literal_pool_frag (bfd_boolean, bfd_boolean);
static bfd_boolean auto_litpools = FALSE;
-static int auto_litpool_limit = 10000;
+static int auto_litpool_limit = 0;
/* Alignment Functions. */
@@ -984,6 +993,8 @@ md_parse_option (int c, const char *arg)
case option_auto_litpools:
auto_litpools = TRUE;
use_literal_section = FALSE;
+ if (auto_litpool_limit <= 0)
+ auto_litpool_limit = MAX_AUTO_POOL_LITERALS / 2;
return 1;
case option_no_auto_litpools:
@@ -7912,6 +7923,7 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
lpf->fragP = fragP;
lpf->priority = (needed) ? (only_if_needed) ? 3 : 2 : 1;
lpf->original_priority = lpf->priority;
+ lpf->literal_count = 0;
lps->frag_count = 0;
}
@@ -11188,6 +11200,66 @@ xg_promote_candidate_litpool (struct litpool_seg *lps,
/* Rest is done in xtensa_relax_frag. */
}
+static struct litpool_frag *xg_find_litpool (struct litpool_seg *lps,
+ struct litpool_frag *lpf,
+ addressT addr)
+{
+ struct litpool_frag *lp = lpf->prev;
+
+ gas_assert (lp->fragP);
+
+ while (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+ {
+ lp = lp->prev;
+ if (lp->fragP == NULL)
+ {
+ /* End of list; have to bite the bullet.
+ Take the nearest. */
+ lp = lpf->prev;
+ break;
+ }
+ /* Does it (conservatively) reach? */
+ if (addr - lp->addr <= 128 * 1024)
+ {
+ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN &&
+ lp->literal_count < MAX_POOL_LITERALS)
+ {
+ /* Found a good one. */
+ break;
+ }
+ else if (lp->prev->fragP &&
+ addr - lp->prev->addr > 128 * 1024 &&
+ lp->prev->literal_count < MAX_POOL_LITERALS)
+ {
+ /* 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. */
+ lp = lpf->prev;
+ break;
+ }
+ }
+ }
+
+ if (lp->literal_count >= MAX_POOL_LITERALS)
+ {
+ lp = lpf->prev;
+ while (lp && lp->fragP && lp->literal_count >= MAX_POOL_LITERALS)
+ {
+ lp = lp->prev;
+ }
+ gas_assert (lp);
+ }
+
+ gas_assert (lp && lp->fragP && lp->literal_count < MAX_POOL_LITERALS);
+ ++lp->literal_count;
+
+ /* Convert candidate and add the jump around. */
+ if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+ xg_promote_candidate_litpool (lps, lp);
+
+ return lp;
+}
+
static void
xtensa_move_literals (void)
{
@@ -11245,49 +11317,12 @@ xtensa_move_literals (void)
preferring non-"candidate" positions to avoid
the jump-around. */
fragS *litfrag = fragP->tc_frag_data.literal_frags[slot];
- struct litpool_frag *lp = lpf->prev;
- if (!lp->fragP)
- {
- break;
- }
- while (lp->fragP->fr_subtype ==
- RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
- {
- lp = lp->prev;
- if (lp->fragP == NULL)
- {
- /* End of list; have to bite the bullet.
- Take the nearest. */
- lp = lpf->prev;
- break;
- }
- /* Does it (conservatively) reach? */
- if (addr - lp->addr <= 128 * 1024)
- {
- if (lp->fragP->fr_subtype == RELAX_LITERAL_POOL_BEGIN)
- {
- /* Found a good one. */
- break;
- }
- else if (lp->prev->fragP &&
- addr - lp->prev->addr > 128 * 1024)
- {
- /* 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. */
- lp = lpf->prev;
- 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)
+ if (!litfrag->tc_frag_data.literal_frag)
{
+ struct litpool_frag *lp;
+
+ lp = xg_find_litpool (lps, lpf, addr);
/* Take earliest use of this literal to avoid
forward refs. */
litfrag->tc_frag_data.literal_frag = lp->fragP;
diff --git a/gas/testsuite/gas/xtensa/all.exp b/gas/testsuite/gas/xtensa/all.exp
index c0dd8a5..650a932 100644
--- a/gas/testsuite/gas/xtensa/all.exp
+++ b/gas/testsuite/gas/xtensa/all.exp
@@ -102,6 +102,7 @@ if [istarget xtensa*-*-*] then {
run_list_test "trampoline-2"
run_dump_test "first_frag_align"
run_dump_test "auto-litpools"
+ run_dump_test "auto-litpools-2"
run_dump_test "auto-litpools-first1"
run_dump_test "auto-litpools-first2"
run_dump_test "loc"
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.d b/gas/testsuite/gas/xtensa/auto-litpools-2.d
new file mode 100644
index 0000000..d153c2b
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-2.d
@@ -0,0 +1,6 @@
+#as: --auto-litpools
+#objdump: -d
+#name: auto litpool size limitation
+
+.*: +file format .*xtensa.*
+#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools-2.s b/gas/testsuite/gas/xtensa/auto-litpools-2.s
new file mode 100644
index 0000000..30b1383
--- /dev/null
+++ b/gas/testsuite/gas/xtensa/auto-litpools-2.s
@@ -0,0 +1,9 @@
+ .text
+ .global _start
+_start:
+ j 1f
+ .rep 33000
+ movi a2, 0xf03df03d
+ .endr
+1:
+ ret
diff --git a/gas/testsuite/gas/xtensa/auto-litpools.d b/gas/testsuite/gas/xtensa/auto-litpools.d
index fc6f5cb..8eadd1f 100644
--- a/gas/testsuite/gas/xtensa/auto-litpools.d
+++ b/gas/testsuite/gas/xtensa/auto-litpools.d
@@ -6,7 +6,7 @@
#...
.*8:.*l32r.a2, 4 .*
#...
-.*3e43b:.*j.3e444 .*
+.*3f029:.*j.3f030 .*
#...
-.*40754:.*l32r.a2, 3e440 .*
+.*40752:.*l32r.a2, 3f02c .*
#...
diff --git a/gas/testsuite/gas/xtensa/auto-litpools.s b/gas/testsuite/gas/xtensa/auto-litpools.s
index 9a5b26b..aa42415 100644
--- a/gas/testsuite/gas/xtensa/auto-litpools.s
+++ b/gas/testsuite/gas/xtensa/auto-litpools.s
@@ -1,7 +1,7 @@
.text
.align 4
.literal .L0, 0x12345
- .literal .L1, 0x12345
+ .literal .L1, 0x78f078f0
f:
l32r a2, .L0