On PPC64 emit the environment pointer. Patch by Adhemerval Zanella.
[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     return true; // Unknown modifier.
289   assert(MI->getOperand(OpNo).isReg());
290   O << "0(";
291   printOperand(MI, OpNo, O);
292   O << ")";
293   return false;
294 }
295
296
297 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
298 /// the current output stream.
299 ///
300 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
301   MCInst TmpInst;
302   
303   // Lower multi-instruction pseudo operations.
304   switch (MI->getOpcode()) {
305   default: break;
306   case TargetOpcode::DBG_VALUE: {
307     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
308       
309     SmallString<32> Str;
310     raw_svector_ostream O(Str);
311     unsigned NOps = MI->getNumOperands();
312     assert(NOps==4);
313     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
314     // cast away const; DIetc do not take const operands for some reason.
315     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
316     O << V.getName();
317     O << " <- ";
318     // Frame address.  Currently handles register +- offset only.
319     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
320     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
321     O << ']';
322     O << "+";
323     printOperand(MI, NOps-2, O);
324     OutStreamer.EmitRawText(O.str());
325     return;
326   }
327       
328   case PPC::MovePCtoLR:
329   case PPC::MovePCtoLR8: {
330     // Transform %LR = MovePCtoLR
331     // Into this, where the label is the PIC base: 
332     //     bl L1$pb
333     // L1$pb:
334     MCSymbol *PICBase = MF->getPICBaseSymbol();
335     
336     // Emit the 'bl'.
337     TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here.
338     
339     
340     // FIXME: We would like an efficient form for this, so we don't have to do
341     // a lot of extra uniquing.
342     TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::
343                                              Create(PICBase, OutContext)));
344     OutStreamer.EmitInstruction(TmpInst);
345     
346     // Emit the label.
347     OutStreamer.EmitLabel(PICBase);
348     return;
349   }
350   case PPC::LDtocJTI:
351   case PPC::LDtocCPT:
352   case PPC::LDtoc: {
353     // Transform %X3 = LDtoc <ga:@min1>, %X2
354     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
355
356     // Change the opcode to LD, and the global address operand to be a
357     // reference to the TOC entry we will synthesize later.
358     TmpInst.setOpcode(PPC::LD);
359     const MachineOperand &MO = MI->getOperand(1);
360
361     // Map symbol -> label of TOC entry
362     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
363     MCSymbol *MOSymbol = 0;
364     if (MO.isGlobal())
365       MOSymbol = Mang->getSymbol(MO.getGlobal());
366     else if (MO.isCPI())
367       MOSymbol = GetCPISymbol(MO.getIndex());
368     else if (MO.isJTI())
369       MOSymbol = GetJTISymbol(MO.getIndex());
370     MCSymbol *&TOCEntry = TOC[MOSymbol];
371     if (TOCEntry == 0)
372       TOCEntry = GetTempSymbol("C", TOCLabelID++);
373     
374     const MCExpr *Exp =
375       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
376                               OutContext);
377     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
378     OutStreamer.EmitInstruction(TmpInst);
379     return;
380   }
381       
382   case PPC::MFCRpseud:
383   case PPC::MFCR8pseud:
384     // Transform: %R3 = MFCRpseud %CR7
385     // Into:      %R3 = MFCR      ;; cr7
386     OutStreamer.AddComment(PPCInstPrinter::
387                            getRegisterName(MI->getOperand(1).getReg()));
388     TmpInst.setOpcode(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR);
389     TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
390     OutStreamer.EmitInstruction(TmpInst);
391     return;
392   case PPC::SYNC:
393     // In Book E sync is called msync, handle this special case here...
394     if (Subtarget.isBookE()) {
395       OutStreamer.EmitRawText(StringRef("\tmsync"));
396       return;
397     }
398   }
399
400   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
401   OutStreamer.EmitInstruction(TmpInst);
402 }
403
404 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
405   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
406     return AsmPrinter::EmitFunctionEntryLabel();
407     
408   // Emit an official procedure descriptor.
409   const MCSection *Current = OutStreamer.getCurrentSection();
410   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
411       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
412       SectionKind::getReadOnly());
413   OutStreamer.SwitchSection(Section);
414   OutStreamer.EmitLabel(CurrentFnSym);
415   OutStreamer.EmitValueToAlignment(8);
416   MCSymbol *Symbol1 = 
417     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
418   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.@tocbase"));
419   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
420                         8/*size*/, 0/*addrspace*/);
421   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, OutContext),
422                         8/*size*/, 0/*addrspace*/);
423   // Emit a null environment pointer.
424   OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */);
425   OutStreamer.SwitchSection(Current);
426
427   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
428                           ".L." + Twine(CurrentFnSym->getName()));
429   OutStreamer.EmitLabel(RealFnSym);
430   CurrentFnSymForSize = RealFnSym;
431 }
432
433
434 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
435   const TargetData *TD = TM.getTargetData();
436
437   bool isPPC64 = TD->getPointerSizeInBits() == 64;
438
439   if (isPPC64 && !TOC.empty()) {
440     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
441         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
442         SectionKind::getReadOnly());
443     OutStreamer.SwitchSection(Section);
444
445     // FIXME: This is nondeterminstic!
446     for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
447          E = TOC.end(); I != E; ++I) {
448       OutStreamer.EmitLabel(I->second);
449       OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) +
450                               "[TC]," + I->first->getName());
451     }
452   }
453
454   return AsmPrinter::doFinalization(M);
455 }
456
457 /// EmitFunctionBodyEnd - Print the traceback table before the .size
458 /// directive.
459 ///
460 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
461   // Only the 64-bit target requires a traceback table.  For now,
462   // we only emit the word of zeroes that GDB requires to find
463   // the end of the function, and zeroes for the eight-byte
464   // mandatory fields.
465   // FIXME: We should fill in the eight-byte mandatory fields as described in
466   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
467   // currently make use of these fields).
468   if (Subtarget.isPPC64()) {
469     OutStreamer.EmitIntValue(0, 4/*size*/);
470     OutStreamer.EmitIntValue(0, 8/*size*/);
471   }
472 }
473
474 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
475   static const char *const CPUDirectives[] = {
476     "",
477     "ppc",
478     "ppc440",
479     "ppc601",
480     "ppc602",
481     "ppc603",
482     "ppc7400",
483     "ppc750",
484     "ppc970",
485     "ppcA2",
486     "ppce500mc",
487     "ppce5500",
488     "power6",
489     "power7",
490     "ppc64"
491   };
492
493   unsigned Directive = Subtarget.getDarwinDirective();
494   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
495     Directive = PPC::DIR_970;
496   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
497     Directive = PPC::DIR_7400;
498   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
499     Directive = PPC::DIR_64;
500   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
501   
502   // FIXME: This is a total hack, finish mc'izing the PPC backend.
503   if (OutStreamer.hasRawTextSupport())
504     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
505
506   // Prime text sections so they are adjacent.  This reduces the likelihood a
507   // large data or debug section causes a branch to exceed 16M limit.
508   const TargetLoweringObjectFileMachO &TLOFMacho = 
509     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
510   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
511   if (TM.getRelocationModel() == Reloc::PIC_) {
512     OutStreamer.SwitchSection(
513            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
514                                       MCSectionMachO::S_SYMBOL_STUBS |
515                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
516                                       32, SectionKind::getText()));
517   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
518     OutStreamer.SwitchSection(
519            OutContext.getMachOSection("__TEXT","__symbol_stub1",
520                                       MCSectionMachO::S_SYMBOL_STUBS |
521                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
522                                       16, SectionKind::getText()));
523   }
524   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
525 }
526
527 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
528   // Remove $stub suffix, add $lazy_ptr.
529   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5);
530   TmpStr += "$lazy_ptr";
531   return Ctx.GetOrCreateSymbol(TmpStr.str());
532 }
533
534 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
535   // Add $tmp suffix to $stub, yielding $stub$tmp.
536   SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end());
537   TmpStr += "$tmp";
538   return Ctx.GetOrCreateSymbol(TmpStr.str());
539 }
540
541 void PPCDarwinAsmPrinter::
542 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
543   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
544   
545   const TargetLoweringObjectFileMachO &TLOFMacho = 
546     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
547
548   // .lazy_symbol_pointer
549   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
550   
551   // Output stubs for dynamically-linked functions
552   if (TM.getRelocationModel() == Reloc::PIC_) {
553     const MCSection *StubSection = 
554     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
555                                MCSectionMachO::S_SYMBOL_STUBS |
556                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
557                                32, SectionKind::getText());
558     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
559       OutStreamer.SwitchSection(StubSection);
560       EmitAlignment(4);
561       
562       MCSymbol *Stub = Stubs[i].first;
563       MCSymbol *RawSym = Stubs[i].second.getPointer();
564       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
565       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
566                                            
567       OutStreamer.EmitLabel(Stub);
568       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
569       // FIXME: MCize this.
570       OutStreamer.EmitRawText(StringRef("\tmflr r0"));
571       OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
572       OutStreamer.EmitLabel(AnonSymbol);
573       OutStreamer.EmitRawText(StringRef("\tmflr r11"));
574       OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
575                               "-" + AnonSymbol->getName() + ")");
576       OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
577       
578       if (isPPC64)
579         OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
580                                 "-" + AnonSymbol->getName() + ")(r11)");
581       else
582         OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
583                                 "-" + AnonSymbol->getName() + ")(r11)");
584       OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
585       OutStreamer.EmitRawText(StringRef("\tbctr"));
586       
587       OutStreamer.SwitchSection(LSPSection);
588       OutStreamer.EmitLabel(LazyPtr);
589       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
590       
591       if (isPPC64)
592         OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
593       else
594         OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
595     }
596     OutStreamer.AddBlankLine();
597     return;
598   }
599   
600   const MCSection *StubSection =
601     OutContext.getMachOSection("__TEXT","__symbol_stub1",
602                                MCSectionMachO::S_SYMBOL_STUBS |
603                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
604                                16, SectionKind::getText());
605   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
606     MCSymbol *Stub = Stubs[i].first;
607     MCSymbol *RawSym = Stubs[i].second.getPointer();
608     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
609
610     OutStreamer.SwitchSection(StubSection);
611     EmitAlignment(4);
612     OutStreamer.EmitLabel(Stub);
613     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
614     OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
615     if (isPPC64)
616       OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
617                               ")(r11)");
618     else
619       OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
620                               ")(r11)");
621     OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
622     OutStreamer.EmitRawText(StringRef("\tbctr"));
623     OutStreamer.SwitchSection(LSPSection);
624     OutStreamer.EmitLabel(LazyPtr);
625     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
626     
627     if (isPPC64)
628       OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
629     else
630       OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
631   }
632   
633   OutStreamer.AddBlankLine();
634 }
635
636
637 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
638   bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64;
639
640   // Darwin/PPC always uses mach-o.
641   const TargetLoweringObjectFileMachO &TLOFMacho = 
642     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
643   MachineModuleInfoMachO &MMIMacho =
644     MMI->getObjFileInfo<MachineModuleInfoMachO>();
645   
646   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
647   if (!Stubs.empty())
648     EmitFunctionStubs(Stubs);
649
650   if (MAI->doesSupportExceptionHandling() && MMI) {
651     // Add the (possibly multiple) personalities to the set of global values.
652     // Only referenced functions get into the Personalities list.
653     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
654     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
655          E = Personalities.end(); I != E; ++I) {
656       if (*I) {
657         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
658         MachineModuleInfoImpl::StubValueTy &StubSym =
659           MMIMacho.getGVStubEntry(NLPSym);
660         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
661       }
662     }
663   }
664
665   // Output stubs for dynamically-linked functions.
666   Stubs = MMIMacho.GetGVStubList();
667   
668   // Output macho stubs for external and common global variables.
669   if (!Stubs.empty()) {
670     // Switch with ".non_lazy_symbol_pointer" directive.
671     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
672     EmitAlignment(isPPC64 ? 3 : 2);
673     
674     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
675       // L_foo$stub:
676       OutStreamer.EmitLabel(Stubs[i].first);
677       //   .indirect_symbol _foo
678       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
679       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
680
681       if (MCSym.getInt())
682         // External to current translation unit.
683         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
684       else
685         // Internal to current translation unit.
686         //
687         // When we place the LSDA into the TEXT section, the type info pointers
688         // need to be indirect and pc-rel. We accomplish this by using NLPs.
689         // However, sometimes the types are local to the file. So we need to
690         // fill in the value for the NLP in those cases.
691         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
692                                                       OutContext),
693                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
694     }
695
696     Stubs.clear();
697     OutStreamer.AddBlankLine();
698   }
699
700   Stubs = MMIMacho.GetHiddenGVStubList();
701   if (!Stubs.empty()) {
702     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
703     EmitAlignment(isPPC64 ? 3 : 2);
704     
705     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
706       // L_foo$stub:
707       OutStreamer.EmitLabel(Stubs[i].first);
708       //   .long _foo
709       OutStreamer.EmitValue(MCSymbolRefExpr::
710                             Create(Stubs[i].second.getPointer(),
711                                    OutContext),
712                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
713     }
714
715     Stubs.clear();
716     OutStreamer.AddBlankLine();
717   }
718
719   // Funny Darwin hack: This flag tells the linker that no global symbols
720   // contain code that falls through to other global symbols (e.g. the obvious
721   // implementation of multiple entry points).  If this doesn't occur, the
722   // linker can safely perform dead code stripping.  Since LLVM never generates
723   // code that does this, it is always safe to set.
724   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
725
726   return AsmPrinter::doFinalization(M);
727 }
728
729 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
730 /// for a MachineFunction to the given output stream, in a format that the
731 /// Darwin assembler can deal with.
732 ///
733 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
734                                            MCStreamer &Streamer) {
735   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
736
737   if (Subtarget->isDarwin())
738     return new PPCDarwinAsmPrinter(tm, Streamer);
739   return new PPCLinuxAsmPrinter(tm, Streamer);
740 }
741
742 // Force static initialization.
743 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
744   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
745   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
746 }