PPC: Simplify code with Twines.
[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   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
553   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
554 }
555
556 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
557   // Add $tmp suffix to $stub, yielding $stub$tmp.
558   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
559 }
560
561 void PPCDarwinAsmPrinter::
562 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
563   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
564   
565   const TargetLoweringObjectFileMachO &TLOFMacho = 
566     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
567
568   // .lazy_symbol_pointer
569   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
570   
571   // Output stubs for dynamically-linked functions
572   if (TM.getRelocationModel() == Reloc::PIC_) {
573     const MCSection *StubSection = 
574     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
575                                MCSectionMachO::S_SYMBOL_STUBS |
576                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
577                                32, SectionKind::getText());
578     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
579       OutStreamer.SwitchSection(StubSection);
580       EmitAlignment(4);
581       
582       MCSymbol *Stub = Stubs[i].first;
583       MCSymbol *RawSym = Stubs[i].second.getPointer();
584       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
585       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
586                                            
587       OutStreamer.EmitLabel(Stub);
588       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
589       // FIXME: MCize this.
590       OutStreamer.EmitRawText(StringRef("\tmflr r0"));
591       OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName()));
592       OutStreamer.EmitLabel(AnonSymbol);
593       OutStreamer.EmitRawText(StringRef("\tmflr r11"));
594       OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+
595                               "-" + AnonSymbol->getName() + ")");
596       OutStreamer.EmitRawText(StringRef("\tmtlr r0"));
597       
598       if (isPPC64)
599         OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
600                                 "-" + AnonSymbol->getName() + ")(r11)");
601       else
602         OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
603                                 "-" + AnonSymbol->getName() + ")(r11)");
604       OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
605       OutStreamer.EmitRawText(StringRef("\tbctr"));
606       
607       OutStreamer.SwitchSection(LSPSection);
608       OutStreamer.EmitLabel(LazyPtr);
609       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
610       
611       if (isPPC64)
612         OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
613       else
614         OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
615     }
616     OutStreamer.AddBlankLine();
617     return;
618   }
619   
620   const MCSection *StubSection =
621     OutContext.getMachOSection("__TEXT","__symbol_stub1",
622                                MCSectionMachO::S_SYMBOL_STUBS |
623                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
624                                16, SectionKind::getText());
625   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
626     MCSymbol *Stub = Stubs[i].first;
627     MCSymbol *RawSym = Stubs[i].second.getPointer();
628     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
629
630     OutStreamer.SwitchSection(StubSection);
631     EmitAlignment(4);
632     OutStreamer.EmitLabel(Stub);
633     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
634     OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")");
635     if (isPPC64)
636       OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) +
637                               ")(r11)");
638     else
639       OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) +
640                               ")(r11)");
641     OutStreamer.EmitRawText(StringRef("\tmtctr r12"));
642     OutStreamer.EmitRawText(StringRef("\tbctr"));
643     OutStreamer.SwitchSection(LSPSection);
644     OutStreamer.EmitLabel(LazyPtr);
645     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
646     
647     if (isPPC64)
648       OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper"));
649     else
650       OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper"));
651   }
652   
653   OutStreamer.AddBlankLine();
654 }
655
656
657 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
658   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
659
660   // Darwin/PPC always uses mach-o.
661   const TargetLoweringObjectFileMachO &TLOFMacho = 
662     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
663   MachineModuleInfoMachO &MMIMacho =
664     MMI->getObjFileInfo<MachineModuleInfoMachO>();
665   
666   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
667   if (!Stubs.empty())
668     EmitFunctionStubs(Stubs);
669
670   if (MAI->doesSupportExceptionHandling() && MMI) {
671     // Add the (possibly multiple) personalities to the set of global values.
672     // Only referenced functions get into the Personalities list.
673     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
674     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
675          E = Personalities.end(); I != E; ++I) {
676       if (*I) {
677         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
678         MachineModuleInfoImpl::StubValueTy &StubSym =
679           MMIMacho.getGVStubEntry(NLPSym);
680         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
681       }
682     }
683   }
684
685   // Output stubs for dynamically-linked functions.
686   Stubs = MMIMacho.GetGVStubList();
687   
688   // Output macho stubs for external and common global variables.
689   if (!Stubs.empty()) {
690     // Switch with ".non_lazy_symbol_pointer" directive.
691     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
692     EmitAlignment(isPPC64 ? 3 : 2);
693     
694     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
695       // L_foo$stub:
696       OutStreamer.EmitLabel(Stubs[i].first);
697       //   .indirect_symbol _foo
698       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
699       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
700
701       if (MCSym.getInt())
702         // External to current translation unit.
703         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
704       else
705         // Internal to current translation unit.
706         //
707         // When we place the LSDA into the TEXT section, the type info pointers
708         // need to be indirect and pc-rel. We accomplish this by using NLPs.
709         // However, sometimes the types are local to the file. So we need to
710         // fill in the value for the NLP in those cases.
711         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
712                                                       OutContext),
713                               isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
714     }
715
716     Stubs.clear();
717     OutStreamer.AddBlankLine();
718   }
719
720   Stubs = MMIMacho.GetHiddenGVStubList();
721   if (!Stubs.empty()) {
722     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
723     EmitAlignment(isPPC64 ? 3 : 2);
724     
725     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
726       // L_foo$stub:
727       OutStreamer.EmitLabel(Stubs[i].first);
728       //   .long _foo
729       OutStreamer.EmitValue(MCSymbolRefExpr::
730                             Create(Stubs[i].second.getPointer(),
731                                    OutContext),
732                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
733     }
734
735     Stubs.clear();
736     OutStreamer.AddBlankLine();
737   }
738
739   // Funny Darwin hack: This flag tells the linker that no global symbols
740   // contain code that falls through to other global symbols (e.g. the obvious
741   // implementation of multiple entry points).  If this doesn't occur, the
742   // linker can safely perform dead code stripping.  Since LLVM never generates
743   // code that does this, it is always safe to set.
744   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
745
746   return AsmPrinter::doFinalization(M);
747 }
748
749 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
750 /// for a MachineFunction to the given output stream, in a format that the
751 /// Darwin assembler can deal with.
752 ///
753 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
754                                            MCStreamer &Streamer) {
755   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
756
757   if (Subtarget->isDarwin())
758     return new PPCDarwinAsmPrinter(tm, Streamer);
759   return new PPCLinuxAsmPrinter(tm, Streamer);
760 }
761
762 // Force static initialization.
763 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
764   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
765   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
766 }