- static fixup_cacheS fixup_cache;
- segment_info_type *seginfo = seg_info (now_seg);
- int trampaddr = fragP->fr_address + fragP->fr_fix;
- int searchaddr = trampaddr < J_RANGE ? 0 : trampaddr - J_RANGE;
- unsigned i;
-
- if (now_seg != fixup_cache.seg ||
- fragP == fixup_cache.first_frag ||
- fixup_cache.first_frag == NULL)
- {
- xtensa_cache_relaxable_fixups (&fixup_cache, seginfo);
- fixup_cache.seg = now_seg;
- fixup_cache.first_frag = fragP;
- }
-
- /* Scan for jumps that will not reach. */
- for (i = xtensa_find_first_cached_fixup (&fixup_cache, searchaddr);
- i < fixup_cache.n_fixups; ++i)
-
- {
- fixS *fixP = fixup_cache.fixups[i].fixP;
- int target = fixup_cache.fixups[i].target;
- int addr = fixup_cache.fixups[i].addr;
- int delta = fixup_cache.fixups[i].delta + stretch;
-
- trampaddr = fragP->fr_address + fragP->fr_fix;
-
- if (addr + J_RANGE < trampaddr)
- continue;
- if (addr > trampaddr + J_RANGE)
- break;
- if (abs (delta) < J_RANGE)
- continue;
-
- 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);
- 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;
-
- if ((upper - lower) > 2 * J_RANGE)
- {
- /* 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->tc_frag_data.next_trampoline)
- {
- 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)
- {
- /* Forward jump. */
- if (this_addr - addr < J_RANGE)
- break;
- }
- else
- {
- /* Backward jump. */
- if (next_addr == 0 || addr - next_addr > J_RANGE)
- break;
- }
- }
- }
- else
- {
- fragS *best_tf = NULL;
- fragS *best_tf_prev = NULL;
- int best_delta = 0;
-
- for ( ; tf; prev = tf, tf = tf->tc_frag_data.next_trampoline)
- {
- int this_addr = tf->fr_address + tf->fr_fix;
- int this_delta = abs (this_addr - midpoint);