mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-26 03:24:41 +08:00
* elf64-alpha.c (elf64_alpha_relax_with_lituse): Nop out gpdisp
following a call to a near function.
This commit is contained in:
parent
79bcdb567f
commit
1cd6895c55
@ -1,3 +1,8 @@
|
||||
2001-09-09 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* elf64-alpha.c (elf64_alpha_relax_with_lituse): Nop out gpdisp
|
||||
following a call to a near function.
|
||||
|
||||
2001-09-08 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* elf64-alpha.c (elf64_alpha_relocate_section): Soft fail
|
||||
|
@ -1149,14 +1149,36 @@ elf64_alpha_relax_with_lituse (info, symval, irel, irelend)
|
||||
else
|
||||
all_optimized = false;
|
||||
|
||||
/* ??? If target gp == current gp we can eliminate the gp reload.
|
||||
This does depend on every place a gp could be reloaded will
|
||||
be, which currently happens for all code produced by gcc, but
|
||||
not necessarily by hand-coded assembly, or if sibling calls
|
||||
are enabled in gcc.
|
||||
/* Even if the target is not in range for a direct branch,
|
||||
if we share a GP, we can eliminate the gp reload. */
|
||||
if (optdest)
|
||||
{
|
||||
Elf_Internal_Rela *gpdisp
|
||||
= (elf64_alpha_find_reloc_at_ofs
|
||||
(irel, irelend, urel->r_offset + 4, R_ALPHA_GPDISP));
|
||||
if (gpdisp)
|
||||
{
|
||||
bfd_byte *p_ldah = info->contents + gpdisp->r_offset;
|
||||
bfd_byte *p_lda = p_ldah + gpdisp->r_addend;
|
||||
unsigned int ldah = bfd_get_32 (info->abfd, p_ldah);
|
||||
unsigned int lda = bfd_get_32 (info->abfd, p_lda);
|
||||
|
||||
Perhaps conditionalize this on a flag being set in the target
|
||||
object file's header, and have gcc set it? */
|
||||
/* Verify that the instruction is "ldah $29,0($26)".
|
||||
Consider a function that ends in a noreturn call,
|
||||
and that the next function begins with an ldgp,
|
||||
and that by accident there is no padding between.
|
||||
In that case the insn would use $27 as the base. */
|
||||
if (ldah == 0x27ba0000 && lda == 0x23bd0000)
|
||||
{
|
||||
bfd_put_32 (info->abfd, INSN_UNOP, p_ldah);
|
||||
bfd_put_32 (info->abfd, INSN_UNOP, p_lda);
|
||||
|
||||
gpdisp->r_info = ELF64_R_INFO (0, R_ALPHA_NONE);
|
||||
info->changed_contents = true;
|
||||
info->changed_relocs = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user