From 27de3d395035f94e94c759b84679bc923294dcbe Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sat, 8 Jun 2019 05:19:05 +0000 Subject: [PATCH] [ELF][PPC] Simplify {read,write}FromHalf16 I've change the variable names used in PPC64.cpp from "Instr" to "Insn" because "Insn" is a more common abbreviation for "instruction". While changing PPC64.cpp relocateOne(), make R_PPC64_ADDR16_LO{_DS} slightly more efficient by saving a read and a write for the TocOptimize case. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D63043 llvm-svn: 362867 --- lld/ELF/Arch/PPC.cpp | 4 ++-- lld/ELF/Arch/PPC64.cpp | 57 +++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/lld/ELF/Arch/PPC.cpp b/lld/ELF/Arch/PPC.cpp index ac8319d..57540c4 100644 --- a/lld/ELF/Arch/PPC.cpp +++ b/lld/ELF/Arch/PPC.cpp @@ -53,11 +53,11 @@ static uint16_t lo(uint32_t V) { return V; } static uint16_t ha(uint32_t V) { return (V + 0x8000) >> 16; } static uint32_t readFromHalf16(const uint8_t *Loc) { - return read32(Loc - (Config->EKind == ELF32BEKind ? 2 : 0)); + return read32(Config->IsLE ? Loc : Loc - 2); } static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) { - write32(Loc - (Config->EKind == ELF32BEKind ? 2 : 0), Insn); + write32(Config->IsLE ? Loc : Loc - 2, Insn); } void elf::writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries) { diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp index c574b8b..dddeadd 100644 --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -274,12 +274,12 @@ static bool isInstructionUpdateForm(uint32_t Encoding) { // pointer is pointing into the middle of the word we want to extract, and on // little-endian it is pointing to the start of the word. These 2 helpers are to // simplify reading and writing in that context. -static void writeInstrFromHalf16(uint8_t *Loc, uint32_t Instr) { - write32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0), Instr); +static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) { + write32(Config->IsLE ? Loc : Loc - 2, Insn); } -static uint32_t readInstrFromHalf16(const uint8_t *Loc) { - return read32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0)); +static uint32_t readFromHalf16(const uint8_t *Loc) { + return read32(Config->IsLE ? Loc : Loc - 2); } PPC64::PPC64() { @@ -361,10 +361,10 @@ void PPC64::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const { case R_PPC64_TOC16_LO_DS: { // Convert "ld reg, .LC0@toc@l(reg)" to "addi reg, reg, var@toc@l" or // "addi reg, 2, var@toc". - uint32_t Instr = readInstrFromHalf16(Loc); - if (getPrimaryOpCode(Instr) != LD) + uint32_t Insn = readFromHalf16(Loc); + if (getPrimaryOpCode(Insn) != LD) error("expected a 'ld' for got-indirect to toc-relative relaxing"); - writeInstrFromHalf16(Loc, (Instr & 0x03FFFFFF) | 0x38000000); + writeFromHalf16(Loc, (Insn & 0x03ffffff) | 0x38000000); relocateOne(Loc, R_PPC64_TOC16_LO, Val); break; } @@ -391,11 +391,11 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { switch (Type) { case R_PPC64_GOT_TLSGD16_HA: - writeInstrFromHalf16(Loc, 0x60000000); // nop + writeFromHalf16(Loc, 0x60000000); // nop break; case R_PPC64_GOT_TLSGD16: case R_PPC64_GOT_TLSGD16_LO: - writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13 + writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13 relocateOne(Loc, R_PPC64_TPREL16_HA, Val); break; case R_PPC64_TLSGD: @@ -430,10 +430,10 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const { switch (Type) { case R_PPC64_GOT_TLSLD16_HA: - writeInstrFromHalf16(Loc, 0x60000000); // nop + writeFromHalf16(Loc, 0x60000000); // nop break; case R_PPC64_GOT_TLSLD16_LO: - writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0 + writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0 break; case R_PPC64_TLSLD: write32(Loc, 0x60000000); // nop @@ -757,7 +757,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { checkInt(Loc, Val, 16, OriginalType); // DQ-form instructions use bits 28-31 as part of the instruction encoding // DS-form instructions only use bits 30-31. - uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3; + uint16_t Mask = isDQFormInstruction(readFromHalf16(Loc)) ? 0xf : 0x3; checkAlignment(Loc, lo(Val), Mask + 1, OriginalType); write16(Loc, (read16(Loc) & Mask) | lo(Val)); } break; @@ -765,7 +765,7 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { case R_PPC64_REL16_HA: case R_PPC64_TPREL16_HA: if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) - writeInstrFromHalf16(Loc, 0x60000000); + writeFromHalf16(Loc, 0x60000000); else write16(Loc, ha(Val)); break; @@ -797,35 +797,36 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { // 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 && ShouldTocOptimize && ha(Val) == 0) { - uint32_t Instr = readInstrFromHalf16(Loc); - if (isInstructionUpdateForm(Instr)) + uint32_t Insn = readFromHalf16(Loc); + if (isInstructionUpdateForm(Insn)) error(getErrorLocation(Loc) + "can't toc-optimize an update instruction: 0x" + - utohexstr(Instr)); - Instr = (Instr & 0xFFE00000) | 0x00020000; - writeInstrFromHalf16(Loc, Instr); + utohexstr(Insn)); + writeFromHalf16(Loc, (Insn & 0xffe00000) | 0x00020000 | lo(Val)); + } else { + write16(Loc, lo(Val)); } - write16(Loc, lo(Val)); break; case R_PPC64_ADDR16_LO_DS: case R_PPC64_TPREL16_LO_DS: { // DQ-form instructions use bits 28-31 as part of the instruction encoding // DS-form instructions only use bits 30-31. - uint32_t Inst = readInstrFromHalf16(Loc); - uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3; + uint32_t Insn = readFromHalf16(Loc); + uint16_t Mask = isDQFormInstruction(Insn) ? 0xf : 0x3; checkAlignment(Loc, lo(Val), Mask + 1, OriginalType); 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. - if (isInstructionUpdateForm(Inst)) + if (isInstructionUpdateForm(Insn)) error(getErrorLocation(Loc) + "Can't toc-optimize an update instruction: 0x" + - Twine::utohexstr(Inst)); - Inst = (Inst & 0xFFE0000F) | 0x00020000; - writeInstrFromHalf16(Loc, Inst); + Twine::utohexstr(Insn)); + Insn &= 0xffe00000 | Mask; + writeFromHalf16(Loc, Insn | 0x00020000 | lo(Val)); + } else { + write16(Loc, (read16(Loc) & Mask) | lo(Val)); } - write16(Loc, (read16(Loc) & Mask) | lo(Val)); } break; case R_PPC64_ADDR32: case R_PPC64_REL32: @@ -934,8 +935,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const { case R_PPC64_GOT_TLSGD16_LO: { // Relax from addi r3, rA, sym@got@tlsgd@l to // ld r3, sym@got@tprel@l(rA) - uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16)); - writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister); + uint32_t RA = (readFromHalf16(Loc) & (0x1f << 16)); + writeFromHalf16(Loc, 0xe8600000 | RA); relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val); return; } -- 2.7.4