diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-13 00:42:43 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-27 15:14:48 -0800 |
commit | 76a493ab99d9276180db6e791f95d1d6d86d2954 (patch) | |
tree | 87a026ec0dfcf483c671287b36abaa842ba4b6af /gas | |
parent | fe6c2f1b6409867a03dd32214679dd825f74ec48 (diff) | |
download | fsf-binutils-gdb-76a493ab99d9276180db6e791f95d1d6d86d2954.zip fsf-binutils-gdb-76a493ab99d9276180db6e791f95d1d6d86d2954.tar.gz fsf-binutils-gdb-76a493ab99d9276180db6e791f95d1d6d86d2954.tar.bz2 |
gas: xtensa: reuse trampoline placement code
There's almost exact copy of the trampoline placement code in the
search_trampolines function that is used for jumps generated for relaxed
branch instructions. Get rid of the duplication and reuse
xg_find_best_trampoline function for that.
gas/
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (search_trampolines, get_best_trampoline):
Remove definitions.
(xg_find_best_trampoline_for_tinsn): New function.
(relax_frag_immed): Replace call to get_best_trampoline with a
call to xg_find_best_trampoline_for_tinsn.
* testsuite/gas/xtensa/trampoline.d: Adjust absolute addresses
as the placement of trampolines for relaxed branches has been
changed.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 97 | ||||
-rw-r--r-- | gas/testsuite/gas/xtensa/trampoline.d | 6 |
3 files changed, 23 insertions, 91 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 24c1eb0..c129941 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,16 @@ 2017-11-27 Max Filippov <jcmvbkbc@gmail.com> + * config/tc-xtensa.c (search_trampolines, get_best_trampoline): + Remove definitions. + (xg_find_best_trampoline_for_tinsn): New function. + (relax_frag_immed): Replace call to get_best_trampoline with a + call to xg_find_best_trampoline_for_tinsn. + * testsuite/gas/xtensa/trampoline.d: Adjust absolute addresses + as the placement of trampolines for relaxed branches has been + changed. + +2017-11-27 Max Filippov <jcmvbkbc@gmail.com> + * config/tc-xtensa.c (trampoline_index): New structure. (trampoline_seg): Replace trampoline list with trampoline index. (xg_find_trampoline, xg_add_trampoline_to_index) diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index 7d8b62b..b507d44 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -9806,99 +9806,20 @@ bytes_to_stretch (fragS *this_frag, static fragS * -search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) +xg_find_best_trampoline_for_tinsn (TInsn *tinsn, fragS *fragP) { + symbolS *sym = tinsn->tok[0].X_add_symbol; + addressT source = fragP->fr_address; + addressT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; struct trampoline_seg *ts = find_trampoline_seg (now_seg); - fragS *tf = NULL; size_t i; - fragS *best_tf = NULL; - offsetT best_delta = 0; - offsetT best_addr = 0; - symbolS *sym = tinsn->tok[0].X_add_symbol; - offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number; - offsetT addr = fragP->fr_address; - offsetT lower = (addr < target) ? addr : target; - offsetT upper = (addr > target) ? addr : target; - offsetT delta = upper - lower; - offsetT midpoint = lower + delta / 2; - offsetT this_delta = -1; - offsetT this_addr = -1; - - if (!ts) - return NULL; - - if (delta > 2 * J_RANGE) - { - /* One trampoline won't do; we need multiple. - Choose the farthest trampoline that's still in range of the original - and let a later pass finish the job. */ - for (i = 0; i < ts->index.n_entries; ++i) - { - tf = ts->index.entry[i]; - this_addr = tf->fr_address + tf->fr_fix; - if (upper == addr) - { - /* Backward jump. */ - if (addr - this_addr < J_RANGE) - break; - } - else if (i + 1 < ts->index.n_entries) - { - /* Forward jump. */ - fragS *next = ts->index.entry[i + 1]; - offsetT next_addr = next->fr_address + next->fr_fix; - - if (next_addr - addr > J_RANGE) - break; - } - else - { - break; - } - } - if (i < ts->index.n_entries && - labs (addr - this_addr) < J_RANGE) - return tf; - - return NULL; - } - - for (i = 0; i < ts->index.n_entries; ++i) - { - tf = ts->index.entry[i]; - this_addr = tf->fr_address + tf->fr_fix; - this_delta = labs (this_addr - midpoint); - if (unreachable_only && tf->tc_frag_data.needs_jump_around) - continue; - if (!best_tf || this_delta < best_delta) - { - best_tf = tf; - best_delta = this_delta; - best_addr = this_addr; - } - } - - if (best_tf && - best_delta < J_RANGE && - labs(best_addr - lower) < J_RANGE && - labs(best_addr - upper) < J_RANGE) - return best_tf; - - return NULL; /* No suitable trampoline found. */ -} - -static fragS * -get_best_trampoline (TInsn *tinsn, fragS *fragP) -{ - fragS *tf = NULL; - - tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ + if (!ts || !ts->index.n_entries) + return NULL; - if (tf == NULL) - tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */ + i = xg_find_best_trampoline (&ts->index, source, target); - return tf; + return ts->index.entry[i]; } @@ -10154,7 +10075,7 @@ relax_frag_immed (segT segP, if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) { - fragS *tf = get_best_trampoline (jinsn, fragP); + fragS *tf = xg_find_best_trampoline_for_tinsn (jinsn, fragP); if (tf) { diff --git a/gas/testsuite/gas/xtensa/trampoline.d b/gas/testsuite/gas/xtensa/trampoline.d index c0bac6d..f9aa5d9 100644 --- a/gas/testsuite/gas/xtensa/trampoline.d +++ b/gas/testsuite/gas/xtensa/trampoline.d @@ -23,11 +23,11 @@ #... .*49404:.*j.0x49404 .*49407:.*beqz.n.a2,.0x4940c -.*49409:.*j.0x693ce +.*49409:.*j.0x61aa2 #... -.*693ce:.*j.0x7ddd1 +.*61aa2:.*j.0x7a13b #... -.*7ddd1:.*j.0x927f5 +.*7a13b:.*j.0x927f5 #... .*927f5:.*j.0x927f5 #... |