diff options
author | Sean Fertile <sfertile@ca.ibm.com> | 2018-12-20 17:00:33 +0000 |
---|---|---|
committer | Sean Fertile <sfertile@ca.ibm.com> | 2018-12-20 17:00:33 +0000 |
commit | c992a1008f899f848a031df492d758ca3baefef5 (patch) | |
tree | 700173fa7b46a012b2152ef6583182d7119a66dd /lld | |
parent | 227090455b9c78ecfebab24542b6172bec13d8ff (diff) |
[PPC64] Add toc-optimizations for got based relocations.
Differential Revision: https://reviews.llvm.org/D54907
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/Arch/PPC64.cpp | 22 | ||||
-rw-r--r-- | lld/test/ELF/ppc64-got-off.s | 17 |
2 files changed, 32 insertions, 7 deletions
diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index 4d42a26ee2e..94e98a31813 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -597,15 +597,23 @@ static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) { } } -static bool isTocRelType(RelType Type) { - return Type == R_PPC64_TOC16_HA || Type == R_PPC64_TOC16_LO_DS || - Type == R_PPC64_TOC16_LO; +static bool isTocOptType(RelType Type) { + switch (Type) { + case R_PPC64_GOT16_HA: + case R_PPC64_GOT16_LO_DS: + case R_PPC64_TOC16_HA: + case R_PPC64_TOC16_LO_DS: + case R_PPC64_TOC16_LO: + return true; + default: + return false; + } } void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { // We need to save the original relocation type to determine if we should // toc-optimize the instructions being relocated. - bool IsTocRelType = isTocRelType(Type); + bool ShouldTocOptimize = isTocOptType(Type); // For TOC-relative and GOT-indirect relocations, proceed in terms of the // corresponding ADDR16 relocation type. std::tie(Type, Val) = toAddr16Rel(Type, Val); @@ -635,7 +643,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { case R_PPC64_ADDR16_HA: case R_PPC64_REL16_HA: case R_PPC64_TPREL16_HA: - if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) + if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) writeInstrFromHalf16(Loc, 0x60000000); else write16(Loc, ha(Val)); @@ -667,7 +675,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { // When the high-adjusted part of a toc relocation evalutes to 0, it is // changed into a nop. The lo part then needs to be updated to use the // toc-pointer register r2, as the base register. - if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) { + if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) { uint32_t Instr = readInstrFromHalf16(Loc); if (isInstructionUpdateForm(Instr)) error(getErrorLocation(Loc) + @@ -685,7 +693,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { uint32_t Inst = readInstrFromHalf16(Loc); uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3; checkAlignment(Loc, lo(Val), Mask + 1, Type); - if (Config->TocOptimize && IsTocRelType && ha(Val) == 0) { + if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) { // When the high-adjusted part of a toc relocation evalutes to 0, it is // changed into a nop. The lo part then needs to be updated to use the toc // pointer register r2, as the base register. diff --git a/lld/test/ELF/ppc64-got-off.s b/lld/test/ELF/ppc64-got-off.s index 0a1a09e1ca9..d3dff226250 100644 --- a/lld/test/ELF/ppc64-got-off.s +++ b/lld/test/ELF/ppc64-got-off.s @@ -8,6 +8,14 @@ # RUN: ld.lld -shared --no-toc-optimize %t.o -o %t # RUN: llvm-objdump -d %t | FileCheck %s +# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t +# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t +# RUN: llvm-objdump -d %t | FileCheck --check-prefix=OPT %s + .abiversion 2 .section ".text" @@ -38,6 +46,15 @@ func: # CHECK-NEXT: li 6, 0 # CHECK-NEXT: ori 6, 6, 32776 +# OPT-LABEL: func +# OPT: nop +# OPT-NEXT: ld 3, -32760(2) +# OPT-NEXT: ld 4, -32760(2) +# OPT-NEXT: lis 5, -1 +# OPT-NEXT: ori 5, 5, 32776 +# OPT-NEXT: li 6, 0 +# OPT-NEXT: ori 6, 6, 32776 + # Since the got entry for a is .got[1] and the TOC base points to # .got + 0x8000, the offset for a@got is -0x7FF8 --> -32760 |