+ if (!BRA_STUBS)
+ bfd_put_32 (sec->owner, BRSL + (((to - from) << 5) & 0x007fff80) + 75,
+ sec->contents + sec->size);
+ else
+ bfd_put_32 (sec->owner, BRASL + ((to << 5) & 0x007fff80) + 75,
+ sec->contents + sec->size);
+ bfd_put_32 (sec->owner, (dest & 0x3ffff) | (dest_ovl << 18),
+ sec->contents + sec->size + 4);
+ }
+ else if (htab->params->ovly_flavour == ovly_soft_icache
+ && htab->params->compact_stub)
+ {
+ lrlive = 0;
+ if (stub_type == nonovl_stub)
+ ;
+ else if (stub_type == call_ovl_stub)
+ /* A brsl makes lr live and *(*sp+16) is live.
+ Tail calls have the same liveness. */
+ lrlive = 5;
+ else if (!htab->params->lrlive_analysis)
+ /* Assume stack frame and lr save. */
+ lrlive = 1;
+ else if (irela != NULL)
+ {
+ /* Analyse branch instructions. */
+ struct function_info *caller;
+ bfd_vma off;
+
+ caller = find_function (isec, irela->r_offset, info);
+ if (caller->start == NULL)
+ off = irela->r_offset;
+ else
+ {
+ struct function_info *found = NULL;
+
+ /* Find the earliest piece of this function that
+ has frame adjusting instructions. We might
+ see dynamic frame adjustment (eg. for alloca)
+ in some later piece, but functions using
+ alloca always set up a frame earlier. Frame
+ setup instructions are always in one piece. */
+ if (caller->lr_store != (bfd_vma) -1
+ || caller->sp_adjust != (bfd_vma) -1)
+ found = caller;
+ while (caller->start != NULL)
+ {
+ caller = caller->start;
+ if (caller->lr_store != (bfd_vma) -1
+ || caller->sp_adjust != (bfd_vma) -1)
+ found = caller;
+ }
+ if (found != NULL)
+ caller = found;
+ off = (bfd_vma) -1;
+ }
+
+ if (off > caller->sp_adjust)
+ {
+ if (off > caller->lr_store)
+ /* Only *(*sp+16) is live. */
+ lrlive = 1;
+ else
+ /* If no lr save, then we must be in a
+ leaf function with a frame.
+ lr is still live. */
+ lrlive = 4;
+ }
+ else if (off > caller->lr_store)
+ {
+ /* Between lr save and stack adjust. */
+ lrlive = 3;
+ /* This should never happen since prologues won't
+ be split here. */
+ BFD_ASSERT (0);
+ }
+ else
+ /* On entry to function. */
+ lrlive = 5;
+
+ if (stub_type != br000_ovl_stub
+ && lrlive != stub_type - br000_ovl_stub)
+ info->callbacks->einfo (_("%A:0x%v lrlive .brinfo (%u) differs "
+ "from analysis (%u)\n"),
+ isec, irela->r_offset, lrlive,
+ stub_type - br000_ovl_stub);
+ }
+
+ /* If given lrlive info via .brinfo, use it. */
+ if (stub_type > br000_ovl_stub)
+ lrlive = stub_type - br000_ovl_stub;
+
+ if (ovl == 0)
+ to = (htab->ovly_entry[1]->root.u.def.value
+ + htab->ovly_entry[1]->root.u.def.section->output_offset
+ + htab->ovly_entry[1]->root.u.def.section->output_section->vma);
+
+ /* The branch that uses this stub goes to stub_addr + 4. We'll
+ set up an xor pattern that can be used by the icache manager
+ to modify this branch to go directly to its destination. */
+ g->stub_addr += 4;
+ br_dest = g->stub_addr;
+ if (irela == NULL)
+ {
+ /* Except in the case of _SPUEAR_ stubs, the branch in
+ question is the one in the stub itself. */
+ BFD_ASSERT (stub_type == nonovl_stub);
+ g->br_addr = g->stub_addr;
+ br_dest = to;
+ }