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_TLS __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_TLSGD, OutContext);
577     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
578                                 .addExpr(TlsRef)
579                                 .addExpr(SymVar));
580     return;
581   }
582   case PPC::ADDIStlsldHA: {
583     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
584     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
585     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
586     const MachineOperand &MO = MI->getOperand(2);
587     const GlobalValue *GValue = MO.getGlobal();
588     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
589     const MCExpr *SymGotTlsLD =
590       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
591                               OutContext);
592     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
593                                 .addReg(MI->getOperand(0).getReg())
594                                 .addReg(PPC::X2)
595                                 .addExpr(SymGotTlsLD));
596     return;
597   }
598   case PPC::ADDItlsldL: {
599     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
600     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
601     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
602     const MachineOperand &MO = MI->getOperand(2);
603     const GlobalValue *GValue = MO.getGlobal();
604     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
605     const MCExpr *SymGotTlsLD =
606       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO,
607                               OutContext);
608     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
609                                 .addReg(MI->getOperand(0).getReg())
610                                 .addReg(MI->getOperand(1).getReg())
611                                 .addExpr(SymGotTlsLD));
612     return;
613   }
614   case PPC::GETtlsldADDR: {
615     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
616     // Into:      BL8_NOP_TLS __tls_get_addr(sym@tlsld)
617     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
618 
619     StringRef Name = "__tls_get_addr";
620     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
621     const MCSymbolRefExpr *TlsRef =
622       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
623     const MachineOperand &MO = MI->getOperand(2);
624     const GlobalValue *GValue = MO.getGlobal();
625     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
626     const MCExpr *SymVar =
627       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_TLSLD, OutContext);
628     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLS)
629                                 .addExpr(TlsRef)
630                                 .addExpr(SymVar));
631     return;
632   }
633   case PPC::ADDISdtprelHA: {
634     // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
635     // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
636     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
637     const MachineOperand &MO = MI->getOperand(2);
638     const GlobalValue *GValue = MO.getGlobal();
639     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
640     const MCExpr *SymDtprel =
641       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
642                               OutContext);
643     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
644                                 .addReg(MI->getOperand(0).getReg())
645                                 .addReg(PPC::X3)
646                                 .addExpr(SymDtprel));
647     return;
648   }
649   case PPC::ADDIdtprelL: {
650     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
651     // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
652     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
653     const MachineOperand &MO = MI->getOperand(2);
654     const GlobalValue *GValue = MO.getGlobal();
655     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
656     const MCExpr *SymDtprel =
657       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
658                               OutContext);
659     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
660                                 .addReg(MI->getOperand(0).getReg())
661                                 .addReg(MI->getOperand(1).getReg())
662                                 .addExpr(SymDtprel));
663     return;
664   }
665   case PPC::MFOCRF:
666   case PPC::MFOCRF8:
667     if (!Subtarget.hasMFOCRF()) {
668       // Transform: %R3 = MFOCRF %CR7
669       // Into:      %R3 = MFCR   ;; cr7
670       unsigned NewOpcode =
671         MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
672       OutStreamer.AddComment(PPCInstPrinter::
673                              getRegisterName(MI->getOperand(1).getReg()));
674       OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode)
675                                   .addReg(MI->getOperand(0).getReg()));
676       return;
677     }
678     break;
679   case PPC::MTOCRF:
680   case PPC::MTOCRF8:
681     if (!Subtarget.hasMFOCRF()) {
682       // Transform: %CR7 = MTOCRF %R3
683       // Into:      MTCRF mask, %R3 ;; cr7
684       unsigned NewOpcode =
685         MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
686       unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
687                               ->getEncodingValue(MI->getOperand(0).getReg());
688       OutStreamer.AddComment(PPCInstPrinter::
689                              getRegisterName(MI->getOperand(0).getReg()));
690       OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode)
691                                   .addImm(Mask)
692                                   .addReg(MI->getOperand(1).getReg()));
693       return;
694     }
695     break;
696   case PPC::SYNC:
697     // In Book E sync is called msync, handle this special case here...
698     if (Subtarget.isBookE()) {
699       OutStreamer.EmitRawText(StringRef("\tmsync"));
700       return;
701     }
702     break;
703   case PPC::LD:
704   case PPC::STD:
705   case PPC::LWA: {
706     // Verify alignment is legal, so we don't create relocations
707     // that can't be supported.
708     // FIXME:  This test is currently disabled for Darwin.  The test
709     // suite shows a handful of test cases that fail this check for
710     // Darwin.  Those need to be investigated before this sanity test
711     // can be enabled for those subtargets.
712     if (!Subtarget.isDarwin()) {
713       unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
714       const MachineOperand &MO = MI->getOperand(OpNum);
715       if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
716         llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
717     }
718     // Now process the instruction normally.
719     break;
720   }
721   }
722 
723   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
724   OutStreamer.EmitInstruction(TmpInst);
725 }
726 
727 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
728   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
729     return AsmPrinter::EmitFunctionEntryLabel();
730 
731   // Emit an official procedure descriptor.
732   MCSectionSubPair Current = OutStreamer.getCurrentSection();
733   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
734       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
735       SectionKind::getReadOnly());
736   OutStreamer.SwitchSection(Section);
737   OutStreamer.EmitLabel(CurrentFnSym);
738   OutStreamer.EmitValueToAlignment(8);
739   MCSymbol *Symbol1 =
740     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
741   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
742   // entry point.
743   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
744 			8 /*size*/);
745   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
746   // Generates a R_PPC64_TOC relocation for TOC base insertion.
747   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
748                         MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
749                         8/*size*/);
750   // Emit a null environment pointer.
751   OutStreamer.EmitIntValue(0, 8 /* size */);
752   OutStreamer.SwitchSection(Current.first, Current.second);
753 
754   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
755                           ".L." + Twine(CurrentFnSym->getName()));
756   OutStreamer.EmitLabel(RealFnSym);
757   CurrentFnSymForSize = RealFnSym;
758 }
759 
760 
761 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
762   const DataLayout *TD = TM.getDataLayout();
763 
764   bool isPPC64 = TD->getPointerSizeInBits() == 64;
765 
766   if (isPPC64 && !TOC.empty()) {
767     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
768         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
769         SectionKind::getReadOnly());
770     OutStreamer.SwitchSection(Section);
771 
772     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
773          E = TOC.end(); I != E; ++I) {
774       OutStreamer.EmitLabel(I->second);
775       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
776       OutStreamer.EmitTCEntry(*S);
777     }
778   }
779 
780   MachineModuleInfoELF &MMIELF =
781     MMI->getObjFileInfo<MachineModuleInfoELF>();
782 
783   MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
784   if (!Stubs.empty()) {
785     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
786     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
787       // L_foo$stub:
788       OutStreamer.EmitLabel(Stubs[i].first);
789       //   .long _foo
790       OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
791                                                     OutContext),
792                             isPPC64 ? 8 : 4/*size*/);
793     }
794 
795     Stubs.clear();
796     OutStreamer.AddBlankLine();
797   }
798 
799   return AsmPrinter::doFinalization(M);
800 }
801 
802 /// EmitFunctionBodyEnd - Print the traceback table before the .size
803 /// directive.
804 ///
805 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
806   // Only the 64-bit target requires a traceback table.  For now,
807   // we only emit the word of zeroes that GDB requires to find
808   // the end of the function, and zeroes for the eight-byte
809   // mandatory fields.
810   // FIXME: We should fill in the eight-byte mandatory fields as described in
811   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
812   // currently make use of these fields).
813   if (Subtarget.isPPC64()) {
814     OutStreamer.EmitIntValue(0, 4/*size*/);
815     OutStreamer.EmitIntValue(0, 8/*size*/);
816   }
817 }
818 
819 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
820   static const char *const CPUDirectives[] = {
821     "",
822     "ppc",
823     "ppc440",
824     "ppc601",
825     "ppc602",
826     "ppc603",
827     "ppc7400",
828     "ppc750",
829     "ppc970",
830     "ppcA2",
831     "ppce500mc",
832     "ppce5500",
833     "power3",
834     "power4",
835     "power5",
836     "power5x",
837     "power6",
838     "power6x",
839     "power7",
840     "ppc64"
841   };
842 
843   unsigned Directive = Subtarget.getDarwinDirective();
844   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
845     Directive = PPC::DIR_970;
846   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
847     Directive = PPC::DIR_7400;
848   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
849     Directive = PPC::DIR_64;
850   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
851 
852   // FIXME: This is a total hack, finish mc'izing the PPC backend.
853   if (OutStreamer.hasRawTextSupport()) {
854     assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) &&
855            "CPUDirectives[] might not be up-to-date!");
856     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
857   }
858 
859   // Prime text sections so they are adjacent.  This reduces the likelihood a
860   // large data or debug section causes a branch to exceed 16M limit.
861   const TargetLoweringObjectFileMachO &TLOFMacho =
862     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
863   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
864   if (TM.getRelocationModel() == Reloc::PIC_) {
865     OutStreamer.SwitchSection(
866            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
867                                       MCSectionMachO::S_SYMBOL_STUBS |
868                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
869                                       32, SectionKind::getText()));
870   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
871     OutStreamer.SwitchSection(
872            OutContext.getMachOSection("__TEXT","__symbol_stub1",
873                                       MCSectionMachO::S_SYMBOL_STUBS |
874                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
875                                       16, SectionKind::getText()));
876   }
877   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
878 }
879 
880 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
881   // Remove $stub suffix, add $lazy_ptr.
882   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
883   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
884 }
885 
886 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
887   // Add $tmp suffix to $stub, yielding $stub$tmp.
888   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
889 }
890 
891 void PPCDarwinAsmPrinter::
892 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
893   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
894 
895   const TargetLoweringObjectFileMachO &TLOFMacho =
896     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
897 
898   // .lazy_symbol_pointer
899   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
900 
901   // Output stubs for dynamically-linked functions
902   if (TM.getRelocationModel() == Reloc::PIC_) {
903     const MCSection *StubSection =
904     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
905                                MCSectionMachO::S_SYMBOL_STUBS |
906                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
907                                32, SectionKind::getText());
908     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
909       OutStreamer.SwitchSection(StubSection);
910       EmitAlignment(4);
911 
912       MCSymbol *Stub = Stubs[i].first;
913       MCSymbol *RawSym = Stubs[i].second.getPointer();
914       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
915       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
916 
917       OutStreamer.EmitLabel(Stub);
918       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
919 
920       const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
921       const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
922       const MCExpr *Sub =
923         MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext);
924 
925       // mflr r0
926       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
927       // bcl 20, 31, AnonSymbol
928       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon));
929       OutStreamer.EmitLabel(AnonSymbol);
930       // mflr r11
931       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
932       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
933       const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, OutContext);
934       OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
935         .addReg(PPC::R11)
936         .addReg(PPC::R11)
937         .addExpr(SubHa16));
938       // mtlr r0
939       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
940 
941       // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
942       // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
943       const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, OutContext);
944       OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
945         .addReg(PPC::R12)
946         .addExpr(SubLo16).addExpr(SubLo16)
947         .addReg(PPC::R11));
948       // mtctr r12
949       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
950       // bctr
951       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
952 
953       OutStreamer.SwitchSection(LSPSection);
954       OutStreamer.EmitLabel(LazyPtr);
955       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
956 
957       MCSymbol *DyldStubBindingHelper =
958         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
959       if (isPPC64) {
960         // .quad dyld_stub_binding_helper
961         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
962       } else {
963         // .long dyld_stub_binding_helper
964         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
965       }
966     }
967     OutStreamer.AddBlankLine();
968     return;
969   }
970 
971   const MCSection *StubSection =
972     OutContext.getMachOSection("__TEXT","__symbol_stub1",
973                                MCSectionMachO::S_SYMBOL_STUBS |
974                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
975                                16, SectionKind::getText());
976   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
977     MCSymbol *Stub = Stubs[i].first;
978     MCSymbol *RawSym = Stubs[i].second.getPointer();
979     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
980     const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
981 
982     OutStreamer.SwitchSection(StubSection);
983     EmitAlignment(4);
984     OutStreamer.EmitLabel(Stub);
985     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
986 
987     // lis r11, ha16(LazyPtr)
988     const MCExpr *LazyPtrHa16 = PPCMCExpr::CreateHa(LazyPtrExpr, OutContext);
989     OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
990       .addReg(PPC::R11)
991       .addExpr(LazyPtrHa16));
992 
993     // ldu r12, lo16(LazyPtr)(r11)
994     // lwzu r12, lo16(LazyPtr)(r11)
995     const MCExpr *LazyPtrLo16 = PPCMCExpr::CreateLo(LazyPtrExpr, OutContext);
996     OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
997       .addReg(PPC::R12)
998       .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
999       .addReg(PPC::R11));
1000 
1001     // mtctr r12
1002     OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
1003     // bctr
1004     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
1005 
1006     OutStreamer.SwitchSection(LSPSection);
1007     OutStreamer.EmitLabel(LazyPtr);
1008     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
1009 
1010     MCSymbol *DyldStubBindingHelper =
1011       OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
1012     if (isPPC64) {
1013       // .quad dyld_stub_binding_helper
1014       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
1015     } else {
1016       // .long dyld_stub_binding_helper
1017       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
1018     }
1019   }
1020 
1021   OutStreamer.AddBlankLine();
1022 }
1023 
1024 
1025 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1026   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
1027 
1028   // Darwin/PPC always uses mach-o.
1029   const TargetLoweringObjectFileMachO &TLOFMacho =
1030     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1031   MachineModuleInfoMachO &MMIMacho =
1032     MMI->getObjFileInfo<MachineModuleInfoMachO>();
1033 
1034   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
1035   if (!Stubs.empty())
1036     EmitFunctionStubs(Stubs);
1037 
1038   if (MAI->doesSupportExceptionHandling() && MMI) {
1039     // Add the (possibly multiple) personalities to the set of global values.
1040     // Only referenced functions get into the Personalities list.
1041     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
1042     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
1043          E = Personalities.end(); I != E; ++I) {
1044       if (*I) {
1045         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
1046         MachineModuleInfoImpl::StubValueTy &StubSym =
1047           MMIMacho.getGVStubEntry(NLPSym);
1048         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
1049       }
1050     }
1051   }
1052 
1053   // Output stubs for dynamically-linked functions.
1054   Stubs = MMIMacho.GetGVStubList();
1055 
1056   // Output macho stubs for external and common global variables.
1057   if (!Stubs.empty()) {
1058     // Switch with ".non_lazy_symbol_pointer" directive.
1059     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1060     EmitAlignment(isPPC64 ? 3 : 2);
1061 
1062     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1063       // L_foo$stub:
1064       OutStreamer.EmitLabel(Stubs[i].first);
1065       //   .indirect_symbol _foo
1066       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1067       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
1068 
1069       if (MCSym.getInt())
1070         // External to current translation unit.
1071         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
1072       else
1073         // Internal to current translation unit.
1074         //
1075         // When we place the LSDA into the TEXT section, the type info pointers
1076         // need to be indirect and pc-rel. We accomplish this by using NLPs.
1077         // However, sometimes the types are local to the file. So we need to
1078         // fill in the value for the NLP in those cases.
1079         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1080                                                       OutContext),
1081                               isPPC64 ? 8 : 4/*size*/);
1082     }
1083 
1084     Stubs.clear();
1085     OutStreamer.AddBlankLine();
1086   }
1087 
1088   Stubs = MMIMacho.GetHiddenGVStubList();
1089   if (!Stubs.empty()) {
1090     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1091     EmitAlignment(isPPC64 ? 3 : 2);
1092 
1093     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1094       // L_foo$stub:
1095       OutStreamer.EmitLabel(Stubs[i].first);
1096       //   .long _foo
1097       OutStreamer.EmitValue(MCSymbolRefExpr::
1098                             Create(Stubs[i].second.getPointer(),
1099                                    OutContext),
1100                             isPPC64 ? 8 : 4/*size*/);
1101     }
1102 
1103     Stubs.clear();
1104     OutStreamer.AddBlankLine();
1105   }
1106 
1107   // Funny Darwin hack: This flag tells the linker that no global symbols
1108   // contain code that falls through to other global symbols (e.g. the obvious
1109   // implementation of multiple entry points).  If this doesn't occur, the
1110   // linker can safely perform dead code stripping.  Since LLVM never generates
1111   // code that does this, it is always safe to set.
1112   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1113 
1114   return AsmPrinter::doFinalization(M);
1115 }
1116 
1117 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1118 /// for a MachineFunction to the given output stream, in a format that the
1119 /// Darwin assembler can deal with.
1120 ///
1121 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
1122                                            MCStreamer &Streamer) {
1123   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
1124 
1125   if (Subtarget->isDarwin())
1126     return new PPCDarwinAsmPrinter(tm, Streamer);
1127   return new PPCLinuxAsmPrinter(tm, Streamer);
1128 }
1129 
1130 // Force static initialization.
1131 extern "C" void LLVMInitializePowerPCAsmPrinter() {
1132   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
1133   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
1134 }
1135