mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC][PCRelative] Thread Local Storage Support for Initial Exec
This patch is the initial support for the Intial Exec Thread Local Local Storage model to produce code sequence and relocations correct to the ABI for the model when using PC relative memory operations. Reviewed By: stefanp Differential Revision: https://reviews.llvm.org/D81947
This commit is contained in:
parent
c4598749ca
commit
710eb84124
@ -101,6 +101,7 @@
|
||||
#undef R_PPC64_PCREL34
|
||||
#undef R_PPC64_GOT_PCREL34
|
||||
#undef R_PPC64_GOT_TLSGD_PCREL34
|
||||
#undef R_PPC64_GOT_TPREL_PCREL34
|
||||
#undef R_PPC64_IRELATIVE
|
||||
#undef R_PPC64_REL16
|
||||
#undef R_PPC64_REL16_LO
|
||||
@ -200,6 +201,7 @@ ELF_RELOC(R_PPC64_PCREL_OPT, 123)
|
||||
ELF_RELOC(R_PPC64_PCREL34, 132)
|
||||
ELF_RELOC(R_PPC64_GOT_PCREL34, 133)
|
||||
ELF_RELOC(R_PPC64_GOT_TLSGD_PCREL34, 148)
|
||||
ELF_RELOC(R_PPC64_GOT_TPREL_PCREL34, 150)
|
||||
ELF_RELOC(R_PPC64_IRELATIVE, 248)
|
||||
ELF_RELOC(R_PPC64_REL16, 249)
|
||||
ELF_RELOC(R_PPC64_REL16_LO, 250)
|
||||
|
@ -300,6 +300,8 @@ public:
|
||||
VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
|
||||
VK_PPC_GOT_PCREL, // symbol@got@pcrel
|
||||
VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
|
||||
VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
|
||||
VK_PPC_TLS_PCREL, // symbol@tls@pcrel
|
||||
VK_PPC_TLSLD, // symbol@tlsld
|
||||
VK_PPC_LOCAL, // symbol@local
|
||||
VK_PPC_NOTOC, // symbol@notoc
|
||||
|
@ -324,6 +324,10 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
|
||||
return "got@pcrel";
|
||||
case VK_PPC_GOT_TLSGD_PCREL:
|
||||
return "got@tlsgd@pcrel";
|
||||
case VK_PPC_GOT_TPREL_PCREL:
|
||||
return "got@tprel@pcrel";
|
||||
case VK_PPC_TLS_PCREL:
|
||||
return "tls@pcrel";
|
||||
case VK_PPC_TLSLD: return "tlsld";
|
||||
case VK_PPC_LOCAL: return "local";
|
||||
case VK_PPC_NOTOC: return "notoc";
|
||||
@ -457,6 +461,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
|
||||
.Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
|
||||
.Case("got@pcrel", VK_PPC_GOT_PCREL)
|
||||
.Case("got@tlsgd@pcrel", VK_PPC_GOT_TLSGD_PCREL)
|
||||
.Case("got@tprel@pcrel", VK_PPC_GOT_TPREL_PCREL)
|
||||
.Case("tls@pcrel", VK_PPC_TLS_PCREL)
|
||||
.Case("notoc", VK_PPC_NOTOC)
|
||||
.Case("gdgot", VK_Hexagon_GD_GOT)
|
||||
.Case("gdplt", VK_Hexagon_GD_PLT)
|
||||
|
@ -651,7 +651,8 @@ public:
|
||||
return CreateImm(CE->getValue(), S, E, IsPPC64);
|
||||
|
||||
if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
|
||||
if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS)
|
||||
if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
|
||||
SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
|
||||
return CreateTLSReg(SRE, S, E, IsPPC64);
|
||||
|
||||
if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
|
||||
|
@ -141,6 +141,9 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL:
|
||||
Type = ELF::R_PPC64_GOT_TLSGD_PCREL34;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL:
|
||||
Type = ELF::R_PPC64_GOT_TPREL_PCREL34;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FK_Data_4:
|
||||
@ -410,6 +413,9 @@ unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
else
|
||||
Type = ELF::R_PPC_TLS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TLS_PCREL:
|
||||
Type = ELF::R_PPC64_TLS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PPC::fixup_ppc_imm34:
|
||||
|
@ -232,9 +232,10 @@ PPCMCCodeEmitter::getMemRI34PCRelEncoding(const MCInst &MI, unsigned OpNo,
|
||||
// Currently these are the only valid PCRelative Relocations.
|
||||
assert((SRE->getKind() == MCSymbolRefExpr::VK_PCREL ||
|
||||
SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_PCREL ||
|
||||
SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL) &&
|
||||
SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL ||
|
||||
SRE->getKind() == MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL) &&
|
||||
"VariantKind must be VK_PCREL or VK_PPC_GOT_PCREL or "
|
||||
"VK_PPC_GOT_TLSGD_PCREL");
|
||||
"VK_PPC_GOT_TLSGD_PCREL or VK_PPC_GOT_TPREL_PCREL");
|
||||
// Generate the fixup for the relocation.
|
||||
Fixups.push_back(
|
||||
MCFixup::create(0, Expr,
|
||||
@ -346,8 +347,12 @@ unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
||||
|
||||
// Add a fixup for the TLS register, which simply provides a relocation
|
||||
// hint to the linker that this statement is part of a relocation sequence.
|
||||
// Return the thread-pointer register's encoding.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
// Return the thread-pointer register's encoding. Add a one byte displacement
|
||||
// if using PC relative memops.
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
|
||||
bool IsPCRel = SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL;
|
||||
Fixups.push_back(MCFixup::create(IsPCRel ? 1 : 0, Expr,
|
||||
(MCFixupKind)PPC::fixup_ppc_nofixup));
|
||||
const Triple &TT = STI.getTargetTriple();
|
||||
bool isPPC64 = TT.isPPC64();
|
||||
|
@ -113,11 +113,20 @@ namespace llvm {
|
||||
/// TLS General Dynamic model.
|
||||
MO_TLSGD_FLAG = 32,
|
||||
|
||||
/// MO_TPREL_FLAG - If this bit is set the symbol reference is relative to
|
||||
/// TLS Initial Exec model.
|
||||
MO_TPREL_FLAG = 64,
|
||||
|
||||
/// MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set
|
||||
/// they should produce the relocation @got@tlsgd@pcrel.
|
||||
/// Fix up is VK_PPC_GOT_TLSGD_PCREL
|
||||
MO_GOT_TLSGD_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG | MO_TLSGD_FLAG,
|
||||
|
||||
/// MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set
|
||||
/// they should produce the relocation @got@tprel@pcrel.
|
||||
/// Fix up is VK_PPC_GOT_TPREL_PCREL
|
||||
MO_GOT_TPREL_PCREL_FLAG = MO_GOT_FLAG | MO_TPREL_FLAG | MO_PCREL_FLAG,
|
||||
|
||||
/// The next are not flags but distinct values.
|
||||
MO_ACCESS_MASK = 0xf00,
|
||||
|
||||
|
@ -2978,25 +2978,34 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
||||
}
|
||||
|
||||
if (Model == TLSModel::InitialExec) {
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
|
||||
SDValue TGATLS = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
|
||||
PPCII::MO_TLS);
|
||||
SDValue GOTPtr;
|
||||
if (is64bit) {
|
||||
setUsesTOCBasePtr(DAG);
|
||||
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
||||
GOTPtr = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
|
||||
PtrVT, GOTReg, TGA);
|
||||
bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
|
||||
SDValue TGA = DAG.getTargetGlobalAddress(
|
||||
GV, dl, PtrVT, 0, IsPCRel ? PPCII::MO_GOT_TPREL_PCREL_FLAG : 0);
|
||||
SDValue TGATLS = DAG.getTargetGlobalAddress(
|
||||
GV, dl, PtrVT, 0,
|
||||
IsPCRel ? (PPCII::MO_TLS | PPCII::MO_PCREL_FLAG) : PPCII::MO_TLS);
|
||||
SDValue TPOffset;
|
||||
if (IsPCRel) {
|
||||
SDValue MatPCRel = DAG.getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
|
||||
TPOffset = DAG.getLoad(MVT::i64, dl, DAG.getEntryNode(), MatPCRel,
|
||||
MachinePointerInfo());
|
||||
} else {
|
||||
if (!TM.isPositionIndependent())
|
||||
GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
|
||||
else if (picLevel == PICLevel::SmallPIC)
|
||||
GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
|
||||
else
|
||||
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
|
||||
SDValue GOTPtr;
|
||||
if (is64bit) {
|
||||
setUsesTOCBasePtr(DAG);
|
||||
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
||||
GOTPtr =
|
||||
DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
|
||||
} else {
|
||||
if (!TM.isPositionIndependent())
|
||||
GOTPtr = DAG.getNode(PPCISD::PPC32_GOT, dl, PtrVT);
|
||||
else if (picLevel == PICLevel::SmallPIC)
|
||||
GOTPtr = DAG.getNode(PPCISD::GlobalBaseReg, dl, PtrVT);
|
||||
else
|
||||
GOTPtr = DAG.getNode(PPCISD::PPC32_PICGOT, dl, PtrVT);
|
||||
}
|
||||
TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
|
||||
}
|
||||
SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl,
|
||||
PtrVT, TGA, GOTPtr);
|
||||
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
|
||||
}
|
||||
|
||||
|
@ -2274,7 +2274,9 @@ PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
|
||||
{MO_GOT_FLAG, "ppc-got"},
|
||||
{MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},
|
||||
{MO_TLSGD_FLAG, "ppc-tlsgd"},
|
||||
{MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"}};
|
||||
{MO_TPREL_FLAG, "ppc-tprel"},
|
||||
{MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
|
||||
{MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};
|
||||
return makeArrayRef(TargetFlags);
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,9 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO;
|
||||
break;
|
||||
case PPCII::MO_TLS:
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_TLS;
|
||||
bool IsPCRel = (MO.getTargetFlags() & ~access) == PPCII::MO_PCREL_FLAG;
|
||||
RefKind = IsPCRel ? MCSymbolRefExpr::VK_PPC_TLS_PCREL
|
||||
: MCSymbolRefExpr::VK_PPC_TLS;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -86,6 +88,8 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_GOT_PCREL;
|
||||
else if (MO.getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG)
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL;
|
||||
else if (MO.getTargetFlags() == PPCII::MO_GOT_TPREL_PCREL_FLAG)
|
||||
RefKind = MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL;
|
||||
|
||||
const MachineInstr *MI = MO.getParent();
|
||||
const MachineFunction *MF = MI->getMF();
|
||||
|
48
test/CodeGen/PowerPC/pcrel-tls-initial-exec.ll
Normal file
48
test/CodeGen/PowerPC/pcrel-tls-initial-exec.ll
Normal file
@ -0,0 +1,48 @@
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
||||
; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names -enable-ppc-pcrel-tls < %s | \
|
||||
; RUN: FileCheck %s --check-prefix=CHECK-S
|
||||
; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
|
||||
; RUN: -mcpu=pwr10 -ppc-asm-full-reg-names --filetype=obj \
|
||||
; RUN: -enable-ppc-pcrel-tls < %s | llvm-objdump --mcpu=pwr10 -dr - | \
|
||||
; RUN: FileCheck %s --check-prefix=CHECK-O
|
||||
|
||||
; These test cases are to ensure that when using pc relative memory operations
|
||||
; ABI correct code and relocations are produced for Initial Exec TLS Model.
|
||||
; Note that with R_PPC64_TLS relocations, to distinguish PC relative
|
||||
; TLS the relocation has a field value displaced by one byte from the
|
||||
; beginning of the instruction.
|
||||
|
||||
@x = external thread_local global i32, align 4
|
||||
|
||||
define i32* @InitialExecAddressLoad() {
|
||||
; CHECK-S-LABEL: InitialExecAddressLoad:
|
||||
; CHECK-S: # %bb.0: # %entry
|
||||
; CHECK-S-NEXT: pld r3, x@got@tprel@pcrel(0), 1
|
||||
; CHECK-S-NEXT: add r3, r3, x@tls@pcrel
|
||||
; CHECK-S-NEXT: blr
|
||||
; CHECK-O-LABEL: <InitialExecAddressLoad>:
|
||||
; CHECK-O: 00 00 10 04 00 00 60 e4 pld 3, 0(0), 1
|
||||
; CHECK-O-NEXT: 0000000000000000: R_PPC64_GOT_TPREL_PCREL34 x
|
||||
; CHECK-O-NEXT: 14 6a 63 7c add 3, 3, 13
|
||||
; CHECK-O-NEXT: 0000000000000009: R_PPC64_TLS x
|
||||
; CHECK-O-NEXT: 20 00 80 4e blr
|
||||
entry:
|
||||
ret i32* @x
|
||||
}
|
||||
|
||||
define i32 @InitialExecValueLoad() {
|
||||
; CHECK-S-LABEL: InitialExecValueLoad:
|
||||
; CHECK-S: # %bb.0: # %entry
|
||||
; CHECK-S-NEXT: pld r3, x@got@tprel@pcrel(0), 1
|
||||
; CHECK-S-NEXT: lwzx r3, r3, x@tls@pcrel
|
||||
; CHECK-S-NEXT: blr
|
||||
; CHECK-O-LABEL: <InitialExecValueLoad>:
|
||||
; CHECK-O: 00 00 10 04 00 00 60 e4 pld 3, 0(0), 1
|
||||
; CHECK-O-NEXT: 0000000000000020: R_PPC64_GOT_TPREL_PCREL34 x
|
||||
; CHECK-O-NEXT: 2e 68 63 7c lwzx 3, 3, 13
|
||||
; CHECK-O-NEXT: 0000000000000029: R_PPC64_TLS x
|
||||
; CHECK-O-NEXT: 20 00 80 4e blr
|
||||
entry:
|
||||
%0 = load i32, i32* @x, align 4
|
||||
ret i32 %0
|
||||
}
|
21
test/MC/PowerPC/pcrel-tls-initial-exec-address-load-reloc.s
Normal file
21
test/MC/PowerPC/pcrel-tls-initial-exec-address-load-reloc.s
Normal file
@ -0,0 +1,21 @@
|
||||
# RUN: llvm-mc -triple=powerpc64le-unknown-unknown -filetype=obj %s 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=MC
|
||||
# RUN: llvm-mc -triple=powerpc64le-unknown-unknown -filetype=obj %s | \
|
||||
# RUN: llvm-readobj -r - | FileCheck %s -check-prefix=READOBJ
|
||||
|
||||
# This test checks that on Power PC we can correctly convert x@got@tprel@pcrel
|
||||
# and x@tls@pcrel into R_PPC64_GOT_TPREL_PCREL34, and R_PPC64_TLS for initial
|
||||
# exec relocations with address loaded.
|
||||
# Note that with R_PPC64_TLS relocations, to distinguish PC relative
|
||||
# TLS the relocation has a field value displaced by one byte from the
|
||||
# beginning of the instruction.
|
||||
|
||||
# MC-NOT: error: invalid variant
|
||||
|
||||
# READOBJ: 0x0 R_PPC64_GOT_TPREL_PCREL34 x 0x0
|
||||
# READOBJ-NEXT: 0x9 R_PPC64_TLS x 0x0
|
||||
|
||||
InitialExec:
|
||||
pld 3, x@got@tprel@pcrel(0), 1
|
||||
add 3, 3, x@tls@pcrel
|
||||
blr
|
21
test/MC/PowerPC/pcrel-tls-initial-exec-value-load-reloc.s
Normal file
21
test/MC/PowerPC/pcrel-tls-initial-exec-value-load-reloc.s
Normal file
@ -0,0 +1,21 @@
|
||||
# RUN: llvm-mc -triple=powerpc64le-unknown-unknown -filetype=obj %s 2>&1 | \
|
||||
# RUN: FileCheck %s -check-prefix=MC
|
||||
# RUN: llvm-mc -triple=powerpc64le-unknown-unknown -filetype=obj %s | \
|
||||
# RUN: llvm-readobj -r - | FileCheck %s -check-prefix=READOBJ
|
||||
|
||||
# This test checks that on Power PC we can correctly convert x@got@tprel@pcrel
|
||||
# and x@tls@pcrel into R_PPC64_GOT_TPREL_PCREL34, and R_PPC64_TLS for initial
|
||||
# exec relocations with the value loaded.
|
||||
# Note that with R_PPC64_TLS relocations, to distinguish PC relative
|
||||
# TLS the relocation has a field value displaced by one byte from the
|
||||
# beginning of the instruction.
|
||||
|
||||
# MC-NOT: error: invalid variant
|
||||
|
||||
# READOBJ: 0x0 R_PPC64_GOT_TPREL_PCREL34 x 0x0
|
||||
# READOBJ-NEXT: 0x9 R_PPC64_TLS x 0x0
|
||||
|
||||
InitialExecLoad:
|
||||
pld 3, x@got@tprel@pcrel(0), 1
|
||||
lwzx 3, 3, x@tls@pcrel
|
||||
blr
|
Loading…
x
Reference in New Issue
Block a user