mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
Optimise PowerPC64 r2 adjusting stubs
Sometimes these stubs don't need to change the low 16-bits of r2, so in that case omit a useless addi r2,r2,0 insn. Also, change the get_r2off error return from 0 to -1 since 0 is a valid return for ELFv2 -R objects. * elf64-ppc.c (get_r2off): Return -1 on error. (ppc_build_one_stub): Adjust for get_r2off change. Don't emit addi r2,r2,0 on r2off stubs when the low 16-bit delta is zero. (ppc_size_one_stub): Corresponding size changes for r2off stubs. Add condition in test for -R objects.
This commit is contained in:
@ -1,3 +1,11 @@
|
|||||||
|
2015-08-31 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* elf64-ppc.c (get_r2off): Return -1 on error.
|
||||||
|
(ppc_build_one_stub): Adjust for get_r2off change. Don't emit
|
||||||
|
addi r2,r2,0 on r2off stubs when the low 16-bit delta is zero.
|
||||||
|
(ppc_size_one_stub): Corresponding size changes for r2off stubs.
|
||||||
|
Add condition in test for -R objects.
|
||||||
|
|
||||||
2015-08-31 Alan Modra <amodra@gmail.com>
|
2015-08-31 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* section.c (section_id): Make file scope.
|
* section.c (section_id): Make file scope.
|
||||||
|
@ -10540,10 +10540,10 @@ get_r2off (struct bfd_link_info *info,
|
|||||||
info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
|
info->callbacks->einfo (_("%P: cannot find opd entry toc for `%T'\n"),
|
||||||
stub_entry->h->elf.root.root.string);
|
stub_entry->h->elf.root.root.string);
|
||||||
bfd_set_error (bfd_error_bad_value);
|
bfd_set_error (bfd_error_bad_value);
|
||||||
return 0;
|
return (bfd_vma) -1;
|
||||||
}
|
}
|
||||||
if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
|
if (!bfd_get_section_contents (opd->owner, opd, buf, opd_off + 8, 8))
|
||||||
return 0;
|
return (bfd_vma) -1;
|
||||||
r2off = bfd_get_64 (opd->owner, buf);
|
r2off = bfd_get_64 (opd->owner, buf);
|
||||||
r2off -= elf_gp (info->output_bfd);
|
r2off -= elf_gp (info->output_bfd);
|
||||||
}
|
}
|
||||||
@ -10599,23 +10599,28 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
{
|
{
|
||||||
bfd_vma r2off = get_r2off (info, stub_entry);
|
bfd_vma r2off = get_r2off (info, stub_entry);
|
||||||
|
|
||||||
if (r2off == 0)
|
if (r2off == (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
htab->stub_error = TRUE;
|
htab->stub_error = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
|
bfd_put_32 (htab->params->stub_bfd, STD_R2_0R1 + STK_TOC (htab), loc);
|
||||||
loc += 4;
|
loc += 4;
|
||||||
size = 12;
|
size = 8;
|
||||||
if (PPC_HA (r2off) != 0)
|
if (PPC_HA (r2off) != 0)
|
||||||
{
|
{
|
||||||
size = 16;
|
|
||||||
bfd_put_32 (htab->params->stub_bfd,
|
bfd_put_32 (htab->params->stub_bfd,
|
||||||
ADDIS_R2_R2 | PPC_HA (r2off), loc);
|
ADDIS_R2_R2 | PPC_HA (r2off), loc);
|
||||||
loc += 4;
|
loc += 4;
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
if (PPC_LO (r2off) != 0)
|
||||||
|
{
|
||||||
|
bfd_put_32 (htab->params->stub_bfd,
|
||||||
|
ADDI_R2_R2 | PPC_LO (r2off), loc);
|
||||||
|
loc += 4;
|
||||||
|
size += 4;
|
||||||
}
|
}
|
||||||
bfd_put_32 (htab->params->stub_bfd, ADDI_R2_R2 | PPC_LO (r2off), loc);
|
|
||||||
loc += 4;
|
|
||||||
off -= size - 4;
|
off -= size - 4;
|
||||||
}
|
}
|
||||||
bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
|
bfd_put_32 (htab->params->stub_bfd, B_DOT | (off & 0x3fffffc), loc);
|
||||||
@ -10796,7 +10801,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
{
|
{
|
||||||
bfd_vma r2off = get_r2off (info, stub_entry);
|
bfd_vma r2off = get_r2off (info, stub_entry);
|
||||||
|
|
||||||
if (r2off == 0 && htab->opd_abi)
|
if (r2off == (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
htab->stub_error = TRUE;
|
htab->stub_error = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -11062,14 +11067,16 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
|
if (stub_entry->stub_type == ppc_stub_long_branch_r2off)
|
||||||
{
|
{
|
||||||
r2off = get_r2off (info, stub_entry);
|
r2off = get_r2off (info, stub_entry);
|
||||||
if (r2off == 0 && htab->opd_abi)
|
if (r2off == (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
htab->stub_error = TRUE;
|
htab->stub_error = TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
size = 12;
|
size = 8;
|
||||||
if (PPC_HA (r2off) != 0)
|
if (PPC_HA (r2off) != 0)
|
||||||
size = 16;
|
size += 4;
|
||||||
|
if (PPC_LO (r2off) != 0)
|
||||||
|
size += 4;
|
||||||
off -= size - 4;
|
off -= size - 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11079,7 +11086,8 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
|||||||
Do the same for -R objects without function descriptors. */
|
Do the same for -R objects without function descriptors. */
|
||||||
if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
|
if (off + (1 << 25) >= (bfd_vma) (1 << 26) - local_off
|
||||||
|| (stub_entry->stub_type == ppc_stub_long_branch_r2off
|
|| (stub_entry->stub_type == ppc_stub_long_branch_r2off
|
||||||
&& r2off == 0))
|
&& r2off == 0
|
||||||
|
&& htab->sec_info[stub_entry->target_section->id].toc_off == 0))
|
||||||
{
|
{
|
||||||
struct ppc_branch_hash_entry *br_entry;
|
struct ppc_branch_hash_entry *br_entry;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user