PPCDarwinAsmPrinter::EmitStartOfAsmFile(): Add possible elements in CPUDirectives[].
[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 "InstPrinter/PPCInstPrinter.h"
22 #include "MCTargetDesc/PPCPredicates.h"
23 #include "PPCSubtarget.h"
24 #include "PPCTargetMachine.h"
25 #include "llvm/ADT/MapVector.h"
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/Assembly/Writer.h"
29 #include "llvm/CodeGen/AsmPrinter.h"
30 #include "llvm/CodeGen/MachineFunctionPass.h"
31 #include "llvm/CodeGen/MachineInstr.h"
32 #include "llvm/CodeGen/MachineInstrBuilder.h"
33 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
34 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
35 #include "llvm/DebugInfo.h"
36 #include "llvm/IR/Constants.h"
37 #include "llvm/IR/DerivedTypes.h"
38 #include "llvm/IR/Module.h"
39 #include "llvm/MC/MCAsmInfo.h"
40 #include "llvm/MC/MCContext.h"
41 #include "llvm/MC/MCExpr.h"
42 #include "llvm/MC/MCInst.h"
43 #include "llvm/MC/MCInstBuilder.h"
44 #include "llvm/MC/MCSectionELF.h"
45 #include "llvm/MC/MCSectionMachO.h"
46 #include "llvm/MC/MCStreamer.h"
47 #include "llvm/MC/MCSymbol.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/Debug.h"
50 #include "llvm/Support/ELF.h"
51 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/MathExtras.h"
53 #include "llvm/Support/TargetRegistry.h"
54 #include "llvm/Support/raw_ostream.h"
55 #include "llvm/Target/Mangler.h"
56 #include "llvm/Target/TargetInstrInfo.h"
57 #include "llvm/Target/TargetOptions.h"
58 #include "llvm/Target/TargetRegisterInfo.h"
59 using namespace llvm;
60
61 namespace {
62   class PPCAsmPrinter : public AsmPrinter {
63   protected:
64     MapVector<MCSymbol*, MCSymbol*> TOC;
65     const PPCSubtarget &Subtarget;
66     uint64_t TOCLabelID;
67   public:
68     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
69       : AsmPrinter(TM, Streamer),
70         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
71
72     virtual const char *getPassName() const {
73       return "PowerPC Assembly Printer";
74     }
75
76     MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
77
78     virtual void EmitInstruction(const MachineInstr *MI);
79
80     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
81
82     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
83                          unsigned AsmVariant, const char *ExtraCode,
84                          raw_ostream &O);
85     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
86                                unsigned AsmVariant, const char *ExtraCode,
87                                raw_ostream &O);
88
89     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
90       MachineLocation Location;
91       assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
92       // Frame address.  Currently handles register +- offset only.
93       if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
94         Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
95       else {
96         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
97       }
98       return Location;
99     }
100   };
101
102   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
103   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
104   public:
105     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
106       : PPCAsmPrinter(TM, Streamer) {}
107
108     virtual const char *getPassName() const {
109       return "Linux PPC Assembly Printer";
110     }
111
112     bool doFinalization(Module &M);
113
114     virtual void EmitFunctionEntryLabel();
115
116     void EmitFunctionBodyEnd();
117   };
118
119   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
120   /// OS X
121   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
122   public:
123     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
124       : PPCAsmPrinter(TM, Streamer) {}
125
126     virtual const char *getPassName() const {
127       return "Darwin PPC Assembly Printer";
128     }
129
130     bool doFinalization(Module &M);
131     void EmitStartOfAsmFile(Module &M);
132
133     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
134   };
135 } // end of anonymous namespace
136
137 /// stripRegisterPrefix - This method strips the character prefix from a
138 /// register name so that only the number is left.  Used by for linux asm.
139 static const char *stripRegisterPrefix(const char *RegName) {
140   switch (RegName[0]) {
141     case 'r':
142     case 'f':
143     case 'v': return RegName + 1;
144     case 'c': if (RegName[1] == 'r') return RegName + 2;
145   }
146   
147   return RegName;
148 }
149
150 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
151                                  raw_ostream &O) {
152   const MachineOperand &MO = MI->getOperand(OpNo);
153   
154   switch (MO.getType()) {
155   case MachineOperand::MO_Register: {
156     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
157     // Linux assembler (Others?) does not take register mnemonics.
158     // FIXME - What about special registers used in mfspr/mtspr?
159     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
160     O << RegName;
161     return;
162   }
163   case MachineOperand::MO_Immediate:
164     O << MO.getImm();
165     return;
166
167   case MachineOperand::MO_MachineBasicBlock:
168     O << *MO.getMBB()->getSymbol();
169     return;
170   case MachineOperand::MO_JumpTableIndex:
171     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
172       << '_' << MO.getIndex();
173     // FIXME: PIC relocation model
174     return;
175   case MachineOperand::MO_ConstantPoolIndex:
176     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
177       << '_' << MO.getIndex();
178     return;
179   case MachineOperand::MO_BlockAddress:
180     O << *GetBlockAddressSymbol(MO.getBlockAddress());
181     return;
182   case MachineOperand::MO_ExternalSymbol: {
183     // Computing the address of an external symbol, not calling it.
184     if (TM.getRelocationModel() == Reloc::Static) {
185       O << *GetExternalSymbolSymbol(MO.getSymbolName());
186       return;
187     }
188
189     MCSymbol *NLPSym = 
190       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
191                                    MO.getSymbolName()+"$non_lazy_ptr");
192     MachineModuleInfoImpl::StubValueTy &StubSym = 
193       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
194     if (StubSym.getPointer() == 0)
195       StubSym = MachineModuleInfoImpl::
196         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
197     
198     O << *NLPSym;
199     return;
200   }
201   case MachineOperand::MO_GlobalAddress: {
202     // Computing the address of a global symbol, not calling it.
203     const GlobalValue *GV = MO.getGlobal();
204     MCSymbol *SymToPrint;
205
206     // External or weakly linked global variables need non-lazily-resolved stubs
207     if (TM.getRelocationModel() != Reloc::Static &&
208         (GV->isDeclaration() || GV->isWeakForLinker())) {
209       if (!GV->hasHiddenVisibility()) {
210         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
211         MachineModuleInfoImpl::StubValueTy &StubSym = 
212           MMI->getObjFileInfo<MachineModuleInfoMachO>()
213             .getGVStubEntry(SymToPrint);
214         if (StubSym.getPointer() == 0)
215           StubSym = MachineModuleInfoImpl::
216             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
217       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
218                  GV->hasAvailableExternallyLinkage()) {
219         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
220         
221         MachineModuleInfoImpl::StubValueTy &StubSym = 
222           MMI->getObjFileInfo<MachineModuleInfoMachO>().
223                     getHiddenGVStubEntry(SymToPrint);
224         if (StubSym.getPointer() == 0)
225           StubSym = MachineModuleInfoImpl::
226             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
227       } else {
228         SymToPrint = Mang->getSymbol(GV);
229       }
230     } else {
231       SymToPrint = Mang->getSymbol(GV);
232     }
233     
234     O << *SymToPrint;
235
236     printOffset(MO.getOffset(), O);
237     return;
238   }
239
240   default:
241     O << "<unknown operand type: " << MO.getType() << ">";
242     return;
243   }
244 }
245
246 /// PrintAsmOperand - Print out an operand for an inline asm expression.
247 ///
248 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
249                                     unsigned AsmVariant,
250                                     const char *ExtraCode, raw_ostream &O) {
251   // Does this asm operand have a single letter operand modifier?
252   if (ExtraCode && ExtraCode[0]) {
253     if (ExtraCode[1] != 0) return true; // Unknown modifier.
254
255     switch (ExtraCode[0]) {
256     default:
257       // See if this is a generic print operand
258       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
259     case 'c': // Don't print "$" before a global var name or constant.
260       break; // PPC never has a prefix.
261     case 'L': // Write second word of DImode reference.
262       // Verify that this operand has two consecutive registers.
263       if (!MI->getOperand(OpNo).isReg() ||
264           OpNo+1 == MI->getNumOperands() ||
265           !MI->getOperand(OpNo+1).isReg())
266         return true;
267       ++OpNo;   // Return the high-part.
268       break;
269     case 'I':
270       // Write 'i' if an integer constant, otherwise nothing.  Used to print
271       // addi vs add, etc.
272       if (MI->getOperand(OpNo).isImm())
273         O << "i";
274       return false;
275     }
276   }
277
278   printOperand(MI, OpNo, O);
279   return false;
280 }
281
282 // At the moment, all inline asm memory operands are a single register.
283 // In any case, the output of this routine should always be just one
284 // assembler operand.
285
286 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
287                                           unsigned AsmVariant,
288                                           const char *ExtraCode,
289                                           raw_ostream &O) {
290   if (ExtraCode && ExtraCode[0]) {
291     if (ExtraCode[1] != 0) return true; // Unknown modifier.
292
293     switch (ExtraCode[0]) {
294     default: return true;  // Unknown modifier.
295     case 'y': // A memory reference for an X-form instruction
296       {
297         const char *RegName = "r0";
298         if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
299         O << RegName << ", ";
300         printOperand(MI, OpNo, O);
301         return false;
302       }
303     }
304   }
305
306   assert(MI->getOperand(OpNo).isReg());
307   O << "0(";
308   printOperand(MI, OpNo, O);
309   O << ")";
310   return false;
311 }
312
313
314 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
315 /// exists for it.  If not, create one.  Then return a symbol that references
316 /// the TOC entry.
317 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
318
319   MCSymbol *&TOCEntry = TOC[Sym];
320
321   // To avoid name clash check if the name already exists.
322   while (TOCEntry == 0) {
323     if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
324                                 "C" + Twine(TOCLabelID++)) == 0) {
325       TOCEntry = GetTempSymbol("C", TOCLabelID);
326     }
327   }
328
329   return TOCEntry;
330 }
331
332
333 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
334 /// the current output stream.
335 ///
336 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
337   MCInst TmpInst;
338   
339   // Lower multi-instruction pseudo operations.
340   switch (MI->getOpcode()) {
341   default: break;
342   case TargetOpcode::DBG_VALUE: {
343     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
344       
345     SmallString<32> Str;
346     raw_svector_ostream O(Str);
347     unsigned NOps = MI->getNumOperands();
348     assert(NOps==4);
349     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
350     // cast away const; DIetc do not take const operands for some reason.
351     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
352     O << V.getName();
353     O << " <- ";
354     // Frame address.  Currently handles register +- offset only.
355     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
356     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
357     O << ']';
358     O << "+";
359     printOperand(MI, NOps-2, O);
360     OutStreamer.EmitRawText(O.str());
361     return;
362   }
363       
364   case PPC::MovePCtoLR:
365   case PPC::MovePCtoLR8: {
366     // Transform %LR = MovePCtoLR
367     // Into this, where the label is the PIC base: 
368     //     bl L1$pb
369     // L1$pb:
370     MCSymbol *PICBase = MF->getPICBaseSymbol();
371     
372     // Emit the 'bl'.
373     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
374       // FIXME: We would like an efficient form for this, so we don't have to do
375       // a lot of extra uniquing.
376       .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
377     
378     // Emit the label.
379     OutStreamer.EmitLabel(PICBase);
380     return;
381   }
382   case PPC::LDtocJTI:
383   case PPC::LDtocCPT:
384   case PPC::LDtoc: {
385     // Transform %X3 = LDtoc <ga:@min1>, %X2
386     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
387
388     // Change the opcode to LD, and the global address operand to be a
389     // reference to the TOC entry we will synthesize later.
390     TmpInst.setOpcode(PPC::LD);
391     const MachineOperand &MO = MI->getOperand(1);
392
393     // Map symbol -> label of TOC entry
394     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
395     MCSymbol *MOSymbol = 0;
396     if (MO.isGlobal())
397       MOSymbol = Mang->getSymbol(MO.getGlobal());
398     else if (MO.isCPI())
399       MOSymbol = GetCPISymbol(MO.getIndex());
400     else if (MO.isJTI())
401       MOSymbol = GetJTISymbol(MO.getIndex());
402
403     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
404
405     const MCExpr *Exp =
406       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
407                               OutContext);
408     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
409     OutStreamer.EmitInstruction(TmpInst);
410     return;
411   }
412       
413   case PPC::ADDIStocHA: {
414     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
415     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
416
417     // Change the opcode to ADDIS8.  If the global address is external,
418     // has common linkage, is a function address, or is a jump table
419     // address, then generate a TOC entry and reference that.  Otherwise
420     // reference the symbol directly.
421     TmpInst.setOpcode(PPC::ADDIS8);
422     const MachineOperand &MO = MI->getOperand(2);
423     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
424            "Invalid operand for ADDIStocHA!");
425     MCSymbol *MOSymbol = 0;
426     bool IsExternal = false;
427     bool IsFunction = false;
428     bool IsCommon = false;
429     bool IsAvailExt = false;
430
431     if (MO.isGlobal()) {
432       const GlobalValue *GValue = MO.getGlobal();
433       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
434       const GlobalValue *RealGValue = GAlias ?
435         GAlias->resolveAliasedGlobal(false) : GValue;
436       MOSymbol = Mang->getSymbol(RealGValue);
437       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
438       IsExternal = GVar && !GVar->hasInitializer();
439       IsCommon = GVar && RealGValue->hasCommonLinkage();
440       IsFunction = !GVar;
441       IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
442     } else if (MO.isCPI())
443       MOSymbol = GetCPISymbol(MO.getIndex());
444     else if (MO.isJTI())
445       MOSymbol = GetJTISymbol(MO.getIndex());
446
447     if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
448       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
449
450     const MCExpr *Exp =
451       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA,
452                               OutContext);
453     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
454     OutStreamer.EmitInstruction(TmpInst);
455     return;
456   }
457   case PPC::LDtocL: {
458     // Transform %Xd = LDtocL <ga:@sym>, %Xs
459     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
460
461     // Change the opcode to LDrs, which is a form of LD with the offset
462     // specified by a SymbolLo.  If the global address is external, has
463     // common linkage, or is a jump table address, then reference the
464     // associated TOC entry.  Otherwise reference the symbol directly.
465     TmpInst.setOpcode(PPC::LDrs);
466     const MachineOperand &MO = MI->getOperand(1);
467     assert((MO.isGlobal() || MO.isJTI()) && "Invalid operand for LDtocL!");
468     MCSymbol *MOSymbol = 0;
469
470     if (MO.isJTI())
471       MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
472     else {
473       const GlobalValue *GValue = MO.getGlobal();
474       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
475       const GlobalValue *RealGValue = GAlias ?
476         GAlias->resolveAliasedGlobal(false) : GValue;
477       MOSymbol = Mang->getSymbol(RealGValue);
478       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
479     
480       if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() ||
481           RealGValue->hasAvailableExternallyLinkage())
482         MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
483     }
484
485     const MCExpr *Exp =
486       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
487                               OutContext);
488     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
489     OutStreamer.EmitInstruction(TmpInst);
490     return;
491   }
492   case PPC::ADDItocL: {
493     // Transform %Xd = ADDItocL %Xs, <ga:@sym>
494     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
495
496     // Change the opcode to ADDI8L.  If the global address is external, then
497     // generate a TOC entry and reference that.  Otherwise reference the
498     // symbol directly.
499     TmpInst.setOpcode(PPC::ADDI8L);
500     const MachineOperand &MO = MI->getOperand(2);
501     assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
502     MCSymbol *MOSymbol = 0;
503     bool IsExternal = false;
504     bool IsFunction = false;
505
506     if (MO.isGlobal()) {
507       const GlobalValue *GValue = MO.getGlobal();
508       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
509       const GlobalValue *RealGValue = GAlias ?
510         GAlias->resolveAliasedGlobal(false) : GValue;
511       MOSymbol = Mang->getSymbol(RealGValue);
512       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
513       IsExternal = GVar && !GVar->hasInitializer();
514       IsFunction = !GVar;
515     } else if (MO.isCPI())
516       MOSymbol = GetCPISymbol(MO.getIndex());
517
518     if (IsFunction || IsExternal)
519       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
520
521     const MCExpr *Exp =
522       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
523                               OutContext);
524     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
525     OutStreamer.EmitInstruction(TmpInst);
526     return;
527   }
528   case PPC::ADDISgotTprelHA: {
529     // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
530     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
531     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
532     const MachineOperand &MO = MI->getOperand(2);
533     const GlobalValue *GValue = MO.getGlobal();
534     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
535     const MCExpr *SymGotTprel =
536       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA,
537                               OutContext);
538     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
539                                 .addReg(MI->getOperand(0).getReg())
540                                 .addReg(PPC::X2)
541                                 .addExpr(SymGotTprel));
542     return;
543   }
544   case PPC::LDgotTprelL: {
545     // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
546     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
547
548     // Change the opcode to LDrs, which is a form of LD with the offset
549     // specified by a SymbolLo.
550     TmpInst.setOpcode(PPC::LDrs);
551     const MachineOperand &MO = MI->getOperand(1);
552     const GlobalValue *GValue = MO.getGlobal();
553     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
554     const MCExpr *Exp =
555       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO,
556                               OutContext);
557     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
558     OutStreamer.EmitInstruction(TmpInst);
559     return;
560   }
561   case PPC::ADDIStlsgdHA: {
562     // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
563     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
564     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
565     const MachineOperand &MO = MI->getOperand(2);
566     const GlobalValue *GValue = MO.getGlobal();
567     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
568     const MCExpr *SymGotTlsGD =
569       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA,
570                               OutContext);
571     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
572                                 .addReg(MI->getOperand(0).getReg())
573                                 .addReg(PPC::X2)
574                                 .addExpr(SymGotTlsGD));
575     return;
576   }
577   case PPC::ADDItlsgdL: {
578     // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
579     // Into:      %Xd = ADDI8L %Xs, sym@got@tlsgd@l
580     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
581     const MachineOperand &MO = MI->getOperand(2);
582     const GlobalValue *GValue = MO.getGlobal();
583     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
584     const MCExpr *SymGotTlsGD =
585       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO,
586                               OutContext);
587     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
588                                 .addReg(MI->getOperand(0).getReg())
589                                 .addReg(MI->getOperand(1).getReg())
590                                 .addExpr(SymGotTlsGD));
591     return;
592   }
593   case PPC::GETtlsADDR: {
594     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
595     // Into:      BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd)
596     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
597
598     StringRef Name = "__tls_get_addr";
599     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
600     const MCSymbolRefExpr *TlsRef = 
601       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
602     const MachineOperand &MO = MI->getOperand(2);
603     const GlobalValue *GValue = MO.getGlobal();
604     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
605     const MCExpr *SymVar =
606       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
607                               OutContext);
608     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD)
609                                 .addExpr(TlsRef)
610                                 .addExpr(SymVar));
611     return;
612   }
613   case PPC::ADDIStlsldHA: {
614     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
615     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
616     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
617     const MachineOperand &MO = MI->getOperand(2);
618     const GlobalValue *GValue = MO.getGlobal();
619     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
620     const MCExpr *SymGotTlsLD =
621       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA,
622                               OutContext);
623     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
624                                 .addReg(MI->getOperand(0).getReg())
625                                 .addReg(PPC::X2)
626                                 .addExpr(SymGotTlsLD));
627     return;
628   }
629   case PPC::ADDItlsldL: {
630     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
631     // Into:      %Xd = ADDI8L %Xs, sym@got@tlsld@l
632     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
633     const MachineOperand &MO = MI->getOperand(2);
634     const GlobalValue *GValue = MO.getGlobal();
635     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
636     const MCExpr *SymGotTlsLD =
637       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO,
638                               OutContext);
639     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
640                                 .addReg(MI->getOperand(0).getReg())
641                                 .addReg(MI->getOperand(1).getReg())
642                                 .addExpr(SymGotTlsLD));
643     return;
644   }
645   case PPC::GETtlsldADDR: {
646     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
647     // Into:      BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld)
648     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
649
650     StringRef Name = "__tls_get_addr";
651     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
652     const MCSymbolRefExpr *TlsRef = 
653       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
654     const MachineOperand &MO = MI->getOperand(2);
655     const GlobalValue *GValue = MO.getGlobal();
656     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
657     const MCExpr *SymVar =
658       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
659                               OutContext);
660     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD)
661                                 .addExpr(TlsRef)
662                                 .addExpr(SymVar));
663     return;
664   }
665   case PPC::ADDISdtprelHA: {
666     // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
667     // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
668     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
669     const MachineOperand &MO = MI->getOperand(2);
670     const GlobalValue *GValue = MO.getGlobal();
671     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
672     const MCExpr *SymDtprel =
673       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA,
674                               OutContext);
675     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
676                                 .addReg(MI->getOperand(0).getReg())
677                                 .addReg(PPC::X3)
678                                 .addExpr(SymDtprel));
679     return;
680   }
681   case PPC::ADDIdtprelL: {
682     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
683     // Into:      %Xd = ADDI8L %Xs, sym@dtprel@l
684     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
685     const MachineOperand &MO = MI->getOperand(2);
686     const GlobalValue *GValue = MO.getGlobal();
687     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
688     const MCExpr *SymDtprel =
689       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO,
690                               OutContext);
691     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
692                                 .addReg(MI->getOperand(0).getReg())
693                                 .addReg(MI->getOperand(1).getReg())
694                                 .addExpr(SymDtprel));
695     return;
696   }
697   case PPC::MFCRpseud:
698   case PPC::MFCR8pseud:
699     // Transform: %R3 = MFCRpseud %CR7
700     // Into:      %R3 = MFCR      ;; cr7
701     OutStreamer.AddComment(PPCInstPrinter::
702                            getRegisterName(MI->getOperand(1).getReg()));
703     OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
704       .addReg(MI->getOperand(0).getReg()));
705     return;
706   case PPC::SYNC:
707     // In Book E sync is called msync, handle this special case here...
708     if (Subtarget.isBookE()) {
709       OutStreamer.EmitRawText(StringRef("\tmsync"));
710       return;
711     }
712   }
713
714   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
715   OutStreamer.EmitInstruction(TmpInst);
716 }
717
718 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
719   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
720     return AsmPrinter::EmitFunctionEntryLabel();
721     
722   // Emit an official procedure descriptor.
723   const MCSection *Current = OutStreamer.getCurrentSection();
724   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
725       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
726       SectionKind::getReadOnly());
727   OutStreamer.SwitchSection(Section);
728   OutStreamer.EmitLabel(CurrentFnSym);
729   OutStreamer.EmitValueToAlignment(8);
730   MCSymbol *Symbol1 = 
731     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
732   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
733   // entry point.
734   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
735                         8 /*size*/);
736   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
737   // Generates a R_PPC64_TOC relocation for TOC base insertion.
738   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
739                         MCSymbolRefExpr::VK_PPC_TOC, OutContext),
740                         8/*size*/);
741   // Emit a null environment pointer.
742   OutStreamer.EmitIntValue(0, 8 /* size */);
743   OutStreamer.SwitchSection(Current);
744
745   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
746                           ".L." + Twine(CurrentFnSym->getName()));
747   OutStreamer.EmitLabel(RealFnSym);
748   CurrentFnSymForSize = RealFnSym;
749 }
750
751
752 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
753   const DataLayout *TD = TM.getDataLayout();
754
755   bool isPPC64 = TD->getPointerSizeInBits() == 64;
756
757   if (isPPC64 && !TOC.empty()) {
758     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
759         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
760         SectionKind::getReadOnly());
761     OutStreamer.SwitchSection(Section);
762
763     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
764          E = TOC.end(); I != E; ++I) {
765       OutStreamer.EmitLabel(I->second);
766       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
767       OutStreamer.EmitTCEntry(*S);
768     }
769   }
770
771   MachineModuleInfoELF &MMIELF =
772     MMI->getObjFileInfo<MachineModuleInfoELF>();
773
774   MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
775   if (!Stubs.empty()) {
776     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
777     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
778       // L_foo$stub:
779       OutStreamer.EmitLabel(Stubs[i].first);
780       //   .long _foo
781       OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
782                                                     OutContext),
783                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
784     }
785
786     Stubs.clear();
787     OutStreamer.AddBlankLine();
788   }
789
790   return AsmPrinter::doFinalization(M);
791 }
792
793 /// EmitFunctionBodyEnd - Print the traceback table before the .size
794 /// directive.
795 ///
796 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
797   // Only the 64-bit target requires a traceback table.  For now,
798   // we only emit the word of zeroes that GDB requires to find
799   // the end of the function, and zeroes for the eight-byte
800   // mandatory fields.
801   // FIXME: We should fill in the eight-byte mandatory fields as described in
802   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
803   // currently make use of these fields).
804   if (Subtarget.isPPC64()) {
805     OutStreamer.EmitIntValue(0, 4/*size*/);
806     OutStreamer.EmitIntValue(0, 8/*size*/);
807   }
808 }
809
810 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
811   static const char *const CPUDirectives[] = {
812     "",
813     "ppc",
814     "ppc440",
815     "ppc601",
816     "ppc602",
817     "ppc603",
818     "ppc7400",
819     "ppc750",
820     "ppc970",
821     "ppcA2",
822     "ppce500mc",
823     "ppce5500",
824     "power3",
825     "power4",
826     "power5",
827     "power5x",
828     "power6",
829     "power6x",
830     "power7",
831     "ppc64"
832   };
833
834   unsigned Directive = Subtarget.getDarwinDirective();
835   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
836     Directive = PPC::DIR_970;
837   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
838     Directive = PPC::DIR_7400;
839   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
840     Directive = PPC::DIR_64;
841   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
842   
843   // FIXME: This is a total hack, finish mc'izing the PPC backend.
844   if (OutStreamer.hasRawTextSupport())
845     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
846
847   // Prime text sections so they are adjacent.  This reduces the likelihood a
848   // large data or debug section causes a branch to exceed 16M limit.
849   const TargetLoweringObjectFileMachO &TLOFMacho = 
850     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
851   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
852   if (TM.getRelocationModel() == Reloc::PIC_) {
853     OutStreamer.SwitchSection(
854            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
855                                       MCSectionMachO::S_SYMBOL_STUBS |
856                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
857                                       32, SectionKind::getText()));
858   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
859     OutStreamer.SwitchSection(
860            OutContext.getMachOSection("__TEXT","__symbol_stub1",
861                                       MCSectionMachO::S_SYMBOL_STUBS |
862                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
863                                       16, SectionKind::getText()));
864   }
865   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
866 }
867
868 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
869   // Remove $stub suffix, add $lazy_ptr.
870   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
871   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
872 }
873
874 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
875   // Add $tmp suffix to $stub, yielding $stub$tmp.
876   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
877 }
878
879 void PPCDarwinAsmPrinter::
880 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
881   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
882   
883   const TargetLoweringObjectFileMachO &TLOFMacho = 
884     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
885
886   // .lazy_symbol_pointer
887   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
888   
889   // Output stubs for dynamically-linked functions
890   if (TM.getRelocationModel() == Reloc::PIC_) {
891     const MCSection *StubSection = 
892     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
893                                MCSectionMachO::S_SYMBOL_STUBS |
894                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
895                                32, SectionKind::getText());
896     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
897       OutStreamer.SwitchSection(StubSection);
898       EmitAlignment(4);
899       
900       MCSymbol *Stub = Stubs[i].first;
901       MCSymbol *RawSym = Stubs[i].second.getPointer();
902       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
903       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
904                                            
905       OutStreamer.EmitLabel(Stub);
906       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
907
908       // mflr r0
909       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
910       // FIXME: MCize this.
911       OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
912       OutStreamer.EmitLabel(AnonSymbol);
913       // mflr r11
914       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
915       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
916       const MCExpr *Sub =
917         MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
918                                 MCSymbolRefExpr::Create(AnonSymbol, OutContext),
919                                 OutContext);
920       OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
921         .addReg(PPC::R11)
922         .addReg(PPC::R11)
923         .addExpr(Sub));
924       // mtlr r0
925       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
926
927       // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
928       // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
929       OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
930         .addReg(PPC::R12)
931         .addExpr(Sub).addExpr(Sub)
932         .addReg(PPC::R11));
933       // mtctr r12
934       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
935       // bctr
936       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
937
938       OutStreamer.SwitchSection(LSPSection);
939       OutStreamer.EmitLabel(LazyPtr);
940       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
941
942       MCSymbol *DyldStubBindingHelper =
943         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
944       if (isPPC64) {
945         // .quad dyld_stub_binding_helper
946         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
947       } else {
948         // .long dyld_stub_binding_helper
949         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
950       }
951     }
952     OutStreamer.AddBlankLine();
953     return;
954   }
955   
956   const MCSection *StubSection =
957     OutContext.getMachOSection("__TEXT","__symbol_stub1",
958                                MCSectionMachO::S_SYMBOL_STUBS |
959                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
960                                16, SectionKind::getText());
961   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
962     MCSymbol *Stub = Stubs[i].first;
963     MCSymbol *RawSym = Stubs[i].second.getPointer();
964     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
965
966     OutStreamer.SwitchSection(StubSection);
967     EmitAlignment(4);
968     OutStreamer.EmitLabel(Stub);
969     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
970     // lis r11, ha16(LazyPtr)
971     const MCExpr *LazyPtrHa16 =
972       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
973                               OutContext);
974     OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
975       .addReg(PPC::R11)
976       .addExpr(LazyPtrHa16));
977
978     const MCExpr *LazyPtrLo16 =
979       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
980                               OutContext);
981     // ldu r12, lo16(LazyPtr)(r11)
982     // lwzu r12, lo16(LazyPtr)(r11)
983     OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
984       .addReg(PPC::R12)
985       .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
986       .addReg(PPC::R11));
987
988     // mtctr r12
989     OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
990     // bctr
991     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
992
993     OutStreamer.SwitchSection(LSPSection);
994     OutStreamer.EmitLabel(LazyPtr);
995     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
996
997     MCSymbol *DyldStubBindingHelper =
998       OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
999     if (isPPC64) {
1000       // .quad dyld_stub_binding_helper
1001       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
1002     } else {
1003       // .long dyld_stub_binding_helper
1004       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
1005     }
1006   }
1007   
1008   OutStreamer.AddBlankLine();
1009 }
1010
1011
1012 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1013   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
1014
1015   // Darwin/PPC always uses mach-o.
1016   const TargetLoweringObjectFileMachO &TLOFMacho = 
1017     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1018   MachineModuleInfoMachO &MMIMacho =
1019     MMI->getObjFileInfo<MachineModuleInfoMachO>();
1020   
1021   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
1022   if (!Stubs.empty())
1023     EmitFunctionStubs(Stubs);
1024
1025   if (MAI->doesSupportExceptionHandling() && MMI) {
1026     // Add the (possibly multiple) personalities to the set of global values.
1027     // Only referenced functions get into the Personalities list.
1028     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
1029     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
1030          E = Personalities.end(); I != E; ++I) {
1031       if (*I) {
1032         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
1033         MachineModuleInfoImpl::StubValueTy &StubSym =
1034           MMIMacho.getGVStubEntry(NLPSym);
1035         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
1036       }
1037     }
1038   }
1039
1040   // Output stubs for dynamically-linked functions.
1041   Stubs = MMIMacho.GetGVStubList();
1042   
1043   // Output macho stubs for external and common global variables.
1044   if (!Stubs.empty()) {
1045     // Switch with ".non_lazy_symbol_pointer" directive.
1046     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1047     EmitAlignment(isPPC64 ? 3 : 2);
1048     
1049     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1050       // L_foo$stub:
1051       OutStreamer.EmitLabel(Stubs[i].first);
1052       //   .indirect_symbol _foo
1053       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1054       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
1055
1056       if (MCSym.getInt())
1057         // External to current translation unit.
1058         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
1059       else
1060         // Internal to current translation unit.
1061         //
1062         // When we place the LSDA into the TEXT section, the type info pointers
1063         // need to be indirect and pc-rel. We accomplish this by using NLPs.
1064         // However, sometimes the types are local to the file. So we need to
1065         // fill in the value for the NLP in those cases.
1066         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1067                                                       OutContext),
1068                               isPPC64 ? 8 : 4/*size*/);
1069     }
1070
1071     Stubs.clear();
1072     OutStreamer.AddBlankLine();
1073   }
1074
1075   Stubs = MMIMacho.GetHiddenGVStubList();
1076   if (!Stubs.empty()) {
1077     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1078     EmitAlignment(isPPC64 ? 3 : 2);
1079     
1080     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1081       // L_foo$stub:
1082       OutStreamer.EmitLabel(Stubs[i].first);
1083       //   .long _foo
1084       OutStreamer.EmitValue(MCSymbolRefExpr::
1085                             Create(Stubs[i].second.getPointer(),
1086                                    OutContext),
1087                             isPPC64 ? 8 : 4/*size*/);
1088     }
1089
1090     Stubs.clear();
1091     OutStreamer.AddBlankLine();
1092   }
1093
1094   // Funny Darwin hack: This flag tells the linker that no global symbols
1095   // contain code that falls through to other global symbols (e.g. the obvious
1096   // implementation of multiple entry points).  If this doesn't occur, the
1097   // linker can safely perform dead code stripping.  Since LLVM never generates
1098   // code that does this, it is always safe to set.
1099   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1100
1101   return AsmPrinter::doFinalization(M);
1102 }
1103
1104 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1105 /// for a MachineFunction to the given output stream, in a format that the
1106 /// Darwin assembler can deal with.
1107 ///
1108 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
1109                                            MCStreamer &Streamer) {
1110   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
1111
1112   if (Subtarget->isDarwin())
1113     return new PPCDarwinAsmPrinter(tm, Streamer);
1114   return new PPCLinuxAsmPrinter(tm, Streamer);
1115 }
1116
1117 // Force static initialization.
1118 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
1119   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
1120   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
1121 }