Skip to content

Commit 27de3d3

Browse files
committed
[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
1 parent 99dfd70 commit 27de3d3

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

lld/ELF/Arch/PPC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ static uint16_t lo(uint32_t V) { return V; }
5353
static uint16_t ha(uint32_t V) { return (V + 0x8000) >> 16; }
5454

5555
static uint32_t readFromHalf16(const uint8_t *Loc) {
56-
return read32(Loc - (Config->EKind == ELF32BEKind ? 2 : 0));
56+
return read32(Config->IsLE ? Loc : Loc - 2);
5757
}
5858

5959
static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) {
60-
write32(Loc - (Config->EKind == ELF32BEKind ? 2 : 0), Insn);
60+
write32(Config->IsLE ? Loc : Loc - 2, Insn);
6161
}
6262

6363
void elf::writePPC32GlinkSection(uint8_t *Buf, size_t NumEntries) {

lld/ELF/Arch/PPC64.cpp

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,12 @@ static bool isInstructionUpdateForm(uint32_t Encoding) {
274274
// pointer is pointing into the middle of the word we want to extract, and on
275275
// little-endian it is pointing to the start of the word. These 2 helpers are to
276276
// simplify reading and writing in that context.
277-
static void writeInstrFromHalf16(uint8_t *Loc, uint32_t Instr) {
278-
write32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0), Instr);
277+
static void writeFromHalf16(uint8_t *Loc, uint32_t Insn) {
278+
write32(Config->IsLE ? Loc : Loc - 2, Insn);
279279
}
280280

281-
static uint32_t readInstrFromHalf16(const uint8_t *Loc) {
282-
return read32(Loc - (Config->EKind == ELF64BEKind ? 2 : 0));
281+
static uint32_t readFromHalf16(const uint8_t *Loc) {
282+
return read32(Config->IsLE ? Loc : Loc - 2);
283283
}
284284

285285
PPC64::PPC64() {
@@ -361,10 +361,10 @@ void PPC64::relaxGot(uint8_t *Loc, RelType Type, uint64_t Val) const {
361361
case R_PPC64_TOC16_LO_DS: {
362362
// Convert "ld reg, .LC0@toc@l(reg)" to "addi reg, reg, var@toc@l" or
363363
// "addi reg, 2, var@toc".
364-
uint32_t Instr = readInstrFromHalf16(Loc);
365-
if (getPrimaryOpCode(Instr) != LD)
364+
uint32_t Insn = readFromHalf16(Loc);
365+
if (getPrimaryOpCode(Insn) != LD)
366366
error("expected a 'ld' for got-indirect to toc-relative relaxing");
367-
writeInstrFromHalf16(Loc, (Instr & 0x03FFFFFF) | 0x38000000);
367+
writeFromHalf16(Loc, (Insn & 0x03ffffff) | 0x38000000);
368368
relocateOne(Loc, R_PPC64_TOC16_LO, Val);
369369
break;
370370
}
@@ -391,11 +391,11 @@ void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
391391

392392
switch (Type) {
393393
case R_PPC64_GOT_TLSGD16_HA:
394-
writeInstrFromHalf16(Loc, 0x60000000); // nop
394+
writeFromHalf16(Loc, 0x60000000); // nop
395395
break;
396396
case R_PPC64_GOT_TLSGD16:
397397
case R_PPC64_GOT_TLSGD16_LO:
398-
writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
398+
writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13
399399
relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
400400
break;
401401
case R_PPC64_TLSGD:
@@ -430,10 +430,10 @@ void PPC64::relaxTlsLdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
430430

431431
switch (Type) {
432432
case R_PPC64_GOT_TLSLD16_HA:
433-
writeInstrFromHalf16(Loc, 0x60000000); // nop
433+
writeFromHalf16(Loc, 0x60000000); // nop
434434
break;
435435
case R_PPC64_GOT_TLSLD16_LO:
436-
writeInstrFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
436+
writeFromHalf16(Loc, 0x3c6d0000); // addis r3, r13, 0
437437
break;
438438
case R_PPC64_TLSLD:
439439
write32(Loc, 0x60000000); // nop
@@ -757,15 +757,15 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
757757
checkInt(Loc, Val, 16, OriginalType);
758758
// DQ-form instructions use bits 28-31 as part of the instruction encoding
759759
// DS-form instructions only use bits 30-31.
760-
uint16_t Mask = isDQFormInstruction(readInstrFromHalf16(Loc)) ? 0xF : 0x3;
760+
uint16_t Mask = isDQFormInstruction(readFromHalf16(Loc)) ? 0xf : 0x3;
761761
checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
762762
write16(Loc, (read16(Loc) & Mask) | lo(Val));
763763
} break;
764764
case R_PPC64_ADDR16_HA:
765765
case R_PPC64_REL16_HA:
766766
case R_PPC64_TPREL16_HA:
767767
if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0)
768-
writeInstrFromHalf16(Loc, 0x60000000);
768+
writeFromHalf16(Loc, 0x60000000);
769769
else
770770
write16(Loc, ha(Val));
771771
break;
@@ -797,35 +797,36 @@ void PPC64::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
797797
// changed into a nop. The lo part then needs to be updated to use the
798798
// toc-pointer register r2, as the base register.
799799
if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
800-
uint32_t Instr = readInstrFromHalf16(Loc);
801-
if (isInstructionUpdateForm(Instr))
800+
uint32_t Insn = readFromHalf16(Loc);
801+
if (isInstructionUpdateForm(Insn))
802802
error(getErrorLocation(Loc) +
803803
"can't toc-optimize an update instruction: 0x" +
804-
utohexstr(Instr));
805-
Instr = (Instr & 0xFFE00000) | 0x00020000;
806-
writeInstrFromHalf16(Loc, Instr);
804+
utohexstr(Insn));
805+
writeFromHalf16(Loc, (Insn & 0xffe00000) | 0x00020000 | lo(Val));
806+
} else {
807+
write16(Loc, lo(Val));
807808
}
808-
write16(Loc, lo(Val));
809809
break;
810810
case R_PPC64_ADDR16_LO_DS:
811811
case R_PPC64_TPREL16_LO_DS: {
812812
// DQ-form instructions use bits 28-31 as part of the instruction encoding
813813
// DS-form instructions only use bits 30-31.
814-
uint32_t Inst = readInstrFromHalf16(Loc);
815-
uint16_t Mask = isDQFormInstruction(Inst) ? 0xF : 0x3;
814+
uint32_t Insn = readFromHalf16(Loc);
815+
uint16_t Mask = isDQFormInstruction(Insn) ? 0xf : 0x3;
816816
checkAlignment(Loc, lo(Val), Mask + 1, OriginalType);
817817
if (Config->TocOptimize && ShouldTocOptimize && ha(Val) == 0) {
818818
// When the high-adjusted part of a toc relocation evalutes to 0, it is
819819
// changed into a nop. The lo part then needs to be updated to use the toc
820820
// pointer register r2, as the base register.
821-
if (isInstructionUpdateForm(Inst))
821+
if (isInstructionUpdateForm(Insn))
822822
error(getErrorLocation(Loc) +
823823
"Can't toc-optimize an update instruction: 0x" +
824-
Twine::utohexstr(Inst));
825-
Inst = (Inst & 0xFFE0000F) | 0x00020000;
826-
writeInstrFromHalf16(Loc, Inst);
824+
Twine::utohexstr(Insn));
825+
Insn &= 0xffe00000 | Mask;
826+
writeFromHalf16(Loc, Insn | 0x00020000 | lo(Val));
827+
} else {
828+
write16(Loc, (read16(Loc) & Mask) | lo(Val));
827829
}
828-
write16(Loc, (read16(Loc) & Mask) | lo(Val));
829830
} break;
830831
case R_PPC64_ADDR32:
831832
case R_PPC64_REL32:
@@ -934,8 +935,8 @@ void PPC64::relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const {
934935
case R_PPC64_GOT_TLSGD16_LO: {
935936
// Relax from addi r3, rA, sym@got@tlsgd@l to
936937
// ld r3, sym@got@tprel@l(rA)
937-
uint32_t InputRegister = (readInstrFromHalf16(Loc) & (0x1f << 16));
938-
writeInstrFromHalf16(Loc, 0xE8600000 | InputRegister);
938+
uint32_t RA = (readFromHalf16(Loc) & (0x1f << 16));
939+
writeFromHalf16(Loc, 0xe8600000 | RA);
939940
relocateOne(Loc, R_PPC64_GOT_TPREL16_LO_DS, Val);
940941
return;
941942
}

0 commit comments

Comments
 (0)