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