diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -79,7 +79,7 @@ class PPCAsmPrinter : public AsmPrinter { protected: - MapVector TOC; + MapVector> TOC; const PPCSubtarget *Subtarget = nullptr; StackMaps SM; @@ -92,7 +92,7 @@ StringRef getPassName() const override { return "PowerPC Assembly Printer"; } - MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym); + std::pair lookUpOrCreateTOCEntry(const MCSymbol *Sym); bool doInitialization(Module &M) override { if (!TOC.empty()) @@ -307,14 +307,15 @@ return false; } -/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry -/// exists for it. If not, create one. Then return a symbol that references -/// the TOC entry. -MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) { - MCSymbol *&TOCEntry = TOC[Sym]; - if (!TOCEntry) - TOCEntry = createTempSymbol("C"); - return TOCEntry; +/// Given a symbol, look up whether a TOC/.got2 entry exists for it. If not, +/// create one. Then return the symbol and its ordinal in TOC/.got2 +std::pair PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) { + std::pair &Entry = TOC[Sym]; + if (!Entry.first) { + Entry.first = createTempSymbol("C"); + Entry.second = int(TOC.size() - 1); + } + return Entry; } void PPCAsmPrinter::emitEndOfAsmFile(Module &M) { @@ -680,9 +681,7 @@ // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the // storage allocated in the TOC which contains the address of // 'MOSymbol'. Said TOC entry will be synthesized later. - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); - const MCExpr *Exp = - MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext); + std::pair TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); // AIX uses the label directly as the lwz displacement operand for // references into the toc section. The displacement value will be generated @@ -691,6 +690,8 @@ assert( TM.getCodeModel() == CodeModel::Small && "This pseudo should only be selected for 32-bit small code model."); + const MCExpr *Exp = MCSymbolRefExpr::create( + TOCEntry.first, MCSymbolRefExpr::VK_None, OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; @@ -698,9 +699,8 @@ // Create an explicit subtract expression between the local symbol and // '.LTOC' to manifest the toc-relative offset. - const MCExpr *PB = MCSymbolRefExpr::create( - OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext); - Exp = MCBinaryExpr::createSub(Exp, PB, OutContext); + const auto *Exp = + MCConstantExpr::create(TOCEntry.second * 4 - 0x8000, OutContext); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; @@ -723,7 +723,7 @@ // global address operand to be a reference to the TOC entry we will // synthesize later. MCSymbol *TOCEntry = - lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO)); + lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO)).first; const MCSymbolRefExpr::VariantKind VK = IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC; @@ -755,7 +755,7 @@ // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to // reference the storage allocated in the TOC which contains the address of // 'MOSymbol'. - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol).first; const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_U, OutContext); @@ -785,7 +785,7 @@ // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to // reference the storage allocated in the TOC which contains the address of // 'MOSymbol'. - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol).first; const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_L, OutContext); @@ -813,7 +813,7 @@ MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal()); if (GlobalToc || MO.isJTI() || MO.isBlockAddress() || (MO.isCPI() && TM.getCodeModel() == CodeModel::Large)) - MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); + MOSymbol = lookUpOrCreateTOCEntry(MOSymbol).first; const MCSymbolRefExpr::VariantKind VK = IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA; @@ -854,7 +854,7 @@ const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO); if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large) - MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); + MOSymbol = lookUpOrCreateTOCEntry(MOSymbol).first; const MCSymbolRefExpr::VariantKind VK = IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO; @@ -1409,9 +1409,9 @@ MCSectionELF *CurSection = nullptr, *Section; for (const auto &TOCMapPair : TOC) { const MCSymbol *const TOCEntryTarget = TOCMapPair.first; - MCSymbol *const TOCEntryLabel = TOCMapPair.second; + MCSymbol *const TOCEntryLabel = TOCMapPair.second.first; const MCSymbolELF *Group = nullptr; - if (isPPC64 && TOCEntryTarget->isInSection()) + if (TOCEntryTarget->isInSection()) Group = cast(TOCEntryTarget->getSection()).getGroup(); Section = OutStreamer->getContext().getELFSection( Name, ELF::SHT_PROGBITS, @@ -1691,10 +1691,10 @@ // Setup the csect for the current TC entry. MCSectionXCOFF *TCEntry = cast( getObjFileLowering().getSectionForTOCEntry(I.first)); - cast(I.second)->setContainingCsect(TCEntry); + cast(I.second.first)->setContainingCsect(TCEntry); OutStreamer->SwitchSection(TCEntry); - OutStreamer->emitLabel(I.second); + OutStreamer->emitLabel(I.second.first); TS.emitTCEntry(*I.first); } }