summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 6e0fdd8574e..124c1827154 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -167,7 +167,13 @@ public:
StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
+ void SetupMachineFunction(MachineFunction &MF) override;
+
void EmitGlobalVariable(const GlobalVariable *GV) override;
+
+ void EmitFunctionDescriptor() override;
+
+ void EmitEndOfAsmFile(Module &) override;
};
} // end anonymous namespace
@@ -1669,6 +1675,18 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
return AsmPrinter::doFinalization(M);
}
+void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
+ // Get the function descriptor symbol.
+ CurrentFnDescSym = getSymbol(&MF.getFunction());
+ // Set the containing csect.
+ MCSectionXCOFF *FnDescSec = OutStreamer->getContext().getXCOFFSection(
+ CurrentFnDescSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD,
+ XCOFF::C_HIDEXT, SectionKind::getData());
+ cast<MCSymbolXCOFF>(CurrentFnDescSym)->setContainingCsect(FnDescSec);
+
+ return AsmPrinter::SetupMachineFunction(MF);
+}
+
void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// Early error checking limiting what is supported.
if (GV->isThreadLocal())
@@ -1718,6 +1736,45 @@ void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
}
+void PPCAIXAsmPrinter::EmitFunctionDescriptor() {
+ const DataLayout &DL = getDataLayout();
+ const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
+
+ MCSectionSubPair Current = OutStreamer->getCurrentSection();
+ // Emit function descriptor.
+ OutStreamer->SwitchSection(
+ cast<MCSymbolXCOFF>(CurrentFnDescSym)->getContainingCsect());
+ OutStreamer->EmitLabel(CurrentFnDescSym);
+ // Emit function entry point address.
+ OutStreamer->EmitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
+ PointerSize);
+ // Emit TOC base address.
+ MCSymbol *TOCBaseSym = OutContext.getOrCreateSymbol(StringRef("TOC[TC0]"));
+ OutStreamer->EmitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
+ PointerSize);
+ // Emit a null environment pointer.
+ OutStreamer->EmitIntValue(0, PointerSize);
+
+ OutStreamer->SwitchSection(Current.first, Current.second);
+}
+
+void PPCAIXAsmPrinter::EmitEndOfAsmFile(Module &M) {
+ // If there are no functions in this module, we will never need to reference
+ // the TOC base.
+ if (M.empty())
+ return;
+
+ // Emit TOC base.
+ MCSymbol *TOCBaseSym = OutContext.getOrCreateSymbol(StringRef("TOC[TC0]"));
+ MCSectionXCOFF *TOCBaseSection = OutStreamer->getContext().getXCOFFSection(
+ StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT,
+ SectionKind::getData());
+ cast<MCSymbolXCOFF>(TOCBaseSym)->setContainingCsect(TOCBaseSection);
+ // Switch to section to emit TOC base.
+ OutStreamer->SwitchSection(TOCBaseSection);
+}
+
+
/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
/// for a MachineFunction to the given output stream, in a format that the
/// Darwin assembler can deal with.
OpenPOWER on IntegriCloud