forked from OSchip/llvm-project
Revert "Revert r362867: [ELF][PPC] Simplify {read,write}FromHalf16"
This reverts commit r363060 and restores r362867. r362867 is innocent. The ppc64le-lld-multistage-test bot failure was due to a clang/gcc .toc bug: ld.lld: error: relocation refers to a discarded section: .rodata._ZNK4llvm3MVT13getSizeInBitsEv >>> defined in utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenRegisters.cpp.o >>> referenced by CodeGenRegisters.cpp >>> utils/TableGen/CMakeFiles/llvm-tblgen.dir/CodeGenRegisters.cpp.o:(.toc+0x0) It will be worked around by D63182. llvm-svn: 363124
This commit is contained in:
parent
aa6f2af4e6
commit
8a529f3cea
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
@ -362,10 +362,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;
|
||||
}
|
||||
|
@ -392,11 +392,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:
|
||||
|
@ -431,10 +431,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
|
||||
|
@ -758,7 +758,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;
|
||||
|
@ -766,7 +766,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;
|
||||
|
@ -798,35 +798,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:
|
||||
|
@ -935,8 +936,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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue