mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 14:39:09 +08:00
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.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
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>
|
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
|
||||||
|
|
||||||
* config/tc-xtensa.c (trampoline_index): New structure.
|
* config/tc-xtensa.c (trampoline_index): New structure.
|
||||||
|
@ -9806,99 +9806,20 @@ bytes_to_stretch (fragS *this_frag,
|
|||||||
|
|
||||||
|
|
||||||
static fragS *
|
static fragS *
|
||||||
search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only)
|
xg_find_best_trampoline_for_tinsn (TInsn *tinsn, fragS *fragP)
|
||||||
{
|
{
|
||||||
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;
|
symbolS *sym = tinsn->tok[0].X_add_symbol;
|
||||||
offsetT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
|
addressT source = fragP->fr_address;
|
||||||
offsetT addr = fragP->fr_address;
|
addressT target = S_GET_VALUE (sym) + tinsn->tok[0].X_add_number;
|
||||||
offsetT lower = (addr < target) ? addr : target;
|
struct trampoline_seg *ts = find_trampoline_seg (now_seg);
|
||||||
offsetT upper = (addr > target) ? addr : target;
|
size_t i;
|
||||||
offsetT delta = upper - lower;
|
|
||||||
offsetT midpoint = lower + delta / 2;
|
|
||||||
offsetT this_delta = -1;
|
|
||||||
offsetT this_addr = -1;
|
|
||||||
|
|
||||||
if (!ts)
|
if (!ts || !ts->index.n_entries)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (delta > 2 * J_RANGE)
|
i = xg_find_best_trampoline (&ts->index, source, target);
|
||||||
{
|
|
||||||
/* 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)
|
return ts->index.entry[i];
|
||||||
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 (tf == NULL)
|
|
||||||
tf = search_trampolines (tinsn, fragP, FALSE); /* Try ones needing a jump-around, too. */
|
|
||||||
|
|
||||||
return tf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -10154,7 +10075,7 @@ relax_frag_immed (segT segP,
|
|||||||
|
|
||||||
if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff))
|
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)
|
if (tf)
|
||||||
{
|
{
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
#...
|
#...
|
||||||
.*49404:.*j.0x49404
|
.*49404:.*j.0x49404
|
||||||
.*49407:.*beqz.n.a2,.0x4940c
|
.*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
|
.*927f5:.*j.0x927f5
|
||||||
#...
|
#...
|
||||||
|
Reference in New Issue
Block a user