PPC: MCize most of the darwin PIC emission.
[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 #include "llvm/ADT/MapVector.h"
58 #include "llvm/ADT/VariadicFunction.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     TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here.
354     
355     
356     // FIXME: We would like an efficient form for this, so we don't have to do
357     // a lot of extra uniquing.
358     TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
359                                              Create(PICBase, OutContext)));
360     OutStreamer.EmitInstruction(TmpInst);
361     
362     // Emit the label.
363     OutStreamer.EmitLabel(PICBase);
364     return;
365   }
366   case PPC::LDtocJTI:
367   case PPC::LDtocCPT:
368   case PPC::LDtoc: {
369     // Transform %X3 = LDtoc <ga:@min1>, %X2
370     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
371
372     // Change the opcode to LD, and the global address operand to be a
373     // reference to the TOC entry we will synthesize later.
374     TmpInst.setOpcode(PPC::LD);
375     const MachineOperand &MO = MI->getOperand(1);
376
377     // Map symbol -> label of TOC entry
378     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
379     MCSymbol *MOSymbol = 0;
380     if (MO.isGlobal())
381       MOSymbol = Mang->getSymbol(MO.getGlobal());
382     else if (MO.isCPI())
383       MOSymbol = GetCPISymbol(MO.getIndex());
384     else if (MO.isJTI())
385       MOSymbol = GetJTISymbol(MO.getIndex());
386     MCSymbol *&TOCEntry = TOC[MOSymbol];
387     // To avoid name clash check if the name already exists.
388     while (TOCEntry == 0) {
389       if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
390                                   "C" + Twine(TOCLabelID++)) == 0) {
391         TOCEntry = GetTempSymbol("C", TOCLabelID);
392       }
393     }
394
395     const MCExpr *Exp =
396       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
397                               OutContext);
398     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
399     OutStreamer.EmitInstruction(TmpInst);
400     return;
401   }
402       
403   case PPC::MFCRpseud:
404   case PPC::MFCR8pseud:
405     // Transform: %R3 = MFCRpseud %CR7
406     // Into:      %R3 = MFCR      ;; cr7
407     OutStreamer.AddComment(PPCInstPrinter::
408                            getRegisterName(MI->getOperand(1).getReg()));
409     TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR);
410     TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
411     OutStreamer.EmitInstruction(TmpInst);
412     return;
413   case PPC::SYNC:
414     // In Book E sync is called msync, handle this special case here...
415     if (Subtarget.isBookE()) {
416       OutStreamer.EmitRawText(StringRef("\tmsync"));
417       return;
418     }
419   }
420
421   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
422   OutStreamer.EmitInstruction(TmpInst);
423 }
424
425 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
426   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
427     return AsmPrinter::EmitFunctionEntryLabel();
428     
429   // Emit an official procedure descriptor.
430   const MCSection *Current = OutStreamer.getCurrentSection();
431   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
432       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
433       SectionKind::getReadOnly());
434   OutStreamer.SwitchSection(Section);
435   OutStreamer.EmitLabel(CurrentFnSym);
436   OutStreamer.EmitValueToAlignment(8);
437   MCSymbol *Symbol1 = 
438     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
439   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
440   // entry point.
441   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
442                         8/*size*/, 0/*addrspace*/);
443   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
444   // Generates a R_PPC64_TOC relocation for TOC base insertion.
445   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
446                         MCSymbolRefExpr::VK_PPC_TOC, OutContext),
447                         8/*size*/, 0/*addrspace*/);
448   // Emit a null environment pointer.
449   OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */);
450   OutStreamer.SwitchSection(Current);
451
452   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
453                           ".L." + Twine(CurrentFnSym->getName()));
454   OutStreamer.EmitLabel(RealFnSym);
455   CurrentFnSymForSize = RealFnSym;
456 }
457
458
459 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
460   const DataLayout *TD = TM.getDataLayout();
461
462   bool isPPC64 = TD->getPointerSizeInBits() == 64;
463
464   if (isPPC64 && !TOC.empty()) {
465     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
466         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
467         SectionKind::getReadOnly());
468     OutStreamer.SwitchSection(Section);
469
470     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
471          E = TOC.end(); I != E; ++I) {
472       OutStreamer.EmitLabel(I->second);
473       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
474       OutStreamer.EmitTCEntry(*S);
475     }
476   }
477
478   return AsmPrinter::doFinalization(M);
479 }
480
481 /// EmitFunctionBodyEnd - Print the traceback table before the .size
482 /// directive.
483 ///
484 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
485   // Only the 64-bit target requires a traceback table.  For now,
486   // we only emit the word of zeroes that GDB requires to find
487   // the end of the function, and zeroes for the eight-byte
488   // mandatory fields.
489   // FIXME: We should fill in the eight-byte mandatory fields as described in
490   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
491   // currently make use of these fields).
492   if (Subtarget.isPPC64()) {
493     OutStreamer.EmitIntValue(0, 4/*size*/);
494     OutStreamer.EmitIntValue(0, 8/*size*/);
495   }
496 }
497
498 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
499   static const char *const CPUDirectives[] = {
500     "",
501     "ppc",
502     "ppc440",
503     "ppc601",
504     "ppc602",
505     "ppc603",
506     "ppc7400",
507     "ppc750",
508     "ppc970",
509     "ppcA2",
510     "ppce500mc",
511     "ppce5500",
512     "power6",
513     "power7",
514     "ppc64"
515   };
516
517   unsigned Directive = Subtarget.getDarwinDirective();
518   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
519     Directive = PPC::DIR_970;
520   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
521     Directive = PPC::DIR_7400;
522   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
523     Directive = PPC::DIR_64;
524   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
525   
526   // FIXME: This is a total hack, finish mc'izing the PPC backend.
527   if (OutStreamer.hasRawTextSupport())
528     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
529
530   // Prime text sections so they are adjacent.  This reduces the likelihood a
531   // large data or debug section causes a branch to exceed 16M limit.
532   const TargetLoweringObjectFileMachO &TLOFMacho = 
533     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
534   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
535   if (TM.getRelocationModel() == Reloc::PIC_) {
536     OutStreamer.SwitchSection(
537            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
538                                       MCSectionMachO::S_SYMBOL_STUBS |
539                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
540                                       32, SectionKind::getText()));
541   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
542     OutStreamer.SwitchSection(
543            OutContext.getMachOSection("__TEXT","__symbol_stub1",
544                                       MCSectionMachO::S_SYMBOL_STUBS |
545                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
546                                       16, SectionKind::getText()));
547   }
548   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
549 }
550
551 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
552   // Remove $stub suffix, add $lazy_ptr.
553   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
554   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
555 }
556
557 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
558   // Add $tmp suffix to $stub, yielding $stub$tmp.
559   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
560 }
561
562 namespace {
563   // Helper function to emit a custom MCInst.
564   void emitMCInstImpl(MCStreamer &OutStreamer, unsigned Opcode,
565                       ArrayRef<const MCOperand *> Ops) {
566     MCInst TmpInst;
567     TmpInst.setOpcode(Opcode);
568     for (unsigned I = 0, E = Ops.size(); I != E; ++I)
569       TmpInst.addOperand(*Ops[I]);
570     OutStreamer.EmitInstruction(TmpInst);
571   }
572
573   const VariadicFunction2<void, MCStreamer &, unsigned, MCOperand,
574                           emitMCInstImpl> emitMCInst = {};
575 }
576
577 void PPCDarwinAsmPrinter::
578 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
579   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
580   
581   const TargetLoweringObjectFileMachO &TLOFMacho = 
582     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
583
584   // .lazy_symbol_pointer
585   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
586   
587   // Output stubs for dynamically-linked functions
588   if (TM.getRelocationModel() == Reloc::PIC_) {
589     const MCSection *StubSection = 
590     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
591                                MCSectionMachO::S_SYMBOL_STUBS |
592                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
593                                32, SectionKind::getText());
594     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
595       OutStreamer.SwitchSection(StubSection);
596       EmitAlignment(4);
597       
598       MCSymbol *Stub = Stubs[i].first;
599       MCSymbol *RawSym = Stubs[i].second.getPointer();
600       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
601       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
602                                            
603       OutStreamer.EmitLabel(Stub);
604       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
605
606       // mflr r0
607       emitMCInst(OutStreamer, PPC::MFLR, MCOperand::CreateReg(PPC::R0));
608       // FIXME: MCize this.
609       OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
610       OutStreamer.EmitLabel(AnonSymbol);
611       // mflr r11
612       emitMCInst(OutStreamer, PPC::MFLR, MCOperand::CreateReg(PPC::R11));
613       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
614       MCOperand Sub = MCOperand::CreateExpr(
615                         MCBinaryExpr::CreateSub(
616                           MCSymbolRefExpr::Create(LazyPtr, OutContext),
617                           MCSymbolRefExpr::Create(AnonSymbol, OutContext),
618                         OutContext));
619       emitMCInst(OutStreamer, PPC::ADDIS, MCOperand::CreateReg(PPC::R11),
620                  MCOperand::CreateReg(PPC::R11), Sub);
621       // mtlr r0
622       emitMCInst(OutStreamer, PPC::MTLR, MCOperand::CreateReg(PPC::R0));
623
624       if (isPPC64) {
625         // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
626         emitMCInst(OutStreamer, PPC::LDU, MCOperand::CreateReg(PPC::R12),
627                    Sub, Sub, MCOperand::CreateReg(PPC::R11));
628       } else {
629         // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
630         emitMCInst(OutStreamer, PPC::LWZU, MCOperand::CreateReg(PPC::R12),
631                    Sub, Sub, MCOperand::CreateReg(PPC::R11));
632       }
633       // mtctr r12
634       emitMCInst(OutStreamer, PPC::MTCTR, MCOperand::CreateReg(PPC::R12));
635       // bctr
636       emitMCInst(OutStreamer, PPC::BCTR);
637
638       OutStreamer.SwitchSection(LSPSection);
639       OutStreamer.EmitLabel(LazyPtr);
640       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
641
642       MCSymbol *DyldStubBindingHelper =
643         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
644       if (isPPC64) {
645         // .quad dyld_stub_binding_helper
646         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
647       } else {
648         // .long dyld_stub_binding_helper
649         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
650       }
651     }
652     OutStreamer.AddBlankLine();
653     return;
654   }
655   
656   const MCSection *StubSection =
657     OutContext.getMachOSection("__TEXT","__symbol_stub1",
658                                MCSectionMachO::S_SYMBOL_STUBS |
659                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
660                                16, SectionKind::getText());
661   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
662     MCSymbol *Stub = Stubs[i].first;
663     MCSymbol *RawSym = Stubs[i].second.getPointer();
664     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
665
666     OutStreamer.SwitchSection(StubSection);
667     EmitAlignment(4);
668     OutStreamer.EmitLabel(Stub);
669     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
670     // lis r11, ha16(LazyPtr)
671     MCOperand LazyPtrHa16 =
672       MCOperand::CreateExpr(
673         MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
674                                 OutContext));
675     emitMCInst(OutStreamer, PPC::LIS, MCOperand::CreateReg(PPC::R11),
676                LazyPtrHa16);
677
678     MCOperand LazyPtrLo16 =
679       MCOperand::CreateExpr(
680         MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
681                                 OutContext));
682     if (isPPC64) {
683       // ldu r12, lo16(LazyPtr)(r11)
684       emitMCInst(OutStreamer, PPC::LDU, MCOperand::CreateReg(PPC::R12),
685                  LazyPtrLo16, LazyPtrLo16, MCOperand::CreateReg(PPC::R11));
686     } else {
687       // lwzu r12, lo16(LazyPtr)(r11)
688       emitMCInst(OutStreamer, PPC::LWZU, MCOperand::CreateReg(PPC::R12),
689                  LazyPtrLo16, LazyPtrLo16, MCOperand::CreateReg(PPC::R11));
690     }
691     // mtctr r12
692     emitMCInst(OutStreamer, PPC::MTCTR, MCOperand::CreateReg(PPC::R12));
693     // bctr
694     emitMCInst(OutStreamer, PPC::BCTR);
695     OutStreamer.SwitchSection(LSPSection);
696     OutStreamer.EmitLabel(LazyPtr);
697     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
698
699     MCSymbol *DyldStubBindingHelper =
700       OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
701     if (isPPC64) {
702       // .quad dyld_stub_binding_helper
703       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
704     } else {
705       // .long dyld_stub_binding_helper
706       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
707     }
708   }
709   
710   OutStreamer.AddBlankLine();
711 }
712
713
714 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
715   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
716
717   // Darwin/PPC always uses mach-o.
718   const TargetLoweringObjectFileMachO &TLOFMacho = 
719     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
720   MachineModuleInfoMachO &MMIMacho =
721     MMI->getObjFileInfo<MachineModuleInfoMachO>();
722   
723   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
724   if (!Stubs.empty())
725     EmitFunctionStubs(Stubs);
726
727   if (MAI->doesSupportExceptionHandling() && MMI) {
728     // Add the (possibly multiple) personalities to the set of global values.
729     // Only referenced functions get into the Personalities list.
730     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
731     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
732          E = Personalities.end(); I != E; ++I) {
733       if (*I) {
734         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
735         MachineModuleInfoImpl::StubValueTy &StubSym =
736           MMIMacho.getGVStubEntry(NLPSym);
737         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
738       }
739     }
740   }
741
742   // Output stubs for dynamically-linked functions.
743   Stubs = MMIMacho.GetGVStubList();
744   
745   // Output macho stubs for external and common global variables.
746   if (!Stubs.empty()) {
747     // Switch with ".non_lazy_symbol_pointer" directive.
748     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
749     EmitAlignment(isPPC64 ? 3 : 2);
750     
751     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
752       // L_foo$stub:
753       OutStreamer.EmitLabel(Stubs[i].first);
754       //   .indirect_symbol _foo
755       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
756       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
757
758       if (MCSym.getInt())
759         // External to current translation unit.
760         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
761       else
762         // Internal to current translation unit.
763         //
764         // When we place the LSDA into the TEXT section, the type info pointers
765         // need to be indirect and pc-rel. We accomplish this by using NLPs.
766         // However, sometimes the types are local to the file. So we need to
767         // fill in the value for the NLP in those cases.
768         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
769                                                       OutContext),
770                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
771     }
772
773     Stubs.clear();
774     OutStreamer.AddBlankLine();
775   }
776
777   Stubs = MMIMacho.GetHiddenGVStubList();
778   if (!Stubs.empty()) {
779     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
780     EmitAlignment(isPPC64 ? 3 : 2);
781     
782     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
783       // L_foo$stub:
784       OutStreamer.EmitLabel(Stubs[i].first);
785       //   .long _foo
786       OutStreamer.EmitValue(MCSymbolRefExpr::
787                             Create(Stubs[i].second.getPointer(),
788                                    OutContext),
789                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
790     }
791
792     Stubs.clear();
793     OutStreamer.AddBlankLine();
794   }
795
796   // Funny Darwin hack: This flag tells the linker that no global symbols
797   // contain code that falls through to other global symbols (e.g. the obvious
798   // implementation of multiple entry points).  If this doesn't occur, the
799   // linker can safely perform dead code stripping.  Since LLVM never generates
800   // code that does this, it is always safe to set.
801   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
802
803   return AsmPrinter::doFinalization(M);
804 }
805
806 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
807 /// for a MachineFunction to the given output stream, in a format that the
808 /// Darwin assembler can deal with.
809 ///
810 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
811                                            MCStreamer &Streamer) {
812   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
813
814   if (Subtarget->isDarwin())
815     return new PPCDarwinAsmPrinter(tm, Streamer);
816   return new PPCLinuxAsmPrinter(tm, Streamer);
817 }
818
819 // Force static initialization.
820 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
821   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
822   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
823 }