Skip to content

Commit ae3377c

Browse files
[AIX][TLS] Add ASM portion changes to support TLSGD relocations to XCOFF objects
- Add new variantKinds for the symbol's variable offset and region handle - Print the proper relocation specifier @gd in the asm streamer when emitting the TC Entry for the variable offset for the symbol - Fix the switch section failure between the TC Entry of variable offset and region handle - Put .__tls_get_addr symbol in the ProgramCodeSects with XTY_ER property Reviewed by: sfertile Differential Revision: https://reviews.llvm.org/D100956
1 parent cc63203 commit ae3377c

File tree

10 files changed

+228
-166
lines changed

10 files changed

+228
-166
lines changed

llvm/include/llvm/MC/MCExpr.h

+2
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,8 @@ class MCSymbolRefExpr : public MCExpr {
296296
VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
297297
VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
298298
VK_PPC_TLSGD, // symbol@tlsgd
299+
VK_PPC_AIX_TLSGD, // symbol@gd
300+
VK_PPC_AIX_TLSGDM, // symbol@m
299301
VK_PPC_GOT_TLSLD, // symbol@got@tlsld
300302
VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
301303
VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h

llvm/lib/MC/MCExpr.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
322322
case VK_PPC_GOT_TLSGD_HI: return "got@tlsgd@h";
323323
case VK_PPC_GOT_TLSGD_HA: return "got@tlsgd@ha";
324324
case VK_PPC_TLSGD: return "tlsgd";
325+
case VK_PPC_AIX_TLSGD:
326+
return "gd";
327+
case VK_PPC_AIX_TLSGDM:
328+
return "m";
325329
case VK_PPC_GOT_TLSLD: return "got@tlsld";
326330
case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l";
327331
case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h";

llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,14 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
145145
MCSymbolXCOFF *TCSym =
146146
cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
147147
->getQualNameSymbol();
148-
// If the variant kind is TLSGD the entry represents the region handle for
149-
// the symbol, we prefix the name with a dot and we add the @m
150-
// relocation specifier.
151-
if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_TLSGD)
152-
OS << "\t.tc ." << TCSym->getName() << "," << XSym->getName() << "@m\n";
148+
// If the variant kind is VK_PPC_AIX_TLSGDM the entry represents the
149+
// region handle for the symbol, we add the relocation specifier @m.
150+
// If the variant kind is VK_PPC_AIX_TLSGD the entry represents the
151+
// variable offset for the symbol, we add the relocation specifier @gd.
152+
if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD ||
153+
Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM)
154+
OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
155+
<< MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
153156
else
154157
OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << '\n';
155158

llvm/lib/Target/PowerPC/PPC.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ FunctionPass *createPPCCTRLoops();
116116
MO_PCREL_OPT_FLAG = 16,
117117

118118
/// MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to
119-
/// TLS General Dynamic model.
119+
/// TLS General Dynamic model for Linux and the variable offset of TLS
120+
/// General Dynamic model for AIX.
120121
MO_TLSGD_FLAG = 32,
121122

122123
/// MO_TPREL_FLAG - If this bit is set the symbol reference is relative to
@@ -127,6 +128,10 @@ FunctionPass *createPPCCTRLoops();
127128
/// TLS Local Dynamic model.
128129
MO_TLSLD_FLAG = 128,
129130

131+
/// MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative
132+
/// to the region handle of TLS General Dynamic model for AIX.
133+
MO_TLSGDM_FLAG = 256,
134+
130135
/// MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set
131136
/// they should produce the relocation @got@tlsgd@pcrel.
132137
/// Fix up is VK_PPC_GOT_TLSGD_PCREL

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

+37-12
Original file line numberDiff line numberDiff line change
@@ -522,12 +522,20 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
522522
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
523523
}
524524

525+
/// This helper function creates the TlsGetAddr MCSymbol for AIX. We will
526+
/// create the csect and use the qual-name symbol instead of creating just the
527+
/// external symbol.
528+
static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx) {
529+
return Ctx
530+
.getXCOFFSection(".__tls_get_addr", SectionKind::getText(),
531+
XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER))
532+
->getQualNameSymbol();
533+
}
534+
525535
/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
526536
/// call to __tls_get_addr to the current output stream.
527537
void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
528538
MCSymbolRefExpr::VariantKind VK) {
529-
StringRef Name = Subtarget->isAIXABI() ? ".__tls_get_addr" : "__tls_get_addr";
530-
MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
531539
MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
532540
unsigned Opcode = PPC::BL8_NOP_TLS;
533541

@@ -558,13 +566,15 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
558566
assert(MI->getOperand(2).isReg() &&
559567
MI->getOperand(2).getReg() == VarOffsetReg &&
560568
"GETtls[ld]ADDR[32] must read GPR4");
561-
MCSymbol *TlsGetAddrA = OutContext.getOrCreateSymbol(Name);
569+
MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext);
562570
const MCExpr *TlsRef = MCSymbolRefExpr::create(
563-
TlsGetAddrA, MCSymbolRefExpr::VK_None, OutContext);
571+
TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
564572
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
565573
return;
566574
}
567575

576+
MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr");
577+
568578
if (Subtarget->is32BitELFABI() && isPositionIndependent())
569579
Kind = MCSymbolRefExpr::VK_PLT;
570580

@@ -673,10 +683,12 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
673683
};
674684
auto GetVKForMO = [&](const MachineOperand &MO) {
675685
// For GD TLS access on AIX, we have two TOC entries for the symbol (one for
676-
// the offset and the other for the region handle). They are differentiated
677-
// by the presence of the PPCII::MO_TLSGD_FLAG.
678-
if (IsAIX && (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG))
679-
return MCSymbolRefExpr::VariantKind::VK_PPC_TLSGD;
686+
// the variable offset and the other for the region handle). They are
687+
// differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
688+
if (MO.getTargetFlags() & PPCII::MO_TLSGDM_FLAG)
689+
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
690+
if (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG)
691+
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
680692
return MCSymbolRefExpr::VariantKind::VK_None;
681693
};
682694

@@ -2232,9 +2244,22 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
22322244
static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
22332245

22342246
for (auto &I : TOC) {
2235-
// Setup the csect for the current TC entry.
2236-
MCSectionXCOFF *TCEntry = cast<MCSectionXCOFF>(
2237-
getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
2247+
MCSectionXCOFF *TCEntry;
2248+
// Setup the csect for the current TC entry. If the variant kind is
2249+
// VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a
2250+
// new symbol to prefix the name with a dot.
2251+
if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) {
2252+
SmallString<128> Name;
2253+
StringRef Prefix = ".";
2254+
Name += Prefix;
2255+
Name += I.first.first->getName();
2256+
MCSymbol *S = OutContext.getOrCreateSymbol(Name);
2257+
TCEntry = cast<MCSectionXCOFF>(
2258+
getObjFileLowering().getSectionForTOCEntry(S, TM));
2259+
} else {
2260+
TCEntry = cast<MCSectionXCOFF>(
2261+
getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
2262+
}
22382263
OutStreamer->SwitchSection(TCEntry);
22392264

22402265
OutStreamer->emitLabel(I.second);
@@ -2317,7 +2342,7 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
23172342
case PPC::GETtlsADDR32AIX: {
23182343
// The reference to .__tls_get_addr is unknown to the assembler
23192344
// so we need to emit an external symbol reference.
2320-
MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(".__tls_get_addr");
2345+
MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext);
23212346
ExtSymSDNodeSymbols.insert(TlsGetAddr);
23222347
break;
23232348
}

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -3146,11 +3146,12 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
31463146
// all the GlobalTLSAddress nodes are lowered with this model.
31473147
// We need to generate two TOC entries, one for the variable offset, one for
31483148
// the region handle. The global address for the TOC entry of the region
3149-
// handle is created with the MO_TLSGD_FLAG flag so we can easily identify
3150-
// this entry and add the right relocation.
3151-
SDValue VariableOffsetTGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
3152-
SDValue RegionHandleTGA =
3149+
// handle is created with the MO_TLSGDM_FLAG flag and the global address
3150+
// for the TOC entry of the variable offset is created with MO_TLSGD_FLAG.
3151+
SDValue VariableOffsetTGA =
31533152
DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TLSGD_FLAG);
3153+
SDValue RegionHandleTGA =
3154+
DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TLSGDM_FLAG);
31543155
SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
31553156
SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
31563157
return DAG.getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,

llvm/lib/Target/PowerPC/PPCInstrInfo.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -2893,6 +2893,7 @@ PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
28932893
{MO_TLSGD_FLAG, "ppc-tlsgd"},
28942894
{MO_TLSLD_FLAG, "ppc-tlsld"},
28952895
{MO_TPREL_FLAG, "ppc-tprel"},
2896+
{MO_TLSGDM_FLAG, "ppc-tlsgdm"},
28962897
{MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},
28972898
{MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},
28982899
{MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"}};

0 commit comments

Comments
 (0)