diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-10 14:27:42 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2017-11-27 15:13:00 -0800 |
commit | 46888d710015aa8d4bb3c2dac7aa6505d6ac8227 (patch) | |
tree | 017a7b95e02d879c357234f1a0422b5068cd0a1c /gas/config/tc-xtensa.c | |
parent | 1c2649f50f4e40c07840f45c4d237efcdd02e8e2 (diff) | |
download | gdb-46888d710015aa8d4bb3c2dac7aa6505d6ac8227.zip gdb-46888d710015aa8d4bb3c2dac7aa6505d6ac8227.tar.gz gdb-46888d710015aa8d4bb3c2dac7aa6505d6ac8227.tar.bz2 |
gas: xtensa: merge trampoline_frag into xtensa_frag_type
The split between fragS and trampoline_frag doesn't save much space, but
makes trampolines management much more awkward. Merge trampoline_frag
data into the xtensa_frag_type, which is a part of fragS. No functional
changes.
gas/
2017-11-27 Max Filippov <jcmvbkbc@gmail.com>
* config/tc-xtensa.c (init_trampoline_frag): Replace pointer to
struct trampoline_frag parameter with pointer to fragS.
(xg_append_jump): Remove jump_around parameter.
(struct trampoline_frag): Remove.
(struct trampoline_seg): Change type of trampoline_list from
struct trampoline_frag to fragS.
(xtensa_create_trampoline_frag): Don't allocate struct
trampoline_frag. Initialize new fragS::tc_frag_data fields.
(dump_trampolines, xg_relax_trampoline, search_trampolines)
(get_best_trampoline, init_trampoline_frag)
(add_jump_to_trampoline, relax_frag_immed): Replace pointer to
struct trampoline_frag with a pointer to fragS.
(xg_append_jump): Remove jump_around parameter, use
fragS::tc_frag_data.jump_around_fix instead.
(xg_relax_trampoline, init_trampoline_frag)
(add_jump_to_trampoline): Don't pass jump_around parameter to
xg_append_jump.
* config/tc-xtensa.h (struct xtensa_frag_type): Add new fields:
needs_jump_around, next_trampoline and jump_around_fix.
Diffstat (limited to 'gas/config/tc-xtensa.c')
-rw-r--r-- | gas/config/tc-xtensa.c | 120 |
1 files changed, 53 insertions, 67 deletions
diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index a8ed49b..378537c 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -484,9 +484,8 @@ static void xtensa_check_frag_count (void); static void xtensa_create_trampoline_frag (bfd_boolean); static void xtensa_maybe_create_trampoline_frag (void); struct trampoline_frag; -static int init_trampoline_frag (struct trampoline_frag *); -static fixS *xg_append_jump (fragS *fragP, fixS *jump_around, - symbolS *sym, offsetT offset); +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; @@ -7350,19 +7349,11 @@ xtensa_end (void) } -struct trampoline_frag -{ - struct trampoline_frag *next; - bfd_boolean needs_jump_around; - fragS *fragP; - fixS *fixP; -}; - struct trampoline_seg { struct trampoline_seg *next; asection *seg; - struct trampoline_frag trampoline_list; + fragS trampoline_list; }; static struct trampoline_seg trampoline_seg_list; @@ -7446,7 +7437,6 @@ xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) If that's not enough, oh well. */ struct trampoline_seg *ts = find_trampoline_seg (now_seg); - struct trampoline_frag *tf; char *varP; fragS *fragP; int size = TRAMPOLINE_FRAG_SIZE; @@ -7469,12 +7459,10 @@ xtensa_create_trampoline_frag (bfd_boolean needs_jump_around) trampoline_buf = xtensa_insnbuf_alloc (xtensa_default_isa); trampoline_slotbuf = xtensa_insnbuf_alloc (xtensa_default_isa); } - tf = XNEW (struct trampoline_frag); - tf->next = ts->trampoline_list.next; - ts->trampoline_list.next = tf; - tf->needs_jump_around = needs_jump_around; - tf->fragP = fragP; - tf->fixP = NULL; + fragP->tc_frag_data.next_trampoline = + ts->trampoline_list.tc_frag_data.next_trampoline; + ts->trampoline_list.tc_frag_data.next_trampoline = fragP; + fragP->tc_frag_data.needs_jump_around = needs_jump_around; } @@ -7492,14 +7480,12 @@ dump_trampolines (void) if (seg == NULL) continue; fprintf(stderr, "SECTION %s\n", seg->name); - struct trampoline_frag *tf = ts->trampoline_list.next; - for ( ; tf; tf = tf->next) + fragS *tf = ts->trampoline_list.tc_frag_data.next_trampoline; + for ( ; tf; tf = tf->tc_frag_data.next_trampoline) { - if (tf->fragP == NULL) - continue; fprintf(stderr, " 0x%08x: fix=%d, jump_around=%s\n", - (int)tf->fragP->fr_address, (int)tf->fragP->fr_fix, - tf->needs_jump_around ? "T" : "F"); + (int)tf->fr_address, (int)tf->fr_fix, + tf->tc_frag_data.needs_jump_around ? "T" : "F"); } } } @@ -9199,8 +9185,8 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) if (delta > J_RANGE || delta < -1 * J_RANGE) { /* Found an out-of-range jump; scan the list of trampolines for the best match. */ struct trampoline_seg *ts = find_trampoline_seg (now_seg); - struct trampoline_frag *tf = ts->trampoline_list.next; - struct trampoline_frag *prev = &ts->trampoline_list; + fragS *tf = ts->trampoline_list.tc_frag_data.next_trampoline; + fragS *prev = &ts->trampoline_list; int lower = (target < addr) ? target : addr; int upper = (target > addr) ? target : addr; int midpoint = lower + (upper - lower) / 2; @@ -9210,10 +9196,11 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) /* One trampoline won't suffice; we need multiple jumps. Jump to the trampoline that's farthest, but still in range relative to the original "j" instruction. */ - for ( ; tf; prev = tf, tf = tf->next ) + for ( ; tf; prev = tf, tf = tf->tc_frag_data.next_trampoline) { - int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; - int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0 ; + fragS *next = tf->tc_frag_data.next_trampoline; + int this_addr = tf->fr_address + tf->fr_fix; + int next_addr = next ? next->fr_address + next->fr_fix : 0 ; if (addr == lower) { @@ -9231,13 +9218,13 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) } else { - struct trampoline_frag *best_tf = NULL; - struct trampoline_frag *best_tf_prev = NULL; + fragS *best_tf = NULL; + fragS *best_tf_prev = NULL; int best_delta = 0; - for ( ; tf; prev = tf, tf = tf->next ) + for ( ; tf; prev = tf, tf = tf->tc_frag_data.next_trampoline) { - int this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; + int this_addr = tf->fr_address + tf->fr_fix; int this_delta = abs (this_addr - midpoint); if (!best_tf || this_delta < best_delta) @@ -9250,7 +9237,7 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) tf = best_tf; prev = best_tf_prev; } - if (tf->fragP == fragP) + if (tf == fragP) { if (abs (addr - trampaddr) < J_RANGE) { /* The trampoline is in range of original; fix it! */ @@ -9258,7 +9245,7 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) new_stretch += init_trampoline_frag (tf) + 3; /* Assemble a jump to the target label in the trampoline frag. */ - newfixP = xg_append_jump (fragP, tf->fixP, + newfixP = xg_append_jump (fragP, fixP->fx_addsy, fixP->fx_offset); /* Adjust the fixup for the original "j" instruction to @@ -9282,7 +9269,8 @@ static void xg_relax_trampoline (fragS *fragP, long stretch, long *new_stretch) frag_wane (fragP); fragP->fr_subtype = 0; /* Remove from the trampoline_list. */ - prev->next = tf->next; + prev->tc_frag_data.next_trampoline = + tf->tc_frag_data.next_trampoline; if (fragP == fixup_cache.first_frag) fixup_cache.first_frag = NULL; break; @@ -9877,12 +9865,12 @@ bytes_to_stretch (fragS *this_frag, } -static struct trampoline_frag * +static fragS * search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) { struct trampoline_seg *ts = find_trampoline_seg (now_seg); - struct trampoline_frag *tf = (ts) ? ts->trampoline_list.next : NULL; - struct trampoline_frag *best_tf = NULL; + fragS *tf = ts ? ts->trampoline_list.tc_frag_data.next_trampoline : NULL; + fragS *best_tf = NULL; int best_delta = 0; int best_addr = 0; symbolS *sym = tinsn->tok[0].X_add_symbol; @@ -9900,11 +9888,12 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) /* 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 ( ; tf; tf = tf->next) + for ( ; tf; tf = tf->tc_frag_data.next_trampoline) { - int next_addr = (tf->next) ? tf->next->fragP->fr_address + tf->next->fragP->fr_fix : 0; + fragS *next = tf->tc_frag_data.next_trampoline; + int next_addr = next ? next->fr_address + next->fr_fix : 0; - this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; + this_addr = tf->fr_address + tf->fr_fix; if (lower == addr) { /* Forward jump. */ @@ -9923,11 +9912,11 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) return NULL; } - for ( ; tf; tf = tf->next) + for ( ; tf; tf = tf->tc_frag_data.next_trampoline) { - this_addr = tf->fragP->fr_address + tf->fragP->fr_fix; + this_addr = tf->fr_address + tf->fr_fix; this_delta = abs (this_addr - midpoint); - if (unreachable_only && tf->needs_jump_around) + if (unreachable_only && tf->tc_frag_data.needs_jump_around) continue; if (!best_tf || this_delta < best_delta) { @@ -9947,10 +9936,10 @@ search_trampolines (TInsn *tinsn, fragS *fragP, bfd_boolean unreachable_only) } -static struct trampoline_frag * +static fragS * get_best_trampoline (TInsn *tinsn, fragS *fragP) { - struct trampoline_frag *tf = NULL; + fragS *tf = NULL; tf = search_trampolines (tinsn, fragP, TRUE); /* Try unreachable first. */ @@ -9965,22 +9954,21 @@ static void check_and_update_trampolines (void) { struct trampoline_seg *ts = find_trampoline_seg (now_seg); - struct trampoline_frag *tf = ts->trampoline_list.next; - struct trampoline_frag *prev = &ts->trampoline_list; + fragS *tf = ts->trampoline_list.tc_frag_data.next_trampoline; + fragS *prev = &ts->trampoline_list; - for ( ; tf; prev = tf, tf = tf->next) + for ( ; tf; prev = tf, tf = tf->tc_frag_data.next_trampoline) { - if (tf->fragP->fr_var < 3) + if (tf->fr_var < 3) { - frag_wane (tf->fragP); - prev->next = tf->next; - tf->fragP = NULL; + frag_wane (tf); + prev->tc_frag_data.next_trampoline = + tf->tc_frag_data.next_trampoline; } } } -static fixS *xg_append_jump (fragS *fragP, fixS *jump_around, - symbolS *sym, offsetT offset) +static fixS *xg_append_jump (fragS *fragP, symbolS *sym, offsetT offset) { fixS *fixP; TInsn insn; @@ -10006,17 +9994,16 @@ static fixS *xg_append_jump (fragS *fragP, fixS *jump_around, fragP->fr_var -= 3; /* Adjust the jump around this trampoline (if present). */ - if (jump_around) - jump_around->fx_offset += 3; + if (fragP->tc_frag_data.jump_around_fix) + fragP->tc_frag_data.jump_around_fix->fx_offset += 3; return fixP; } static int -init_trampoline_frag (struct trampoline_frag *trampP) +init_trampoline_frag (fragS *fp) { - fragS *fp = trampP->fragP; int growth = 0; if (fp->fr_fix == 0) @@ -10027,9 +10014,9 @@ init_trampoline_frag (struct trampoline_frag *trampP) sprintf (label, ".L0_TR_%p", fp); lsym = (symbolS *)local_symbol_make (label, now_seg, 0, fp); fp->fr_symbol = lsym; - if (trampP->needs_jump_around) + if (fp->tc_frag_data.needs_jump_around) { - trampP->fixP = xg_append_jump (fp, NULL, lsym, 3); + fp->tc_frag_data.jump_around_fix = xg_append_jump (fp, lsym, 3); growth = 3; } } @@ -10038,9 +10025,8 @@ init_trampoline_frag (struct trampoline_frag *trampP) static int -add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) +add_jump_to_trampoline (fragS *tramp, fragS *origfrag) { - fragS *tramp = trampP->fragP; int i, slot = -1; for (i = 0; i < MAX_SLOTS; ++i) @@ -10053,7 +10039,7 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag) gas_assert (slot >= 0 && slot < MAX_SLOTS); /* Assemble a jump to the target label in the trampoline frag. */ - xg_append_jump (tramp, trampP->fixP, + xg_append_jump (tramp, origfrag->tc_frag_data.slot_symbols[slot], origfrag->tc_frag_data.slot_offsets[slot]); @@ -10216,7 +10202,7 @@ relax_frag_immed (segT segP, if (!xg_symbolic_immeds_fit (jinsn, segP, fragP, fragP->fr_offset, total_text_diff)) { - struct trampoline_frag *tf = get_best_trampoline (jinsn, fragP); + fragS *tf = get_best_trampoline (jinsn, fragP); if (tf) { |