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