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