@@ -78,11 +78,42 @@ using namespace llvm::XCOFF;
78
78
79
79
#define DEBUG_TYPE " asmprinter"
80
80
81
+ // Specialize DenseMapInfo to allow
82
+ // std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap.
83
+ // This specialization is needed here because that type is used as keys in the
84
+ // map representing TOC entries.
85
+ template <>
86
+ struct DenseMapInfo <std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> {
87
+ using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;
88
+
89
+ static inline TOCKey getEmptyKey () {
90
+ return {nullptr , MCSymbolRefExpr::VariantKind::VK_None};
91
+ }
92
+ static inline TOCKey getTombstoneKey () {
93
+ return {nullptr , MCSymbolRefExpr::VariantKind::VK_Invalid};
94
+ }
95
+ static unsigned getHashValue (const TOCKey &PairVal) {
96
+ return detail::combineHashValue (
97
+ DenseMapInfo<const MCSymbol *>::getHashValue (PairVal.first ),
98
+ DenseMapInfo<int >::getHashValue (PairVal.second ));
99
+ }
100
+ static bool isEqual (const TOCKey &A, const TOCKey &B) { return A == B; }
101
+ };
102
+
81
103
namespace {
82
104
83
105
class PPCAsmPrinter : public AsmPrinter {
84
106
protected:
85
- MapVector<const MCSymbol *, MCSymbol *> TOC;
107
+ // For TLS on AIX, we need to be able to identify TOC entries of specific
108
+ // VariantKind so we can add the right relocations when we generate the
109
+ // entries. So each entry is represented by a pair of MCSymbol and
110
+ // VariantKind. For example, we need to be able to identify the following
111
+ // entry as a TLSGD entry so we can add the @m relocation:
112
+ // .tc .i[TC],i[TL]@m
113
+ // By default, VK_None is used for the VariantKind.
114
+ MapVector<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>,
115
+ MCSymbol *>
116
+ TOC;
86
117
const PPCSubtarget *Subtarget = nullptr ;
87
118
StackMaps SM;
88
119
@@ -93,7 +124,9 @@ class PPCAsmPrinter : public AsmPrinter {
93
124
94
125
StringRef getPassName () const override { return " PowerPC Assembly Printer" ; }
95
126
96
- MCSymbol *lookUpOrCreateTOCEntry (const MCSymbol *Sym);
127
+ MCSymbol *lookUpOrCreateTOCEntry (const MCSymbol *Sym,
128
+ MCSymbolRefExpr::VariantKind Kind =
129
+ MCSymbolRefExpr::VariantKind::VK_None);
97
130
98
131
bool doInitialization (Module &M) override {
99
132
if (!TOC.empty ())
@@ -344,8 +377,10 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
344
377
// / lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
345
378
// / exists for it. If not, create one. Then return a symbol that references
346
379
// / the TOC entry.
347
- MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry (const MCSymbol *Sym) {
348
- MCSymbol *&TOCEntry = TOC[Sym];
380
+ MCSymbol *
381
+ PPCAsmPrinter::lookUpOrCreateTOCEntry (const MCSymbol *Sym,
382
+ MCSymbolRefExpr::VariantKind Kind) {
383
+ MCSymbol *&TOCEntry = TOC[{Sym, Kind}];
349
384
if (!TOCEntry)
350
385
TOCEntry = createTempSymbol (" C" );
351
386
return TOCEntry;
@@ -604,7 +639,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
604
639
[IsPPC64, getTOCRelocAdjustedExprForXCOFF,
605
640
this ](const MCSymbol *MOSymbol, const MCExpr *Expr) -> const MCExpr * {
606
641
const unsigned EntryByteSize = IsPPC64 ? 8 : 4 ;
607
- const auto TOCEntryIter = TOC.find (MOSymbol);
642
+ const auto TOCEntryIter =
643
+ TOC.find ({MOSymbol, MCSymbolRefExpr::VariantKind::VK_None});
608
644
assert (TOCEntryIter != TOC.end () &&
609
645
" Could not find the TOC entry for this symbol." );
610
646
const ptrdiff_t EntryDistanceFromTOCBase =
@@ -1505,7 +1541,7 @@ void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {
1505
1541
OutStreamer->emitValueToAlignment (4 );
1506
1542
1507
1543
for (const auto &TOCMapPair : TOC) {
1508
- const MCSymbol *const TOCEntryTarget = TOCMapPair.first ;
1544
+ const MCSymbol *const TOCEntryTarget = TOCMapPair.first . first ;
1509
1545
MCSymbol *const TOCEntryLabel = TOCMapPair.second ;
1510
1546
1511
1547
OutStreamer->emitLabel (TOCEntryLabel);
@@ -2163,12 +2199,12 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
2163
2199
for (auto &I : TOC) {
2164
2200
// Setup the csect for the current TC entry.
2165
2201
MCSectionXCOFF *TCEntry = cast<MCSectionXCOFF>(
2166
- getObjFileLowering ().getSectionForTOCEntry (I.first , TM));
2202
+ getObjFileLowering ().getSectionForTOCEntry (I.first . first , TM));
2167
2203
OutStreamer->SwitchSection (TCEntry);
2168
2204
2169
2205
OutStreamer->emitLabel (I.second );
2170
2206
if (TS != nullptr )
2171
- TS->emitTCEntry (*I.first );
2207
+ TS->emitTCEntry (*I.first . first );
2172
2208
}
2173
2209
}
2174
2210
0 commit comments