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