Add PPC Freescale e500mc and e5500 subtargets.
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to PowerPC assembly language. This printer is
12 // the output mechanism used by `llc'.
13 //
14 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
15 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16 //
17 //===----------------------------------------------------------------------===//
18
19 #define DEBUG_TYPE "asmprinter"
20 #include "PPC.h"
21 #include "PPCTargetMachine.h"
22 #include "PPCSubtarget.h"
23 #include "InstPrinter/PPCInstPrinter.h"
24 #include "MCTargetDesc/PPCPredicates.h"
25 #include "llvm/Constants.h"
26 #include "llvm/DebugInfo.h"
27 #include "llvm/DerivedTypes.h"
28 #include "llvm/Module.h"
29 #include "llvm/Assembly/Writer.h"
30 #include "llvm/CodeGen/AsmPrinter.h"
31 #include "llvm/CodeGen/MachineFunctionPass.h"
32 #include "llvm/CodeGen/MachineInstr.h"
33 #include "llvm/CodeGen/MachineInstrBuilder.h"
34 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
35 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
36 #include "llvm/MC/MCAsmInfo.h"
37 #include "llvm/MC/MCContext.h"
38 #include "llvm/MC/MCExpr.h"
39 #include "llvm/MC/MCInst.h"
40 #include "llvm/MC/MCSectionMachO.h"
41 #include "llvm/MC/MCStreamer.h"
42 #include "llvm/MC/MCSymbol.h"
43 #include "llvm/MC/MCSectionELF.h"
44 #include "llvm/Target/Mangler.h"
45 #include "llvm/Target/TargetRegisterInfo.h"
46 #include "llvm/Target/TargetInstrInfo.h"
47 #include "llvm/Target/TargetOptions.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/Debug.h"
50 #include "llvm/Support/MathExtras.h"
51 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/TargetRegistry.h"
53 #include "llvm/Support/raw_ostream.h"
54 #include "llvm/Support/ELF.h"
55 #include "llvm/ADT/StringExtras.h"
56 #include "llvm/ADT/SmallString.h"
57 using namespace llvm;
58
59 namespace {
60   class PPCAsmPrinter : public AsmPrinter {
61   protected:
62     DenseMap<MCSymbol*, MCSymbol*> TOC;
63     const PPCSubtarget &Subtarget;
64     uint64_t TOCLabelID;
65   public:
66     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
67       : AsmPrinter(TM, Streamer),
68         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
69
70     virtual const char *getPassName() const {
71       return "PowerPC Assembly Printer";
72     }
73
74
75     virtual void EmitInstruction(const MachineInstr *MI);
76
77     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
78
79     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
80                          unsigned AsmVariant, const char *ExtraCode,
81                          raw_ostream &O);
82     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
83                                unsigned AsmVariant, const char *ExtraCode,
84                                raw_ostream &O);
85
86     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
87       MachineLocation Location;
88       assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
89       // Frame address.  Currently handles register +- offset only.
90       if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
91         Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
92       else {
93         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
94       }
95       return Location;
96     }
97   };
98
99   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
100   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
101   public:
102     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
103       : PPCAsmPrinter(TM, Streamer) {}
104
105     virtual const char *getPassName() const {
106       return "Linux PPC Assembly Printer";
107     }
108
109     bool doFinalization(Module &M);
110
111     virtual void EmitFunctionEntryLabel();
112   };
113
114   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
115   /// OS X
116   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
117   public:
118     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
119       : PPCAsmPrinter(TM, Streamer) {}
120
121     virtual const char *getPassName() const {
122       return "Darwin PPC Assembly Printer";
123     }
124
125     bool doFinalization(Module &M);
126     void EmitStartOfAsmFile(Module &M);
127
128     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
129   };
130 } // end of anonymous namespace
131
132 /// stripRegisterPrefix - This method strips the character prefix from a
133 /// register name so that only the number is left.  Used by for linux asm.
134 static const char *stripRegisterPrefix(const char *RegName) {
135   switch (RegName[0]) {
136     case 'r':
137     case 'f':
138     case 'v': return RegName + 1;
139     case 'c': if (RegName[1] == 'r') return RegName + 2;
140   }
141   
142   return RegName;
143 }
144
145 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
146                                  raw_ostream &O) {
147   const MachineOperand &MO = MI->getOperand(OpNo);
148   
149   switch (MO.getType()) {
150   case MachineOperand::MO_Register: {
151     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
152     // Linux assembler (Others?) does not take register mnemonics.
153     // FIXME - What about special registers used in mfspr/mtspr?
154     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
155     O << RegName;
156     return;
157   }
158   case MachineOperand::MO_Immediate:
159     O << MO.getImm();
160     return;
161
162   case MachineOperand::MO_MachineBasicBlock:
163     O << *MO.getMBB()->getSymbol();
164     return;
165   case MachineOperand::MO_JumpTableIndex:
166     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
167       << '_' << MO.getIndex();
168     // FIXME: PIC relocation model
169     return;
170   case MachineOperand::MO_ConstantPoolIndex:
171     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
172       << '_' << MO.getIndex();
173     return;
174   case MachineOperand::MO_BlockAddress:
175     O << *GetBlockAddressSymbol(MO.getBlockAddress());
176     return;
177   case MachineOperand::MO_ExternalSymbol: {
178     // Computing the address of an external symbol, not calling it.
179     if (TM.getRelocationModel() == Reloc::Static) {
180       O << *GetExternalSymbolSymbol(MO.getSymbolName());
181       return;
182     }
183
184     MCSymbol *NLPSym = 
185       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
186                                    MO.getSymbolName()+"$non_lazy_ptr");
187     MachineModuleInfoImpl::StubValueTy &StubSym = 
188       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
189     if (StubSym.getPointer() == 0)
190       StubSym = MachineModuleInfoImpl::
191         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
192     
193     O << *NLPSym;
194     return;
195   }
196   case MachineOperand::MO_GlobalAddress: {
197     // Computing the address of a global symbol, not calling it.
198     const GlobalValue *GV = MO.getGlobal();
199     MCSymbol *SymToPrint;
200
201     // External or weakly linked global variables need non-lazily-resolved stubs
202     if (TM.getRelocationModel() != Reloc::Static &&
203         (GV->isDeclaration() || GV->isWeakForLinker())) {
204       if (!GV->hasHiddenVisibility()) {
205         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
206         MachineModuleInfoImpl::StubValueTy &StubSym = 
207           MMI->getObjFileInfo<MachineModuleInfoMachO>()
208             .getGVStubEntry(SymToPrint);
209         if (StubSym.getPointer() == 0)
210           StubSym = MachineModuleInfoImpl::
211             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
212       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
213                  GV->hasAvailableExternallyLinkage()) {
214         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
215         
216         MachineModuleInfoImpl::StubValueTy &StubSym = 
217           MMI->getObjFileInfo<MachineModuleInfoMachO>().
218                     getHiddenGVStubEntry(SymToPrint);
219         if (StubSym.getPointer() == 0)
220           StubSym = MachineModuleInfoImpl::
221             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
222       } else {
223         SymToPrint = Mang->getSymbol(GV);
224       }
225     } else {
226       SymToPrint = Mang->getSymbol(GV);
227     }
228     
229     O << *SymToPrint;
230
231     printOffset(MO.getOffset(), O);
232     return;
233   }
234
235   default:
236     O << "<unknown operand type: " << MO.getType() << ">";
237     return;
238   }
239 }
240
241 /// PrintAsmOperand - Print out an operand for an inline asm expression.
242 ///
243 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
244                                     unsigned AsmVariant,
245                                     const char *ExtraCode, raw_ostream &O) {
246   // Does this asm operand have a single letter operand modifier?
247   if (ExtraCode && ExtraCode[0]) {
248     if (ExtraCode[1] != 0) return true; // Unknown modifier.
249
250     switch (ExtraCode[0]) {
251     default:
252       // See if this is a generic print operand
253       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
254     case 'c': // Don't print "$" before a global var name or constant.
255       break; // PPC never has a prefix.
256     case 'L': // Write second word of DImode reference.
257       // Verify that this operand has two consecutive registers.
258       if (!MI->getOperand(OpNo).isReg() ||
259           OpNo+1 == MI->getNumOperands() ||
260           !MI->getOperand(OpNo+1).isReg())
261         return true;
262       ++OpNo;   // Return the high-part.
263       break;
264     case 'I':
265       // Write 'i' if an integer constant, otherwise nothing.  Used to print
266       // addi vs add, etc.
267       if (MI->getOperand(OpNo).isImm())
268         O << "i";
269       return false;
270     }
271   }
272
273   printOperand(MI, OpNo, O);
274   return false;
275 }
276
277 // At the moment, all inline asm memory operands are a single register.
278 // In any case, the output of this routine should always be just one
279 // assembler operand.
280
281 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
282                                           unsigned AsmVariant,
283                                           const char *ExtraCode,
284                                           raw_ostream &O) {
285   if (ExtraCode && ExtraCode[0])
286     return true; // Unknown modifier.
287   assert(MI->getOperand(OpNo).isReg());
288   O << "0(";
289   printOperand(MI, OpNo, O);
290   O << ")";
291   return false;
292 }
293
294
295 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
296 /// the current output stream.
297 ///
298 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
299   MCInst TmpInst;
300   
301   // Lower multi-instruction pseudo operations.
302   switch (MI->getOpcode()) {
303   default: break;
304   case TargetOpcode::DBG_VALUE: {
305     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
306       
307     SmallString<32> Str;
308     raw_svector_ostream O(Str);
309     unsigned NOps = MI->getNumOperands();
310     assert(NOps==4);
311     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
312     // cast away const; DIetc do not take const operands for some reason.
313     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
314     O << V.getName();
315     O << " <- ";
316     // Frame address.  Currently handles register +- offset only.
317     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
318     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
319     O << ']';
320     O << "+";
321     printOperand(MI, NOps-2, O);
322     OutStreamer.EmitRawText(O.str());
323     return;
324   }
325       
326   case PPC::MovePCtoLR:
327   case PPC::MovePCtoLR8: {
328     // Transform %LR = MovePCtoLR
329     // Into this, where the label is the PIC base: 
330     //     bl L1$pb
331     // L1$pb:
332     MCSymbol *PICBase = MF->getPICBaseSymbol();
333     
334     // Emit the 'bl'.
335     TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here.
336     
337     
338     // FIXME: We would like an efficient form for this, so we don't have to do
339     // a lot of extra uniquing.
340     TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
341                                              Create(PICBase, OutContext)));
342     OutStreamer.EmitInstruction(TmpInst);
343     
344     // Emit the label.
345     OutStreamer.EmitLabel(PICBase);
346     return;
347   }
348   case PPC::LDtocJTI:
349   case PPC::LDtocCPT:
350   case PPC::LDtoc: {
351     // Transform %X3 = LDtoc <ga:@min1>, %X2
352     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
353
354     // Change the opcode to LD, and the global address operand to be a
355     // reference to the TOC entry we will synthesize later.
356     TmpInst.setOpcode(PPC::LD);
357     const MachineOperand &MO = MI->getOperand(1);
358
359     // Map symbol -> label of TOC entry
360     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
361     MCSymbol *MOSymbol = 0;
362     if (MO.isGlobal())
363       MOSymbol = Mang->getSymbol(MO.getGlobal());
364     else if (MO.isCPI())
365       MOSymbol = GetCPISymbol(MO.getIndex());
366     else if (MO.isJTI())
367       MOSymbol = GetJTISymbol(MO.getIndex());
368     MCSymbol *&TOCEntry = TOC[MOSymbol];
369     if (TOCEntry == 0)
370       TOCEntry = GetTempSymbol("C", TOCLabelID++);
371     
372     const MCExpr *Exp =
373       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
374                               OutContext);
375     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
376     OutStreamer.EmitInstruction(TmpInst);
377     return;
378   }
379       
380   case PPC::MFCRpseud:
381   case PPC::MFCR8pseud:
382     // Transform: %R3 = MFCRpseud %CR7
383     // Into:      %R3 = MFCR      ;; cr7
384     OutStreamer.AddComment(PPCInstPrinter::
385                            getRegisterName(MI->getOperand(1).getReg()));
386     TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR);
387     TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
388     OutStreamer.EmitInstruction(TmpInst);
389     return;
390   case PPC::SYNC:
391     // In Book E sync is called msync, handle this special case here...
392     if (Subtarget.isBookE()) {
393       OutStreamer.EmitRawText(StringRef("\tmsync"));
394       return;
395     }
396   }
397
398   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
399   OutStreamer.EmitInstruction(TmpInst);
400 }
401
402 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
403   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
404     return AsmPrinter::EmitFunctionEntryLabel();
405     
406   // Emit an official procedure descriptor.
407   const MCSection *Current = OutStreamer.getCurrentSection();
408   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
409       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
410       SectionKind::getReadOnly());
411   OutStreamer.SwitchSection(Section);
412   OutStreamer.EmitLabel(CurrentFnSym);
413   OutStreamer.EmitValueToAlignment(8);
414   MCSymbol *Symbol1 = 
415     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
416   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.@tocbase"));
417   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
418                         Subtarget.isPPC64() ? 8 : 4/*size*/, 0/*addrspace*/);
419   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, OutContext),
420                         Subtarget.isPPC64() ? 8 : 4/*size*/, 0/*addrspace*/);
421   OutStreamer.SwitchSection(Current);
422
423   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
424                           ".L." + Twine(CurrentFnSym->getName()));
425   OutStreamer.EmitLabel(RealFnSym);
426   CurrentFnSymForSize = RealFnSym;
427 }
428
429
430 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
431   const TargetData *TD = TM.getTargetData();
432
433   bool isPPC64 = TD->getPointerSizeInBits() == 64;
434
435   if (isPPC64 && !TOC.empty()) {
436     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
437         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
438         SectionKind::getReadOnly());
439     OutStreamer.SwitchSection(Section);
440
441     // FIXME: This is nondeterminstic!
442     for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
443          E = TOC.end(); I != E; ++I) {
444       OutStreamer.EmitLabel(I->second);
445       OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
446                               "[TC]," + I->first->getName());
447     }
448   }
449
450   return AsmPrinter::doFinalization(M);
451 }
452
453 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
454   static const char *const CPUDirectives[] = {
455     "",
456     "ppc",
457     "ppc440",
458     "ppc601",
459     "ppc602",
460     "ppc603",
461     "ppc7400",
462     "ppc750",
463     "ppc970",
464     "ppcA2",
465     "ppce500mc",
466     "ppce5500",
467     "power6",
468     "power7",
469     "ppc64"
470   };
471
472   unsigned Directive = Subtarget.getDarwinDirective();
473   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
474     Directive = PPC::DIR_970;
475   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
476     Directive = PPC::DIR_7400;
477   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
478     Directive = PPC::DIR_64;
479   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
480   
481   // FIXME: This is a total hack, finish mc'izing the PPC backend.
482   if (OutStreamer.hasRawTextSupport())
483     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
484
485   // Prime text sections so they are adjacent.  This reduces the likelihood a
486   // large data or debug section causes a branch to exceed 16M limit.
487   const TargetLoweringObjectFileMachO &TLOFMacho = 
488     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
489   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
490   if (TM.getRelocationModel() == Reloc::PIC_) {
491     OutStreamer.SwitchSection(
492            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
493                                       MCSectionMachO::S_SYMBOL_STUBS |
494                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
495                                       32, SectionKind::getText()));
496   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
497     OutStreamer.SwitchSection(
498            OutContext.getMachOSection("__TEXT","__symbol_stub1",
499                                       MCSectionMachO::S_SYMBOL_STUBS |
500                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
501                                       16, SectionKind::getText()));
502   }
503   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
504 }
505
506 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
507   // Remove $stub suffix, add $lazy_ptr.
508   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
509   TmpStr += "$lazy_ptr";
510   return Ctx.GetOrCreateSymbol(TmpStr.str());
511 }
512
513 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
514   // Add $tmp suffix to $stub, yielding $stub$tmp.
515   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
516   TmpStr += "$tmp";
517   return Ctx.GetOrCreateSymbol(TmpStr.str());
518 }
519
520 void PPCDarwinAsmPrinter::
521 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
522   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
523   
524   const TargetLoweringObjectFileMachO &TLOFMacho = 
525     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
526
527   // .lazy_symbol_pointer
528   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
529   
530   // Output stubs for dynamically-linked functions
531   if (TM.getRelocationModel() == Reloc::PIC_) {
532     const MCSection *StubSection = 
533     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
534                                MCSectionMachO::S_SYMBOL_STUBS |
535                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
536                                32, SectionKind::getText());
537     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
538       OutStreamer.SwitchSection(StubSection);
539       EmitAlignment(4);
540       
541       MCSymbol *Stub = Stubs[i].first;
542       MCSymbol *RawSym = Stubs[i].second.getPointer();
543       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
544       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
545                                            
546       OutStreamer.EmitLabel(Stub);
547       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
548       // FIXME: MCize this.
549       OutStreamer.EmitRawText(StringRef("\tmflr r0"));
550       OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
551       OutStreamer.EmitLabel(AnonSymbol);
552       OutStreamer.EmitRawText(StringRef("\tmflr r11"));
553       OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
554                               "-" + AnonSymbol->getName() + ")");
555       OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
556       
557       if (isPPC64)
558         OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
559                                 "-" + AnonSymbol->getName() + ")(r11)");
560       else
561         OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
562                                 "-" + AnonSymbol->getName() + ")(r11)");
563       OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
564       OutStreamer.EmitRawText(StringRef("\tbctr"));
565       
566       OutStreamer.SwitchSection(LSPSection);
567       OutStreamer.EmitLabel(LazyPtr);
568       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
569       
570       if (isPPC64)
571         OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
572       else
573         OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
574     }
575     OutStreamer.AddBlankLine();
576     return;
577   }
578   
579   const MCSection *StubSection =
580     OutContext.getMachOSection("__TEXT","__symbol_stub1",
581                                MCSectionMachO::S_SYMBOL_STUBS |
582                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
583                                16, SectionKind::getText());
584   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
585     MCSymbol *Stub = Stubs[i].first;
586     MCSymbol *RawSym = Stubs[i].second.getPointer();
587     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
588
589     OutStreamer.SwitchSection(StubSection);
590     EmitAlignment(4);
591     OutStreamer.EmitLabel(Stub);
592     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
593     OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
594     if (isPPC64)
595       OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
596                               ")(r11)");
597     else
598       OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
599                               ")(r11)");
600     OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
601     OutStreamer.EmitRawText(StringRef("\tbctr"));
602     OutStreamer.SwitchSection(LSPSection);
603     OutStreamer.EmitLabel(LazyPtr);
604     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
605     
606     if (isPPC64)
607       OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
608     else
609       OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
610   }
611   
612   OutStreamer.AddBlankLine();
613 }
614
615
616 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
617   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
618
619   // Darwin/PPC always uses mach-o.
620   const TargetLoweringObjectFileMachO &TLOFMacho = 
621     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
622   MachineModuleInfoMachO &MMIMacho =
623     MMI->getObjFileInfo<MachineModuleInfoMachO>();
624   
625   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
626   if (!Stubs.empty())
627     EmitFunctionStubs(Stubs);
628
629   if (MAI->doesSupportExceptionHandling() && MMI) {
630     // Add the (possibly multiple) personalities to the set of global values.
631     // Only referenced functions get into the Personalities list.
632     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
633     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
634          E = Personalities.end(); I != E; ++I) {
635       if (*I) {
636         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
637         MachineModuleInfoImpl::StubValueTy &StubSym =
638           MMIMacho.getGVStubEntry(NLPSym);
639         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
640       }
641     }
642   }
643
644   // Output stubs for dynamically-linked functions.
645   Stubs = MMIMacho.GetGVStubList();
646   
647   // Output macho stubs for external and common global variables.
648   if (!Stubs.empty()) {
649     // Switch with ".non_lazy_symbol_pointer" directive.
650     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
651     EmitAlignment(isPPC64 ? 3 : 2);
652     
653     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
654       // L_foo$stub:
655       OutStreamer.EmitLabel(Stubs[i].first);
656       //   .indirect_symbol _foo
657       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
658       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
659
660       if (MCSym.getInt())
661         // External to current translation unit.
662         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
663       else
664         // Internal to current translation unit.
665         //
666         // When we place the LSDA into the TEXT section, the type info pointers
667         // need to be indirect and pc-rel. We accomplish this by using NLPs.
668         // However, sometimes the types are local to the file. So we need to
669         // fill in the value for the NLP in those cases.
670         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
671                                                       OutContext),
672                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
673     }
674
675     Stubs.clear();
676     OutStreamer.AddBlankLine();
677   }
678
679   Stubs = MMIMacho.GetHiddenGVStubList();
680   if (!Stubs.empty()) {
681     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
682     EmitAlignment(isPPC64 ? 3 : 2);
683     
684     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
685       // L_foo$stub:
686       OutStreamer.EmitLabel(Stubs[i].first);
687       //   .long _foo
688       OutStreamer.EmitValue(MCSymbolRefExpr::
689                             Create(Stubs[i].second.getPointer(),
690                                    OutContext),
691                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
692     }
693
694     Stubs.clear();
695     OutStreamer.AddBlankLine();
696   }
697
698   // Funny Darwin hack: This flag tells the linker that no global symbols
699   // contain code that falls through to other global symbols (e.g. the obvious
700   // implementation of multiple entry points).  If this doesn't occur, the
701   // linker can safely perform dead code stripping.  Since LLVM never generates
702   // code that does this, it is always safe to set.
703   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
704
705   return AsmPrinter::doFinalization(M);
706 }
707
708 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
709 /// for a MachineFunction to the given output stream, in a format that the
710 /// Darwin assembler can deal with.
711 ///
712 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
713                                            MCStreamer &Streamer) {
714   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
715
716   if (Subtarget->isDarwin())
717     return new PPCDarwinAsmPrinter(tm, Streamer);
718   return new PPCLinuxAsmPrinter(tm, Streamer);
719 }
720
721 // Force static initialization.
722 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
723   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
724   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
725 }