mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-23 13:21:43 +08:00
Support fusion for ELFv2 stubs
Power8 fuses addis,addi and addis,ld sequences when the target of the addis is the same as the addi/ld. Thus addis r12,r2,xxx@ha addi r12,r12,xxx@l / ld r12,xxx@l(r12) is faster than addis r11,r2,xxx@ha addi r12,r11,xxx@l / ld r12,xxx@l(r11) So use the form that allows fusion in plt call and branch stubs. bfd/ * elf64-ppc.c (ADDIS_R12_R2): Define. (build_plt_stub): Support fusion on ELFv2 stub. (ppc_build_one_stub): Likewise for plt branch stubs. gold/ * powerpc.cc (addis_12_2): Define. (Stub_table::do_write): Support fusion on ELFv2 stubs. ld/testsuite/ * ld-powerpc/elfv2exe.d: Update for changed plt call stubs. gdb/ * ppc64-tdep.c (ppc64_standard_linkage8): New. (ppc64_skip_trampoline_code): Recognise ELFv2 stub supporting fusion.
This commit is contained in:
parent
61f5c66f62
commit
397998fc32
@ -1,3 +1,9 @@
|
||||
2014-06-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf64-ppc.c (ADDIS_R12_R2): Define.
|
||||
(build_plt_stub): Support fusion on ELFv2 stub.
|
||||
(ppc_build_one_stub): Likewise for plt branch stubs.
|
||||
|
||||
2014-05-28 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf32-rx.c (rx_table_map): Delete set but not used variables.
|
||||
|
@ -173,6 +173,7 @@ static bfd_vma opd_entry_value
|
||||
|
||||
#define LD_R2_0R1 0xe8410000 /* ld %r2,0(%r1) */
|
||||
|
||||
#define ADDIS_R12_R2 0x3d820000 /* addis %r12,%r2,xxx@ha */
|
||||
#define ADDIS_R12_R12 0x3d8c0000 /* addis %r12,%r12,xxx@ha */
|
||||
#define LD_R12_0R12 0xe98c0000 /* ld %r12,xxx@l(%r12) */
|
||||
|
||||
@ -10246,8 +10247,16 @@ build_plt_stub (struct ppc_link_hash_table *htab,
|
||||
if (ALWAYS_EMIT_R2SAVE
|
||||
|| stub_entry->stub_type == ppc_stub_plt_call_r2save)
|
||||
bfd_put_32 (obfd, STD_R2_0R1 + STK_TOC (htab), p), p += 4;
|
||||
bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4;
|
||||
bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4;
|
||||
if (plt_load_toc)
|
||||
{
|
||||
bfd_put_32 (obfd, ADDIS_R11_R2 | PPC_HA (offset), p), p += 4;
|
||||
bfd_put_32 (obfd, LD_R12_0R11 | PPC_LO (offset), p), p += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p), p += 4;
|
||||
bfd_put_32 (obfd, LD_R12_0R12 | PPC_LO (offset), p), p += 4;
|
||||
}
|
||||
if (plt_load_toc
|
||||
&& PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
|
||||
{
|
||||
@ -10668,10 +10677,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
{
|
||||
size = 16;
|
||||
bfd_put_32 (htab->params->stub_bfd,
|
||||
ADDIS_R11_R2 | PPC_HA (off), loc);
|
||||
ADDIS_R12_R2 | PPC_HA (off), loc);
|
||||
loc += 4;
|
||||
bfd_put_32 (htab->params->stub_bfd,
|
||||
LD_R12_0R11 | PPC_LO (off), loc);
|
||||
LD_R12_0R12 | PPC_LO (off), loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -10697,10 +10706,10 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
|
||||
{
|
||||
size += 4;
|
||||
bfd_put_32 (htab->params->stub_bfd,
|
||||
ADDIS_R11_R2 | PPC_HA (off), loc);
|
||||
ADDIS_R12_R2 | PPC_HA (off), loc);
|
||||
loc += 4;
|
||||
bfd_put_32 (htab->params->stub_bfd,
|
||||
LD_R12_0R11 | PPC_LO (off), loc);
|
||||
LD_R12_0R12 | PPC_LO (off), loc);
|
||||
}
|
||||
else
|
||||
bfd_put_32 (htab->params->stub_bfd, LD_R12_0R2 | PPC_LO (off), loc);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-06-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ppc64-tdep.c (ppc64_standard_linkage8): New.
|
||||
(ppc64_skip_trampoline_code): Recognise ELFv2 stub supporting fusion.
|
||||
|
||||
2014-06-02 Doug Evans <dje@google.com>
|
||||
|
||||
Add support for skeletonless type units.
|
||||
|
@ -303,6 +303,29 @@ static struct ppc_insn_pattern ppc64_standard_linkage7[] =
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* ELFv2 PLT call stub to access PLT entries more than +/- 32k from r2,
|
||||
supporting fusion. */
|
||||
|
||||
static struct ppc_insn_pattern ppc64_standard_linkage8[] =
|
||||
{
|
||||
/* std r2, 24(r1) <optional> */
|
||||
{ -1, insn_ds (62, 2, 1, 24, 0), 1 },
|
||||
|
||||
/* addis r12, r2, <any> */
|
||||
{ insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
|
||||
|
||||
/* ld r12, <any>(r12) */
|
||||
{ insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 12, 12, 0, 0), 0 },
|
||||
|
||||
/* mtctr r12 */
|
||||
{ insn_xfx (-1, -1, -1, -1), insn_xfx (31, 12, 9, 467), 0 },
|
||||
|
||||
/* bctr */
|
||||
{ -1, 0x4e800420, 0 },
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* When the dynamic linker is doing lazy symbol resolution, the first
|
||||
call to a function in another object will go like this:
|
||||
|
||||
@ -437,10 +460,14 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||
ARRAY_SIZE (ppc64_standard_linkage4))),
|
||||
MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage5),
|
||||
ARRAY_SIZE (ppc64_standard_linkage6)),
|
||||
ARRAY_SIZE (ppc64_standard_linkage7))) - 1];
|
||||
MAX (ARRAY_SIZE (ppc64_standard_linkage7),
|
||||
ARRAY_SIZE (ppc64_standard_linkage8))))
|
||||
- 1];
|
||||
CORE_ADDR target;
|
||||
|
||||
if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
|
||||
if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage8, insns))
|
||||
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage7, insns))
|
||||
pc = ppc64_standard_linkage3_target (frame, pc, insns);
|
||||
else if (ppc_insns_match_pattern (frame, pc, ppc64_standard_linkage6, insns))
|
||||
pc = ppc64_standard_linkage4_target (frame, pc, insns);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-06-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* powerpc.cc (addis_12_2): Define.
|
||||
(Stub_table::do_write): Support fusion on ELFv2 stubs.
|
||||
|
||||
2014-06-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/plugin_test.c (parse_readelf_line): Skip non-visibility
|
||||
|
@ -3077,6 +3077,7 @@ static const uint32_t addis_3_13 = 0x3c6d0000;
|
||||
static const uint32_t addis_11_2 = 0x3d620000;
|
||||
static const uint32_t addis_11_11 = 0x3d6b0000;
|
||||
static const uint32_t addis_11_30 = 0x3d7e0000;
|
||||
static const uint32_t addis_12_2 = 0x3d820000;
|
||||
static const uint32_t addis_12_12 = 0x3d8c0000;
|
||||
static const uint32_t b = 0x48000000;
|
||||
static const uint32_t bcl_20_31 = 0x429f0005;
|
||||
@ -4210,10 +4211,20 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
|
||||
{
|
||||
write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc());
|
||||
p += 4;
|
||||
write_insn<big_endian>(p, addis_11_2 + ha(off));
|
||||
p += 4;
|
||||
write_insn<big_endian>(p, ld_12_11 + l(off));
|
||||
p += 4;
|
||||
if (plt_load_toc)
|
||||
{
|
||||
write_insn<big_endian>(p, addis_11_2 + ha(off));
|
||||
p += 4;
|
||||
write_insn<big_endian>(p, ld_12_11 + l(off));
|
||||
p += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_insn<big_endian>(p, addis_12_2 + ha(off));
|
||||
p += 4;
|
||||
write_insn<big_endian>(p, ld_12_12 + l(off));
|
||||
p += 4;
|
||||
}
|
||||
if (plt_load_toc
|
||||
&& ha(off + 8 + 8 * static_chain) != ha(off))
|
||||
{
|
||||
@ -4312,8 +4323,8 @@ Stub_table<size, big_endian>::do_write(Output_file* of)
|
||||
}
|
||||
else
|
||||
{
|
||||
write_insn<big_endian>(p, addis_11_2 + ha(brltoff)), p += 4;
|
||||
write_insn<big_endian>(p, ld_12_11 + l(brltoff)), p += 4;
|
||||
write_insn<big_endian>(p, addis_12_2 + ha(brltoff)), p += 4;
|
||||
write_insn<big_endian>(p, ld_12_12 + l(brltoff)), p += 4;
|
||||
}
|
||||
write_insn<big_endian>(p, mtctr_12), p += 4;
|
||||
write_insn<big_endian>(p, bctr);
|
||||
|
@ -1,3 +1,7 @@
|
||||
2014-06-03 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* ld-powerpc/elfv2exe.d: Update for changed plt call stubs.
|
||||
|
||||
2014-05-28 Matthew Fortune <matthew.fortune@imgtec.com>
|
||||
|
||||
* lib/ld-lib.exp: Add objcopy_objects command to run_dump_test.
|
||||
|
@ -8,14 +8,14 @@
|
||||
Disassembly of section \.text:
|
||||
|
||||
0+100000c0 <.*\.plt_branch\.f2>:
|
||||
.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1
|
||||
.*: (f0 7f 8b e9|e9 8b 7f f0) ld r12,32752\(r11\)
|
||||
.*: (ff ff 82 3d|3d 82 ff ff) addis r12,r2,-1
|
||||
.*: (f0 7f 8c e9|e9 8c 7f f0) ld r12,32752\(r12\)
|
||||
.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
||||
.*: (20 04 80 4e|4e 80 04 20) bctr
|
||||
|
||||
0+100000d0 <.*\.plt_branch\.f4>:
|
||||
.*: (ff ff 62 3d|3d 62 ff ff) addis r11,r2,-1
|
||||
.*: (f8 7f 8b e9|e9 8b 7f f8) ld r12,32760\(r11\)
|
||||
.*: (ff ff 82 3d|3d 82 ff ff) addis r12,r2,-1
|
||||
.*: (f8 7f 8c e9|e9 8c 7f f8) ld r12,32760\(r12\)
|
||||
.*: (a6 03 89 7d|7d 89 03 a6) mtctr r12
|
||||
.*: (20 04 80 4e|4e 80 04 20) bctr
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user