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