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