15d690bd8970a22e5a2f5aa5c17311475ca199b3
[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 using namespace llvm;
59
60 namespace {
61   class PPCAsmPrinter : public AsmPrinter {
62   protected:
63     MapVector<MCSymbol*, MCSymbol*> TOC;
64     const PPCSubtarget &Subtarget;
65     uint64_t TOCLabelID;
66   public:
67     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
68       : AsmPrinter(TM, Streamer),
69         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
70
71     virtual const char *getPassName() const {
72       return "PowerPC Assembly Printer";
73     }
74
75
76     virtual void EmitInstruction(const MachineInstr *MI);
77
78     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
79
80     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
81                          unsigned AsmVariant, const char *ExtraCode,
82                          raw_ostream &O);
83     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
84                                unsigned AsmVariant, const char *ExtraCode,
85                                raw_ostream &O);
86
87     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
88       MachineLocation Location;
89       assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
90       // Frame address.  Currently handles register +- offset only.
91       if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
92         Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
93       else {
94         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
95       }
96       return Location;
97     }
98   };
99
100   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
101   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
102   public:
103     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
104       : PPCAsmPrinter(TM, Streamer) {}
105
106     virtual const char *getPassName() const {
107       return "Linux PPC Assembly Printer";
108     }
109
110     bool doFinalization(Module &M);
111
112     virtual void EmitFunctionEntryLabel();
113
114     void EmitFunctionBodyEnd();
115   };
116
117   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
118   /// OS X
119   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
120   public:
121     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
122       : PPCAsmPrinter(TM, Streamer) {}
123
124     virtual const char *getPassName() const {
125       return "Darwin PPC Assembly Printer";
126     }
127
128     bool doFinalization(Module &M);
129     void EmitStartOfAsmFile(Module &M);
130
131     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
132   };
133 } // end of anonymous namespace
134
135 /// stripRegisterPrefix - This method strips the character prefix from a
136 /// register name so that only the number is left.  Used by for linux asm.
137 static const char *stripRegisterPrefix(const char *RegName) {
138   switch (RegName[0]) {
139     case 'r':
140     case 'f':
141     case 'v': return RegName + 1;
142     case 'c': if (RegName[1] == 'r') return RegName + 2;
143   }
144   
145   return RegName;
146 }
147
148 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
149                                  raw_ostream &O) {
150   const MachineOperand &MO = MI->getOperand(OpNo);
151   
152   switch (MO.getType()) {
153   case MachineOperand::MO_Register: {
154     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
155     // Linux assembler (Others?) does not take register mnemonics.
156     // FIXME - What about special registers used in mfspr/mtspr?
157     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
158     O << RegName;
159     return;
160   }
161   case MachineOperand::MO_Immediate:
162     O << MO.getImm();
163     return;
164
165   case MachineOperand::MO_MachineBasicBlock:
166     O << *MO.getMBB()->getSymbol();
167     return;
168   case MachineOperand::MO_JumpTableIndex:
169     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
170       << '_' << MO.getIndex();
171     // FIXME: PIC relocation model
172     return;
173   case MachineOperand::MO_ConstantPoolIndex:
174     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
175       << '_' << MO.getIndex();
176     return;
177   case MachineOperand::MO_BlockAddress:
178     O << *GetBlockAddressSymbol(MO.getBlockAddress());
179     return;
180   case MachineOperand::MO_ExternalSymbol: {
181     // Computing the address of an external symbol, not calling it.
182     if (TM.getRelocationModel() == Reloc::Static) {
183       O << *GetExternalSymbolSymbol(MO.getSymbolName());
184       return;
185     }
186
187     MCSymbol *NLPSym = 
188       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
189                                    MO.getSymbolName()+"$non_lazy_ptr");
190     MachineModuleInfoImpl::StubValueTy &StubSym = 
191       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
192     if (StubSym.getPointer() == 0)
193       StubSym = MachineModuleInfoImpl::
194         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
195     
196     O << *NLPSym;
197     return;
198   }
199   case MachineOperand::MO_GlobalAddress: {
200     // Computing the address of a global symbol, not calling it.
201     const GlobalValue *GV = MO.getGlobal();
202     MCSymbol *SymToPrint;
203
204     // External or weakly linked global variables need non-lazily-resolved stubs
205     if (TM.getRelocationModel() != Reloc::Static &&
206         (GV->isDeclaration() || GV->isWeakForLinker())) {
207       if (!GV->hasHiddenVisibility()) {
208         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
209         MachineModuleInfoImpl::StubValueTy &StubSym = 
210           MMI->getObjFileInfo<MachineModuleInfoMachO>()
211             .getGVStubEntry(SymToPrint);
212         if (StubSym.getPointer() == 0)
213           StubSym = MachineModuleInfoImpl::
214             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
215       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
216                  GV->hasAvailableExternallyLinkage()) {
217         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
218         
219         MachineModuleInfoImpl::StubValueTy &StubSym = 
220           MMI->getObjFileInfo<MachineModuleInfoMachO>().
221                     getHiddenGVStubEntry(SymToPrint);
222         if (StubSym.getPointer() == 0)
223           StubSym = MachineModuleInfoImpl::
224             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
225       } else {
226         SymToPrint = Mang->getSymbol(GV);
227       }
228     } else {
229       SymToPrint = Mang->getSymbol(GV);
230     }
231     
232     O << *SymToPrint;
233
234     printOffset(MO.getOffset(), O);
235     return;
236   }
237
238   default:
239     O << "<unknown operand type: " << MO.getType() << ">";
240     return;
241   }
242 }
243
244 /// PrintAsmOperand - Print out an operand for an inline asm expression.
245 ///
246 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
247                                     unsigned AsmVariant,
248                                     const char *ExtraCode, raw_ostream &O) {
249   // Does this asm operand have a single letter operand modifier?
250   if (ExtraCode && ExtraCode[0]) {
251     if (ExtraCode[1] != 0) return true; // Unknown modifier.
252
253     switch (ExtraCode[0]) {
254     default:
255       // See if this is a generic print operand
256       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
257     case 'c': // Don't print "$" before a global var name or constant.
258       break; // PPC never has a prefix.
259     case 'L': // Write second word of DImode reference.
260       // Verify that this operand has two consecutive registers.
261       if (!MI->getOperand(OpNo).isReg() ||
262           OpNo+1 == MI->getNumOperands() ||
263           !MI->getOperand(OpNo+1).isReg())
264         return true;
265       ++OpNo;   // Return the high-part.
266       break;
267     case 'I':
268       // Write 'i' if an integer constant, otherwise nothing.  Used to print
269       // addi vs add, etc.
270       if (MI->getOperand(OpNo).isImm())
271         O << "i";
272       return false;
273     }
274   }
275
276   printOperand(MI, OpNo, O);
277   return false;
278 }
279
280 // At the moment, all inline asm memory operands are a single register.
281 // In any case, the output of this routine should always be just one
282 // assembler operand.
283
284 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
285                                           unsigned AsmVariant,
286                                           const char *ExtraCode,
287                                           raw_ostream &O) {
288   if (ExtraCode && ExtraCode[0]) {
289     if (ExtraCode[1] != 0) return true; // Unknown modifier.
290
291     switch (ExtraCode[0]) {
292     default: return true;  // Unknown modifier.
293     case 'y': // A memory reference for an X-form instruction
294       {
295         const char *RegName = "r0";
296         if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
297         O << RegName << ", ";
298         printOperand(MI, OpNo, O);
299         return false;
300       }
301     }
302   }
303
304   assert(MI->getOperand(OpNo).isReg());
305   O << "0(";
306   printOperand(MI, OpNo, O);
307   O << ")";
308   return false;
309 }
310
311
312 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
313 /// the current output stream.
314 ///
315 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
316   MCInst TmpInst;
317   
318   // Lower multi-instruction pseudo operations.
319   switch (MI->getOpcode()) {
320   default: break;
321   case TargetOpcode::DBG_VALUE: {
322     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
323       
324     SmallString<32> Str;
325     raw_svector_ostream O(Str);
326     unsigned NOps = MI->getNumOperands();
327     assert(NOps==4);
328     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
329     // cast away const; DIetc do not take const operands for some reason.
330     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
331     O << V.getName();
332     O << " <- ";
333     // Frame address.  Currently handles register +- offset only.
334     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
335     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
336     O << ']';
337     O << "+";
338     printOperand(MI, NOps-2, O);
339     OutStreamer.EmitRawText(O.str());
340     return;
341   }
342       
343   case PPC::MovePCtoLR:
344   case PPC::MovePCtoLR8: {
345     // Transform %LR = MovePCtoLR
346     // Into this, where the label is the PIC base: 
347     //     bl L1$pb
348     // L1$pb:
349     MCSymbol *PICBase = MF->getPICBaseSymbol();
350     
351     // Emit the 'bl'.
352     TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here.
353     
354     
355     // FIXME: We would like an efficient form for this, so we don't have to do
356     // a lot of extra uniquing.
357     TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
358                                              Create(PICBase, OutContext)));
359     OutStreamer.EmitInstruction(TmpInst);
360     
361     // Emit the label.
362     OutStreamer.EmitLabel(PICBase);
363     return;
364   }
365   case PPC::LDtocJTI:
366   case PPC::LDtocCPT:
367   case PPC::LDtoc: {
368     // Transform %X3 = LDtoc <ga:@min1>, %X2
369     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
370
371     // Change the opcode to LD, and the global address operand to be a
372     // reference to the TOC entry we will synthesize later.
373     TmpInst.setOpcode(PPC::LD);
374     const MachineOperand &MO = MI->getOperand(1);
375
376     // Map symbol -> label of TOC entry
377     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
378     MCSymbol *MOSymbol = 0;
379     if (MO.isGlobal())
380       MOSymbol = Mang->getSymbol(MO.getGlobal());
381     else if (MO.isCPI())
382       MOSymbol = GetCPISymbol(MO.getIndex());
383     else if (MO.isJTI())
384       MOSymbol = GetJTISymbol(MO.getIndex());
385     MCSymbol *&TOCEntry = TOC[MOSymbol];
386     // To avoid name clash check if the name already exists.
387     while (TOCEntry == 0) {
388       if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
389                                   "C" + Twine(TOCLabelID++)) == 0) {
390         TOCEntry = GetTempSymbol("C", TOCLabelID);
391       }
392     }
393
394     const MCExpr *Exp =
395       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
396                               OutContext);
397     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
398     OutStreamer.EmitInstruction(TmpInst);
399     return;
400   }
401       
402   case PPC::MFCRpseud:
403   case PPC::MFCR8pseud:
404     // Transform: %R3 = MFCRpseud %CR7
405     // Into:      %R3 = MFCR      ;; cr7
406     OutStreamer.AddComment(PPCInstPrinter::
407                            getRegisterName(MI->getOperand(1).getReg()));
408     TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR);
409     TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
410     OutStreamer.EmitInstruction(TmpInst);
411     return;
412   case PPC::SYNC:
413     // In Book E sync is called msync, handle this special case here...
414     if (Subtarget.isBookE()) {
415       OutStreamer.EmitRawText(StringRef("\tmsync"));
416       return;
417     }
418   }
419
420   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
421   OutStreamer.EmitInstruction(TmpInst);
422 }
423
424 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
425   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
426     return AsmPrinter::EmitFunctionEntryLabel();
427     
428   // Emit an official procedure descriptor.
429   const MCSection *Current = OutStreamer.getCurrentSection();
430   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
431       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
432       SectionKind::getReadOnly());
433   OutStreamer.SwitchSection(Section);
434   OutStreamer.EmitLabel(CurrentFnSym);
435   OutStreamer.EmitValueToAlignment(8);
436   MCSymbol *Symbol1 = 
437     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
438   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
439   // entry point.
440   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
441                         8/*size*/, 0/*addrspace*/);
442   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
443   // Generates a R_PPC64_TOC relocation for TOC base insertion.
444   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
445                         MCSymbolRefExpr::VK_PPC_TOC, OutContext),
446                         8/*size*/, 0/*addrspace*/);
447   // Emit a null environment pointer.
448   OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */);
449   OutStreamer.SwitchSection(Current);
450
451   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
452                           ".L." + Twine(CurrentFnSym->getName()));
453   OutStreamer.EmitLabel(RealFnSym);
454   CurrentFnSymForSize = RealFnSym;
455 }
456
457
458 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
459   const DataLayout *TD = TM.getDataLayout();
460
461   bool isPPC64 = TD->getPointerSizeInBits() == 64;
462
463   if (isPPC64 && !TOC.empty()) {
464     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
465         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
466         SectionKind::getReadOnly());
467     OutStreamer.SwitchSection(Section);
468
469     for (MapVector<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 }