The original patch had a merge error and wouldn't compile. This one has been fixed. As well, a large #if 0 has been replaced with a simple "TODO" comment.
Nick
Index: lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp,v retrieving revision 1.226 diff -u -r1.226 PPCAsmPrinter.cpp --- lib/Target/PowerPC/PPCAsmPrinter.cpp 20 Dec 2006 21:35:00 -0000 1.226 +++ lib/Target/PowerPC/PPCAsmPrinter.cpp 21 Dec 2006 01:19:14 -0000 @@ -282,6 +282,35 @@ virtual bool doFinalization(Module &M) = 0; }; + /// LinuxAsmPrinter - PowerPC assembly printer, customized for Linux + struct VISIBILITY_HIDDEN LinuxAsmPrinter : public PPCAsmPrinter { + + DwarfWriter DW; + + LinuxAsmPrinter(std::ostream &O, PPCTargetMachine &TM, + const TargetAsmInfo *T) + : PPCAsmPrinter(O, TM, T), DW(O, this, T) { + } + + virtual const char *getPassName() const { + return "Linux PPC Assembly Printer"; + } + + bool runOnMachineFunction(MachineFunction &F); + bool doInitialization(Module &M); + bool doFinalization(Module &M); + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + AU.addRequired<MachineDebugInfo>(); + PPCAsmPrinter::getAnalysisUsage(AU); + } + + /// getSectionForFunction - Return the section that we should emit the + /// specified function body into. + virtual std::string getSectionForFunction(const Function &F) const; + }; + /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS /// X struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter { @@ -491,7 +520,194 @@ return; } +/// runOnMachineFunction - This uses the printMachineInstruction() +/// method to print assembly for each instruction. +/// +bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { + DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>()); + + 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(); + SwitchToTextSection(getSectionForFunction(*F).c_str(), F); + + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + break; + case Function::ExternalLinkage: + O << "\t.global\t" << CurrentFnName << '\n' + << "\t.type\t" << CurrentFnName << ", @function\n"; + break; + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + O << "\t.global\t" << CurrentFnName << '\n'; + O << "\t.weak\t" << CurrentFnName << '\n'; + break; + } + EmitAlignment(2, F); + O << CurrentFnName << ":\n"; + + // Emit pre-function debug information. + DW.BeginFunction(&MF); + + // 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()) { + printBasicBlockLabel(I, true); + O << '\n'; + } + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) { + // Print the assembly for the instruction. + O << "\t"; + printMachineInstruction(II); + } + } + + O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n"; + + // Print out jump tables referenced by the function. + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + + // Emit post-function debug information. + DW.EndFunction(); + + // We didn't modify anything. + return false; +} + +bool LinuxAsmPrinter::doInitialization(Module &M) { + AsmPrinter::doInitialization(M); + + // GNU as handles section names wrapped in quotes + Mang->setUseQuotes(true); + + SwitchToTextSection(TAI->getTextSection()); + + // Emit initial debug information. + DW.BeginModule(&M); + return false; +} + +bool LinuxAsmPrinter::doFinalization(Module &M) { + const TargetData *TD = TM.getTargetData(); + // Print out module-level global variables here. + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + if (!I->hasInitializer()) continue; // External global require no code + + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(I)) + continue; + + std::string name = Mang->getValueName(I); + Constant *C = I->getInitializer(); + unsigned Size = TD->getTypeSize(C->getType()); + unsigned Align = TD->getPreferredAlignmentLog(I); + + if (C->isNullValue() && /* FIXME: Verify correct */ + (I->hasInternalLinkage() || I->hasWeakLinkage() || + I->hasLinkOnceLinkage() || + (I->hasExternalLinkage() && !I->hasSection()))) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + if (I->hasExternalLinkage()) { + O << "\t.global " << name << '\n'; + O << "\t.type " << name << ", @object\n"; + //O << "\t.zerofill __DATA, __common, " << name << ", " + // << Size << ", " << Align; + } else if (I->hasInternalLinkage()) { + SwitchToDataSection("\t.data", I); + O << TAI->getLCOMMDirective() << name << "," << Size; + } else { + SwitchToDataSection("\t.data", I); + O << ".comm " << name << "," << Size; + } + O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n"; + } else { + switch (I->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: + O << "\t.global " << name << '\n' + << "\t.type " << name << ", @object\n" + << "\t.weak " << name << '\n'; + SwitchToDataSection("\t.data", I); + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << "\t.global " << name << "\n" + << "\t.type " << name << ", @object\n"; + // FALL THROUGH + case GlobalValue::InternalLinkage: + if (I->isConstant()) { + const ConstantArray *CVA = dyn_cast<ConstantArray>(C); + if (TAI->getCStringSection() && CVA && CVA->isCString()) { + SwitchToDataSection(TAI->getCStringSection(), I); + break; + } + } + + // FIXME: special handling for ".ctors" & ".dtors" sections + if (I->hasSection() && + (I->getSection() == ".ctors" || + I->getSection() == ".dtors")) { + std::string SectionName = ".section " + I->getSection() + + ",\"aw\",@progbits"; + SwitchToDataSection(SectionName.c_str()); + } else { + SwitchToDataSection(TAI->getDataSection(), I); + } + break; + default: + cerr << "Unknown linkage type!"; + abort(); + } + + EmitAlignment(Align, I); + O << name << ":\t\t\t\t" << TAI->getCommentString() << " '" + << I->getName() << "'\n"; + + // If the initializer is a extern weak symbol, remember to emit the weak + // reference! + if (const GlobalValue *GV = dyn_cast<GlobalValue>(C)) + if (GV->hasExternalWeakLinkage()) + ExtWeakSymbols.insert(GV); + + EmitGlobalConstant(C); + O << '\n'; + } + } + + // TODO + + // Emit initial debug information. + DW.EndModule(); + + AsmPrinter::doFinalization(M); + return false; // success +} + +std::string LinuxAsmPrinter::getSectionForFunction(const Function &F) const { + switch (F.getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::ExternalLinkage: + case Function::InternalLinkage: return TAI->getTextSection(); + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + return ".text"; + } +} std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const { switch (F.getLinkage()) { @@ -786,6 +1002,12 @@ /// FunctionPass *llvm::createPPCAsmPrinterPass(std::ostream &o, PPCTargetMachine &tm) { - return new DarwinAsmPrinter(o, tm, tm.getTargetAsmInfo()); + const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); + + if (Subtarget->isDarwin()) { + return new DarwinAsmPrinter(o, tm, tm.getTargetAsmInfo()); + } else { + return new LinuxAsmPrinter(o, tm, tm.getTargetAsmInfo()); + } } Index: lib/Target/PowerPC/PPCRegisterInfo.td =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCRegisterInfo.td,v retrieving revision 1.42 diff -u -r1.42 PPCRegisterInfo.td --- lib/Target/PowerPC/PPCRegisterInfo.td 20 Nov 2006 20:48:05 -0000 1.42 +++ lib/Target/PowerPC/PPCRegisterInfo.td 21 Dec 2006 01:19:14 -0000 @@ -209,9 +209,9 @@ // Allocate volatiles first // then nonvolatiles in reverse order since stmw/lmw save from rN to r31 def GPRC : RegisterClass<"PPC", [i32], 32, - [R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, + [R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17, - R16, R15, R14, R13, R31, R0, R1, LR]> + R16, R15, R14, R2, R13, R31, R0, R1, LR]> { let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -224,6 +224,10 @@ } GPRCClass::iterator GPRCClass::allocation_order_end(const MachineFunction &MF) const { + // In Linux, r2 is reserved for the OS. + if (!MF.getTarget().getSubtarget<PPCSubtarget>().isDarwin()) + return end()-6; + // On PPC64, r13 is the thread pointer. Never allocate this register. // Note that this is overconservative, as it also prevents allocation of // R31 when the FP is not needed. Index: lib/Target/PowerPC/PPCTargetAsmInfo.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCTargetAsmInfo.cpp,v retrieving revision 1.9 diff -u -r1.9 PPCTargetAsmInfo.cpp --- lib/Target/PowerPC/PPCTargetAsmInfo.cpp 1 Dec 2006 20:47:11 -0000 1.9 +++ lib/Target/PowerPC/PPCTargetAsmInfo.cpp 21 Dec 2006 01:19:14 -0000 @@ -52,3 +52,38 @@ DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; } +LinuxTargetAsmInfo::LinuxTargetAsmInfo(const PPCTargetMachine &TM) { + bool isPPC64 = TM.getSubtargetImpl()->isPPC64(); + + CommentString = "#"; + GlobalPrefix = ""; + PrivateGlobalPrefix = ""; + ZeroDirective = "\t.space\t"; + SetDirective = "\t.set"; + Data64bitsDirective = isPPC64 ? "\t.quad\t" : 0; + AlignmentIsInBytes = false; + ConstantPoolSection = "\t.section .rodata.cst4\t"; + JumpTableDataSection = ".section .rodata.cst4"; + CStringSection = "\t.section\t.rodata"; + LCOMMDirective = "\t.lcomm\t"; + StaticCtorsSection = ".section\t.ctors,\"aw\",@progbits"; + StaticDtorsSection = ".section\t.dtors,\"aw\",@progbits"; + UsedDirective = "\t# .no_dead_strip\t"; + WeakRefDirective = "\t.weak\t"; + InlineAsmStart = "# InlineAsm Start"; + InlineAsmEnd = "# InlineAsm End"; + + NeedsSet = true; + AddressSize = isPPC64 ? 8 : 4; + DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; + DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; + DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; + DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; + DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; + DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; + DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; + DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; + DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; + DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; + DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; +} Index: lib/Target/PowerPC/PPCTargetAsmInfo.h =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCTargetAsmInfo.h,v retrieving revision 1.3 diff -u -r1.3 PPCTargetAsmInfo.h --- lib/Target/PowerPC/PPCTargetAsmInfo.h 5 Oct 2006 02:42:20 -0000 1.3 +++ lib/Target/PowerPC/PPCTargetAsmInfo.h 21 Dec 2006 01:19:14 -0000 @@ -25,6 +25,10 @@ DarwinTargetAsmInfo(const PPCTargetMachine &TM); }; + struct LinuxTargetAsmInfo : public TargetAsmInfo { + LinuxTargetAsmInfo(const PPCTargetMachine &TM); + }; + } // namespace llvm #endif Index: lib/Target/PowerPC/PPCTargetMachine.cpp =================================================================== RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCTargetMachine.cpp,v retrieving revision 1.110 diff -u -r1.110 PPCTargetMachine.cpp --- lib/Target/PowerPC/PPCTargetMachine.cpp 11 Dec 2006 23:22:45 -0000 1.110 +++ lib/Target/PowerPC/PPCTargetMachine.cpp 21 Dec 2006 01:19:14 -0000 @@ -28,7 +28,10 @@ } const TargetAsmInfo *PPCTargetMachine::createTargetAsmInfo() const { - return new DarwinTargetAsmInfo(*this); + if (Subtarget.isDarwin()) + return new DarwinTargetAsmInfo(*this); + else + return new LinuxTargetAsmInfo(*this); } unsigned PPC32TargetMachine::getJITMatchQuality() { @@ -90,7 +93,7 @@ if (Subtarget.isDarwin()) setRelocationModel(Reloc::DynamicNoPIC); else - setRelocationModel(Reloc::PIC_); + setRelocationModel(Reloc::Static); } PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS)
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits