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