Revert r151278, breaks static linking.
[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   case PPC::MFCR8pseud:
369     // Transform: %R3 = MFCRpseud %CR7
370     // Into:      %R3 = MFCR      ;; cr7
371     OutStreamer.AddComment(PPCInstPrinter::
372                            getRegisterName(MI->getOperand(1).getReg()));
373     TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR);
374     TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
375     OutStreamer.EmitInstruction(TmpInst);
376     return;
377   case PPC::SYNC:
378     // In Book E sync is called msync, handle this special case here...
379     if (Subtarget.isBookE()) {
380       OutStreamer.EmitRawText(StringRef("\tmsync"));
381       return;
382     }
383   }
384
385   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
386   OutStreamer.EmitInstruction(TmpInst);
387 }
388
389 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
390   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
391     return AsmPrinter::EmitFunctionEntryLabel();
392     
393   // Emit an official procedure descriptor.
394   // FIXME 64-bit SVR4: Use MCSection here!
395   OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\""));
396   OutStreamer.EmitRawText(StringRef("\t.align 3"));
397   OutStreamer.EmitLabel(CurrentFnSym);
398   OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) +
399                           ",.TOC.@tocbase");
400   OutStreamer.EmitRawText(StringRef("\t.previous"));
401
402   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
403                           ".L." + Twine(CurrentFnSym->getName()));
404   OutStreamer.EmitLabel(RealFnSym);
405   CurrentFnSymForSize = RealFnSym;
406 }
407
408
409 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
410   const TargetData *TD = TM.getTargetData();
411
412   bool isPPC64 = TD->getPointerSizeInBits() == 64;
413
414   if (isPPC64 && !TOC.empty()) {
415     // FIXME 64-bit SVR4: Use MCSection here?
416     OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\""));
417
418     // FIXME: This is nondeterminstic!
419     for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
420          E = TOC.end(); I != E; ++I) {
421       OutStreamer.EmitLabel(I->second);
422       OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
423                               "[TC]," + I->first->getName());
424     }
425   }
426
427   return AsmPrinter::doFinalization(M);
428 }
429
430 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
431   static const char *const CPUDirectives[] = {
432     "",
433     "ppc",
434     "ppc440",
435     "ppc601",
436     "ppc602",
437     "ppc603",
438     "ppc7400",
439     "ppc750",
440     "ppc970",
441     "ppc64"
442   };
443
444   unsigned Directive = Subtarget.getDarwinDirective();
445   if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970)
446     Directive = PPC::DIR_970;
447   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
448     Directive = PPC::DIR_7400;
449   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
450     Directive = PPC::DIR_64;
451   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
452   
453   // FIXME: This is a total hack, finish mc'izing the PPC backend.
454   if (OutStreamer.hasRawTextSupport())
455     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
456
457   // Prime text sections so they are adjacent.  This reduces the likelihood a
458   // large data or debug section causes a branch to exceed 16M limit.
459   const TargetLoweringObjectFileMachO &TLOFMacho = 
460     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
461   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
462   if (TM.getRelocationModel() == Reloc::PIC_) {
463     OutStreamer.SwitchSection(
464            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
465                                       MCSectionMachO::S_SYMBOL_STUBS |
466                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
467                                       32, SectionKind::getText()));
468   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
469     OutStreamer.SwitchSection(
470            OutContext.getMachOSection("__TEXT","__symbol_stub1",
471                                       MCSectionMachO::S_SYMBOL_STUBS |
472                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
473                                       16, SectionKind::getText()));
474   }
475   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
476 }
477
478 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
479   // Remove $stub suffix, add $lazy_ptr.
480   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
481   TmpStr += "$lazy_ptr";
482   return Ctx.GetOrCreateSymbol(TmpStr.str());
483 }
484
485 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
486   // Add $tmp suffix to $stub, yielding $stub$tmp.
487   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
488   TmpStr += "$tmp";
489   return Ctx.GetOrCreateSymbol(TmpStr.str());
490 }
491
492 void PPCDarwinAsmPrinter::
493 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
494   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
495   
496   const TargetLoweringObjectFileMachO &TLOFMacho = 
497     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
498
499   // .lazy_symbol_pointer
500   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
501   
502   // Output stubs for dynamically-linked functions
503   if (TM.getRelocationModel() == Reloc::PIC_) {
504     const MCSection *StubSection = 
505     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
506                                MCSectionMachO::S_SYMBOL_STUBS |
507                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
508                                32, SectionKind::getText());
509     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
510       OutStreamer.SwitchSection(StubSection);
511       EmitAlignment(4);
512       
513       MCSymbol *Stub = Stubs[i].first;
514       MCSymbol *RawSym = Stubs[i].second.getPointer();
515       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
516       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
517                                            
518       OutStreamer.EmitLabel(Stub);
519       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
520       // FIXME: MCize this.
521       OutStreamer.EmitRawText(StringRef("\tmflr r0"));
522       OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
523       OutStreamer.EmitLabel(AnonSymbol);
524       OutStreamer.EmitRawText(StringRef("\tmflr r11"));
525       OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
526                               "-" + AnonSymbol->getName() + ")");
527       OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
528       
529       if (isPPC64)
530         OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
531                                 "-" + AnonSymbol->getName() + ")(r11)");
532       else
533         OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
534                                 "-" + AnonSymbol->getName() + ")(r11)");
535       OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
536       OutStreamer.EmitRawText(StringRef("\tbctr"));
537       
538       OutStreamer.SwitchSection(LSPSection);
539       OutStreamer.EmitLabel(LazyPtr);
540       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
541       
542       if (isPPC64)
543         OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
544       else
545         OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
546     }
547     OutStreamer.AddBlankLine();
548     return;
549   }
550   
551   const MCSection *StubSection =
552     OutContext.getMachOSection("__TEXT","__symbol_stub1",
553                                MCSectionMachO::S_SYMBOL_STUBS |
554                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
555                                16, SectionKind::getText());
556   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
557     MCSymbol *Stub = Stubs[i].first;
558     MCSymbol *RawSym = Stubs[i].second.getPointer();
559     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
560
561     OutStreamer.SwitchSection(StubSection);
562     EmitAlignment(4);
563     OutStreamer.EmitLabel(Stub);
564     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
565     OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
566     if (isPPC64)
567       OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
568                               ")(r11)");
569     else
570       OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
571                               ")(r11)");
572     OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
573     OutStreamer.EmitRawText(StringRef("\tbctr"));
574     OutStreamer.SwitchSection(LSPSection);
575     OutStreamer.EmitLabel(LazyPtr);
576     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
577     
578     if (isPPC64)
579       OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
580     else
581       OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
582   }
583   
584   OutStreamer.AddBlankLine();
585 }
586
587
588 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
589   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
590
591   // Darwin/PPC always uses mach-o.
592   const TargetLoweringObjectFileMachO &TLOFMacho = 
593     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
594   MachineModuleInfoMachO &MMIMacho =
595     MMI->getObjFileInfo<MachineModuleInfoMachO>();
596   
597   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
598   if (!Stubs.empty())
599     EmitFunctionStubs(Stubs);
600
601   if (MAI->doesSupportExceptionHandling() && MMI) {
602     // Add the (possibly multiple) personalities to the set of global values.
603     // Only referenced functions get into the Personalities list.
604     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
605     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
606          E = Personalities.end(); I != E; ++I) {
607       if (*I) {
608         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
609         MachineModuleInfoImpl::StubValueTy &StubSym =
610           MMIMacho.getGVStubEntry(NLPSym);
611         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
612       }
613     }
614   }
615
616   // Output stubs for dynamically-linked functions.
617   Stubs = MMIMacho.GetGVStubList();
618   
619   // Output macho stubs for external and common global variables.
620   if (!Stubs.empty()) {
621     // Switch with ".non_lazy_symbol_pointer" directive.
622     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
623     EmitAlignment(isPPC64 ? 3 : 2);
624     
625     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
626       // L_foo$stub:
627       OutStreamer.EmitLabel(Stubs[i].first);
628       //   .indirect_symbol _foo
629       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
630       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
631
632       if (MCSym.getInt())
633         // External to current translation unit.
634         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
635       else
636         // Internal to current translation unit.
637         //
638         // When we place the LSDA into the TEXT section, the type info pointers
639         // need to be indirect and pc-rel. We accomplish this by using NLPs.
640         // However, sometimes the types are local to the file. So we need to
641         // fill in the value for the NLP in those cases.
642         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
643                                                       OutContext),
644                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
645     }
646
647     Stubs.clear();
648     OutStreamer.AddBlankLine();
649   }
650
651   Stubs = MMIMacho.GetHiddenGVStubList();
652   if (!Stubs.empty()) {
653     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
654     EmitAlignment(isPPC64 ? 3 : 2);
655     
656     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
657       // L_foo$stub:
658       OutStreamer.EmitLabel(Stubs[i].first);
659       //   .long _foo
660       OutStreamer.EmitValue(MCSymbolRefExpr::
661                             Create(Stubs[i].second.getPointer(),
662                                    OutContext),
663                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
664     }
665
666     Stubs.clear();
667     OutStreamer.AddBlankLine();
668   }
669
670   // Funny Darwin hack: This flag tells the linker that no global symbols
671   // contain code that falls through to other global symbols (e.g. the obvious
672   // implementation of multiple entry points).  If this doesn't occur, the
673   // linker can safely perform dead code stripping.  Since LLVM never generates
674   // code that does this, it is always safe to set.
675   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
676
677   return AsmPrinter::doFinalization(M);
678 }
679
680 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
681 /// for a MachineFunction to the given output stream, in a format that the
682 /// Darwin assembler can deal with.
683 ///
684 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
685                                            MCStreamer &Streamer) {
686   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
687
688   if (Subtarget->isDarwin())
689     return new PPCDarwinAsmPrinter(tm, Streamer);
690   return new PPCLinuxAsmPrinter(tm, Streamer);
691 }
692
693 // Force static initialization.
694 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
695   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
696   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
697 }