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