diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index c124fe1ed8b..52ac5476214 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -335,6 +335,8 @@ namespace llvm { void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0); protected: + virtual void EmitFunctionEntryLabel(); + virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV); /// processDebugLoc - Processes the debug information of each machine diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8c9b0f1a898..fd29937eb0b 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -313,8 +313,11 @@ void AsmPrinter::EmitFunctionHeader() { /*PrintType=*/false, F->getParent()); OutStreamer.GetCommentOS() << '\n'; } - OutStreamer.EmitLabel(CurrentFnSym); + // Emit the CurrentFnSym. This is is a virtual function to allow targets to + // do their wild and crazy things as required. + EmitFunctionEntryLabel(); + // Add some workaround for linkonce linkage on Cygwin\MinGW. if (MAI->getLinkOnceDirective() != 0 && (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) @@ -326,7 +329,11 @@ void AsmPrinter::EmitFunctionHeader() { DW->BeginFunction(MF); } - +/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the +/// function. This can be overridden by targets as required to do custom stuff. +void AsmPrinter::EmitFunctionEntryLabel() { + OutStreamer.EmitLabel(CurrentFnSym); +} bool AsmPrinter::doFinalization(Module &M) { diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index 398c49e97e2..7fd17690f4d 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -337,6 +337,8 @@ namespace { bool runOnMachineFunction(MachineFunction &F); bool doFinalization(Module &M); + virtual void EmitFunctionEntryLabel(); + void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); @@ -594,77 +596,45 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { processDebugLoc(MI, false); } +void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { + if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. + return AsmPrinter::EmitFunctionEntryLabel(); + + // Emit an official procedure descriptor. + // FIXME 64-bit SVR4: Use MCSection here! + O << "\t.section\t\".opd\",\"aw\"\n"; + O << "\t.align 3\n"; + OutStreamer.EmitLabel(CurrentFnSym); + O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n"; + O << "\t.previous\n"; + O << ".L." << *CurrentFnSym << ":\n"; +} + + /// runOnMachineFunction - This uses the printMachineInstruction() /// method to print assembly for each instruction. /// bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SetupMachineFunction(MF); O << "\n\n"; - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // Print out labels for the function. - const Function *F = MF.getFunction(); - OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); - - switch (F->getLinkage()) { - default: llvm_unreachable("Unknown linkage type!"); - case Function::PrivateLinkage: - case Function::InternalLinkage: // Symbols default to internal. - break; - case Function::ExternalLinkage: - O << "\t.global\t" << *CurrentFnSym << '\n' << "\t.type\t"; - O << *CurrentFnSym << ", @function\n"; - break; - case Function::LinkerPrivateLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - O << "\t.global\t" << *CurrentFnSym << '\n'; - O << "\t.weak\t" << *CurrentFnSym << '\n'; - break; - } - - printVisibility(CurrentFnSym, F->getVisibility()); - - EmitAlignment(MF.getAlignment(), F); - - if (Subtarget.isPPC64()) { - // Emit an official procedure descriptor. - // FIXME 64-bit SVR4: Use MCSection here! - O << "\t.section\t\".opd\",\"aw\"\n"; - O << "\t.align 3\n"; - O << *CurrentFnSym << ":\n"; - O << "\t.quad .L." << *CurrentFnSym << ",.TOC.@tocbase\n"; - O << "\t.previous\n"; - O << ".L." << *CurrentFnSym << ":\n"; - } else { - O << *CurrentFnSym << ":\n"; - } - - // Emit pre-function debug information. - DW->BeginFunction(&MF); + + EmitFunctionHeader(); // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { // Print a label for the basic block. - if (I != MF.begin()) { + if (I != MF.begin()) EmitBasicBlockStart(I); - } + + // Print the assembly for the instructions. for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. + II != E; ++II) printMachineInstruction(II); - } } O << "\t.size\t" << *CurrentFnSym << ",.-" << *CurrentFnSym << '\n'; - OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); - // Emit post-function debug information. DW->EndFunction(&MF);