PPCAsmPrinter.cpp revision b516e9b64850e0e1a50f680fd1443ac12e56557b
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"
59using namespace llvm;
60
61namespace {
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.
139static 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
150void 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///
248bool 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
286bool 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.
317MCSymbol *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///
336void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
337  MCInst TmpInst;
338
339  // Lower multi-instruction pseudo operations.
340  switch (MI->getOpcode()) {
341  default: break;
342  case TargetOpcode::DBG_VALUE: {
343    if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
344
345    SmallString<32> Str;
346    raw_svector_ostream O(Str);
347    unsigned NOps = MI->getNumOperands();
348    assert(NOps==4);
349    O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
350    // cast away const; DIetc do not take const operands for some reason.
351    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
352    O << V.getName();
353    O << " <- ";
354    // Frame address.  Currently handles register +- offset only.
355    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
356    O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
357    O << ']';
358    O << "+";
359    printOperand(MI, NOps-2, O);
360    OutStreamer.EmitRawText(O.str());
361    return;
362  }
363
364  case PPC::MovePCtoLR:
365  case PPC::MovePCtoLR8: {
366    // Transform %LR = MovePCtoLR
367    // Into this, where the label is the PIC base:
368    //     bl L1$pb
369    // L1$pb:
370    MCSymbol *PICBase = MF->getPICBaseSymbol();
371
372    // Emit the 'bl'.
373    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
374      // FIXME: We would like an efficient form for this, so we don't have to do
375      // a lot of extra uniquing.
376      .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
377
378    // Emit the label.
379    OutStreamer.EmitLabel(PICBase);
380    return;
381  }
382  case PPC::LDtocJTI:
383  case PPC::LDtocCPT:
384  case PPC::LDtoc: {
385    // Transform %X3 = LDtoc <ga:@min1>, %X2
386    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
387
388    // Change the opcode to LD, and the global address operand to be a
389    // reference to the TOC entry we will synthesize later.
390    TmpInst.setOpcode(PPC::LD);
391    const MachineOperand &MO = MI->getOperand(1);
392
393    // Map symbol -> label of TOC entry
394    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
395    MCSymbol *MOSymbol = 0;
396    if (MO.isGlobal())
397      MOSymbol = Mang->getSymbol(MO.getGlobal());
398    else if (MO.isCPI())
399      MOSymbol = GetCPISymbol(MO.getIndex());
400    else if (MO.isJTI())
401      MOSymbol = GetJTISymbol(MO.getIndex());
402
403    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
404
405    const MCExpr *Exp =
406      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
407                              OutContext);
408    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
409    OutStreamer.EmitInstruction(TmpInst);
410    return;
411  }
412
413  case PPC::ADDIStocHA: {
414    // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
415    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
416
417    // Change the opcode to ADDIS8.  If the global address is external,
418    // has common linkage, is a function address, or is a jump table
419    // address, then generate a TOC entry and reference that.  Otherwise
420    // reference the symbol directly.
421    TmpInst.setOpcode(PPC::ADDIS8);
422    const MachineOperand &MO = MI->getOperand(2);
423    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
424           "Invalid operand for ADDIStocHA!");
425    MCSymbol *MOSymbol = 0;
426    bool IsExternal = false;
427    bool IsFunction = false;
428    bool IsCommon = false;
429    bool IsAvailExt = false;
430
431    if (MO.isGlobal()) {
432      const GlobalValue *GValue = MO.getGlobal();
433      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
434      const GlobalValue *RealGValue = GAlias ?
435        GAlias->resolveAliasedGlobal(false) : GValue;
436      MOSymbol = Mang->getSymbol(RealGValue);
437      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
438      IsExternal = GVar && !GVar->hasInitializer();
439      IsCommon = GVar && RealGValue->hasCommonLinkage();
440      IsFunction = !GVar;
441      IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
442    } else if (MO.isCPI())
443      MOSymbol = GetCPISymbol(MO.getIndex());
444    else if (MO.isJTI())
445      MOSymbol = GetJTISymbol(MO.getIndex());
446
447    if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
448      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
449
450    const MCExpr *Exp =
451      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA,
452                              OutContext);
453    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
454    OutStreamer.EmitInstruction(TmpInst);
455    return;
456  }
457  case PPC::LDtocL: {
458    // Transform %Xd = LDtocL <ga:@sym>, %Xs
459    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
460
461    // Change the opcode to LDrs, which is a form of LD with the offset
462    // specified by a SymbolLo.  If the global address is external, has
463    // common linkage, or is a jump table address, then reference the
464    // associated TOC entry.  Otherwise reference the symbol directly.
465    TmpInst.setOpcode(PPC::LDrs);
466    const MachineOperand &MO = MI->getOperand(1);
467    assert((MO.isGlobal() || MO.isJTI()) && "Invalid operand for LDtocL!");
468    MCSymbol *MOSymbol = 0;
469
470    if (MO.isJTI())
471      MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
472    else {
473      const GlobalValue *GValue = MO.getGlobal();
474      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
475      const GlobalValue *RealGValue = GAlias ?
476        GAlias->resolveAliasedGlobal(false) : GValue;
477      MOSymbol = Mang->getSymbol(RealGValue);
478      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
479
480      if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() ||
481          RealGValue->hasAvailableExternallyLinkage())
482        MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
483    }
484
485    const MCExpr *Exp =
486      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
487                              OutContext);
488    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
489    OutStreamer.EmitInstruction(TmpInst);
490    return;
491  }
492  case PPC::ADDItocL: {
493    // Transform %Xd = ADDItocL %Xs, <ga:@sym>
494    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
495
496    // Change the opcode to ADDI8L.  If the global address is external, then
497    // generate a TOC entry and reference that.  Otherwise reference the
498    // symbol directly.
499    TmpInst.setOpcode(PPC::ADDI8L);
500    const MachineOperand &MO = MI->getOperand(2);
501    assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
502    MCSymbol *MOSymbol = 0;
503    bool IsExternal = false;
504    bool IsFunction = false;
505
506    if (MO.isGlobal()) {
507      const GlobalValue *GValue = MO.getGlobal();
508      const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
509      const GlobalValue *RealGValue = GAlias ?
510        GAlias->resolveAliasedGlobal(false) : GValue;
511      MOSymbol = Mang->getSymbol(RealGValue);
512      const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
513      IsExternal = GVar && !GVar->hasInitializer();
514      IsFunction = !GVar;
515    } else if (MO.isCPI())
516      MOSymbol = GetCPISymbol(MO.getIndex());
517
518    if (IsFunction || IsExternal)
519      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
520
521    const MCExpr *Exp =
522      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
523                              OutContext);
524    TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
525    OutStreamer.EmitInstruction(TmpInst);
526    return;
527  }
528  case PPC::ADDISgotTprelHA: {
529    // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
530    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
531    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
532    const MachineOperand &MO = MI->getOperand(2);
533    const GlobalValue *GValue = MO.getGlobal();
534    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
535    const MCExpr *SymGotTprel =
536      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA,
537                              OutContext);
538    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
539                                .addReg(MI->getOperand(0).getReg())
540                                .addReg(PPC::X2)
541                                .addExpr(SymGotTprel));
542    return;
543  }
544  case PPC::LDgotTprelL: {
545    // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
546    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
547
548    // Change the opcode to LDrs, which is a form of LD with the offset
549    // specified by a SymbolLo.
550    TmpInst.setOpcode(PPC::LDrs);
551    const MachineOperand &MO = MI->getOperand(1);
552    const GlobalValue *GValue = MO.getGlobal();
553    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
554    const MCExpr *Exp =
555      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO,
556                              OutContext);
557    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
558    OutStreamer.EmitInstruction(TmpInst);
559    return;
560  }
561  case PPC::ADDIStlsgdHA: {
562    // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
563    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
564    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
565    const MachineOperand &MO = MI->getOperand(2);
566    const GlobalValue *GValue = MO.getGlobal();
567    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
568    const MCExpr *SymGotTlsGD =
569      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA,
570                              OutContext);
571    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
572                                .addReg(MI->getOperand(0).getReg())
573                                .addReg(PPC::X2)
574                                .addExpr(SymGotTlsGD));
575    return;
576  }
577  case PPC::ADDItlsgdL: {
578    // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
579    // Into:      %Xd = ADDI8L %Xs, sym@got@tlsgd@l
580    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
581    const MachineOperand &MO = MI->getOperand(2);
582    const GlobalValue *GValue = MO.getGlobal();
583    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
584    const MCExpr *SymGotTlsGD =
585      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO,
586                              OutContext);
587    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
588                                .addReg(MI->getOperand(0).getReg())
589                                .addReg(MI->getOperand(1).getReg())
590                                .addExpr(SymGotTlsGD));
591    return;
592  }
593  case PPC::GETtlsADDR: {
594    // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
595    // Into:      BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd)
596    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
597
598    StringRef Name = "__tls_get_addr";
599    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
600    const MCSymbolRefExpr *TlsRef =
601      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
602    const MachineOperand &MO = MI->getOperand(2);
603    const GlobalValue *GValue = MO.getGlobal();
604    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
605    const MCExpr *SymVar =
606      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
607                              OutContext);
608    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD)
609                                .addExpr(TlsRef)
610                                .addExpr(SymVar));
611    return;
612  }
613  case PPC::ADDIStlsldHA: {
614    // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
615    // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
616    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
617    const MachineOperand &MO = MI->getOperand(2);
618    const GlobalValue *GValue = MO.getGlobal();
619    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
620    const MCExpr *SymGotTlsLD =
621      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA,
622                              OutContext);
623    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
624                                .addReg(MI->getOperand(0).getReg())
625                                .addReg(PPC::X2)
626                                .addExpr(SymGotTlsLD));
627    return;
628  }
629  case PPC::ADDItlsldL: {
630    // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
631    // Into:      %Xd = ADDI8L %Xs, sym@got@tlsld@l
632    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
633    const MachineOperand &MO = MI->getOperand(2);
634    const GlobalValue *GValue = MO.getGlobal();
635    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
636    const MCExpr *SymGotTlsLD =
637      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO,
638                              OutContext);
639    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
640                                .addReg(MI->getOperand(0).getReg())
641                                .addReg(MI->getOperand(1).getReg())
642                                .addExpr(SymGotTlsLD));
643    return;
644  }
645  case PPC::GETtlsldADDR: {
646    // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
647    // Into:      BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld)
648    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
649
650    StringRef Name = "__tls_get_addr";
651    MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
652    const MCSymbolRefExpr *TlsRef =
653      MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
654    const MachineOperand &MO = MI->getOperand(2);
655    const GlobalValue *GValue = MO.getGlobal();
656    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
657    const MCExpr *SymVar =
658      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
659                              OutContext);
660    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD)
661                                .addExpr(TlsRef)
662                                .addExpr(SymVar));
663    return;
664  }
665  case PPC::ADDISdtprelHA: {
666    // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
667    // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
668    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
669    const MachineOperand &MO = MI->getOperand(2);
670    const GlobalValue *GValue = MO.getGlobal();
671    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
672    const MCExpr *SymDtprel =
673      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA,
674                              OutContext);
675    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
676                                .addReg(MI->getOperand(0).getReg())
677                                .addReg(PPC::X3)
678                                .addExpr(SymDtprel));
679    return;
680  }
681  case PPC::ADDIdtprelL: {
682    // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
683    // Into:      %Xd = ADDI8L %Xs, sym@dtprel@l
684    assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
685    const MachineOperand &MO = MI->getOperand(2);
686    const GlobalValue *GValue = MO.getGlobal();
687    MCSymbol *MOSymbol = Mang->getSymbol(GValue);
688    const MCExpr *SymDtprel =
689      MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO,
690                              OutContext);
691    OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
692                                .addReg(MI->getOperand(0).getReg())
693                                .addReg(MI->getOperand(1).getReg())
694                                .addExpr(SymDtprel));
695    return;
696  }
697  case PPC::MFCRpseud:
698  case PPC::MFCR8pseud:
699    // Transform: %R3 = MFCRpseud %CR7
700    // Into:      %R3 = MFCR      ;; cr7
701    OutStreamer.AddComment(PPCInstPrinter::
702                           getRegisterName(MI->getOperand(1).getReg()));
703    OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
704      .addReg(MI->getOperand(0).getReg()));
705    return;
706  case PPC::SYNC:
707    // In Book E sync is called msync, handle this special case here...
708    if (Subtarget.isBookE()) {
709      OutStreamer.EmitRawText(StringRef("\tmsync"));
710      return;
711    }
712  }
713
714  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
715  OutStreamer.EmitInstruction(TmpInst);
716}
717
718void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
719  if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
720    return AsmPrinter::EmitFunctionEntryLabel();
721
722  // Emit an official procedure descriptor.
723  const MCSection *Current = OutStreamer.getCurrentSection();
724  const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
725      ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
726      SectionKind::getReadOnly());
727  OutStreamer.SwitchSection(Section);
728  OutStreamer.EmitLabel(CurrentFnSym);
729  OutStreamer.EmitValueToAlignment(8);
730  MCSymbol *Symbol1 =
731    OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
732  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
733  // entry point.
734  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
735			8 /*size*/);
736  MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
737  // Generates a R_PPC64_TOC relocation for TOC base insertion.
738  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
739                        MCSymbolRefExpr::VK_PPC_TOC, OutContext),
740                        8/*size*/);
741  // Emit a null environment pointer.
742  OutStreamer.EmitIntValue(0, 8 /* size */);
743  OutStreamer.SwitchSection(Current);
744
745  MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
746                          ".L." + Twine(CurrentFnSym->getName()));
747  OutStreamer.EmitLabel(RealFnSym);
748  CurrentFnSymForSize = RealFnSym;
749}
750
751
752bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
753  const DataLayout *TD = TM.getDataLayout();
754
755  bool isPPC64 = TD->getPointerSizeInBits() == 64;
756
757  if (isPPC64 && !TOC.empty()) {
758    const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
759        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
760        SectionKind::getReadOnly());
761    OutStreamer.SwitchSection(Section);
762
763    for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
764         E = TOC.end(); I != E; ++I) {
765      OutStreamer.EmitLabel(I->second);
766      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
767      OutStreamer.EmitTCEntry(*S);
768    }
769  }
770
771  MachineModuleInfoELF &MMIELF =
772    MMI->getObjFileInfo<MachineModuleInfoELF>();
773
774  MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
775  if (!Stubs.empty()) {
776    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
777    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
778      // L_foo$stub:
779      OutStreamer.EmitLabel(Stubs[i].first);
780      //   .long _foo
781      OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
782                                                    OutContext),
783                            isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
784    }
785
786    Stubs.clear();
787    OutStreamer.AddBlankLine();
788  }
789
790  return AsmPrinter::doFinalization(M);
791}
792
793/// EmitFunctionBodyEnd - Print the traceback table before the .size
794/// directive.
795///
796void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
797  // Only the 64-bit target requires a traceback table.  For now,
798  // we only emit the word of zeroes that GDB requires to find
799  // the end of the function, and zeroes for the eight-byte
800  // mandatory fields.
801  // FIXME: We should fill in the eight-byte mandatory fields as described in
802  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
803  // currently make use of these fields).
804  if (Subtarget.isPPC64()) {
805    OutStreamer.EmitIntValue(0, 4/*size*/);
806    OutStreamer.EmitIntValue(0, 8/*size*/);
807  }
808}
809
810void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
811  static const char *const CPUDirectives[] = {
812    "",
813    "ppc",
814    "ppc440",
815    "ppc601",
816    "ppc602",
817    "ppc603",
818    "ppc7400",
819    "ppc750",
820    "ppc970",
821    "ppcA2",
822    "ppce500mc",
823    "ppce5500",
824    "power3",
825    "power4",
826    "power5",
827    "power5x",
828    "power6",
829    "power6x",
830    "power7",
831    "ppc64"
832  };
833
834  unsigned Directive = Subtarget.getDarwinDirective();
835  if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
836    Directive = PPC::DIR_970;
837  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
838    Directive = PPC::DIR_7400;
839  if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
840    Directive = PPC::DIR_64;
841  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
842
843  // FIXME: This is a total hack, finish mc'izing the PPC backend.
844  if (OutStreamer.hasRawTextSupport())
845    OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
846
847  // Prime text sections so they are adjacent.  This reduces the likelihood a
848  // large data or debug section causes a branch to exceed 16M limit.
849  const TargetLoweringObjectFileMachO &TLOFMacho =
850    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
851  OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
852  if (TM.getRelocationModel() == Reloc::PIC_) {
853    OutStreamer.SwitchSection(
854           OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
855                                      MCSectionMachO::S_SYMBOL_STUBS |
856                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
857                                      32, SectionKind::getText()));
858  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
859    OutStreamer.SwitchSection(
860           OutContext.getMachOSection("__TEXT","__symbol_stub1",
861                                      MCSectionMachO::S_SYMBOL_STUBS |
862                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
863                                      16, SectionKind::getText()));
864  }
865  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
866}
867
868static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
869  // Remove $stub suffix, add $lazy_ptr.
870  StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
871  return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
872}
873
874static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
875  // Add $tmp suffix to $stub, yielding $stub$tmp.
876  return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
877}
878
879void PPCDarwinAsmPrinter::
880EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
881  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
882
883  const TargetLoweringObjectFileMachO &TLOFMacho =
884    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
885
886  // .lazy_symbol_pointer
887  const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
888
889  // Output stubs for dynamically-linked functions
890  if (TM.getRelocationModel() == Reloc::PIC_) {
891    const MCSection *StubSection =
892    OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
893                               MCSectionMachO::S_SYMBOL_STUBS |
894                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
895                               32, SectionKind::getText());
896    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
897      OutStreamer.SwitchSection(StubSection);
898      EmitAlignment(4);
899
900      MCSymbol *Stub = Stubs[i].first;
901      MCSymbol *RawSym = Stubs[i].second.getPointer();
902      MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
903      MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
904
905      OutStreamer.EmitLabel(Stub);
906      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
907
908      // mflr r0
909      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
910      // FIXME: MCize this.
911      OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
912      OutStreamer.EmitLabel(AnonSymbol);
913      // mflr r11
914      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
915      // addis r11, r11, ha16(LazyPtr - AnonSymbol)
916      const MCExpr *Sub =
917        MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
918                                MCSymbolRefExpr::Create(AnonSymbol, OutContext),
919                                OutContext);
920      OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
921        .addReg(PPC::R11)
922        .addReg(PPC::R11)
923        .addExpr(Sub));
924      // mtlr r0
925      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
926
927      // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
928      // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
929      OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
930        .addReg(PPC::R12)
931        .addExpr(Sub).addExpr(Sub)
932        .addReg(PPC::R11));
933      // mtctr r12
934      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
935      // bctr
936      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
937
938      OutStreamer.SwitchSection(LSPSection);
939      OutStreamer.EmitLabel(LazyPtr);
940      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
941
942      MCSymbol *DyldStubBindingHelper =
943        OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
944      if (isPPC64) {
945        // .quad dyld_stub_binding_helper
946        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
947      } else {
948        // .long dyld_stub_binding_helper
949        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
950      }
951    }
952    OutStreamer.AddBlankLine();
953    return;
954  }
955
956  const MCSection *StubSection =
957    OutContext.getMachOSection("__TEXT","__symbol_stub1",
958                               MCSectionMachO::S_SYMBOL_STUBS |
959                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
960                               16, SectionKind::getText());
961  for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
962    MCSymbol *Stub = Stubs[i].first;
963    MCSymbol *RawSym = Stubs[i].second.getPointer();
964    MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
965
966    OutStreamer.SwitchSection(StubSection);
967    EmitAlignment(4);
968    OutStreamer.EmitLabel(Stub);
969    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
970    // lis r11, ha16(LazyPtr)
971    const MCExpr *LazyPtrHa16 =
972      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
973                              OutContext);
974    OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
975      .addReg(PPC::R11)
976      .addExpr(LazyPtrHa16));
977
978    const MCExpr *LazyPtrLo16 =
979      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
980                              OutContext);
981    // ldu r12, lo16(LazyPtr)(r11)
982    // lwzu r12, lo16(LazyPtr)(r11)
983    OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
984      .addReg(PPC::R12)
985      .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
986      .addReg(PPC::R11));
987
988    // mtctr r12
989    OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
990    // bctr
991    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
992
993    OutStreamer.SwitchSection(LSPSection);
994    OutStreamer.EmitLabel(LazyPtr);
995    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
996
997    MCSymbol *DyldStubBindingHelper =
998      OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
999    if (isPPC64) {
1000      // .quad dyld_stub_binding_helper
1001      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
1002    } else {
1003      // .long dyld_stub_binding_helper
1004      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
1005    }
1006  }
1007
1008  OutStreamer.AddBlankLine();
1009}
1010
1011
1012bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1013  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
1014
1015  // Darwin/PPC always uses mach-o.
1016  const TargetLoweringObjectFileMachO &TLOFMacho =
1017    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1018  MachineModuleInfoMachO &MMIMacho =
1019    MMI->getObjFileInfo<MachineModuleInfoMachO>();
1020
1021  MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
1022  if (!Stubs.empty())
1023    EmitFunctionStubs(Stubs);
1024
1025  if (MAI->doesSupportExceptionHandling() && MMI) {
1026    // Add the (possibly multiple) personalities to the set of global values.
1027    // Only referenced functions get into the Personalities list.
1028    const std::vector<const Function*> &Personalities = MMI->getPersonalities();
1029    for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
1030         E = Personalities.end(); I != E; ++I) {
1031      if (*I) {
1032        MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
1033        MachineModuleInfoImpl::StubValueTy &StubSym =
1034          MMIMacho.getGVStubEntry(NLPSym);
1035        StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
1036      }
1037    }
1038  }
1039
1040  // Output stubs for dynamically-linked functions.
1041  Stubs = MMIMacho.GetGVStubList();
1042
1043  // Output macho stubs for external and common global variables.
1044  if (!Stubs.empty()) {
1045    // Switch with ".non_lazy_symbol_pointer" directive.
1046    OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1047    EmitAlignment(isPPC64 ? 3 : 2);
1048
1049    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1050      // L_foo$stub:
1051      OutStreamer.EmitLabel(Stubs[i].first);
1052      //   .indirect_symbol _foo
1053      MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1054      OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
1055
1056      if (MCSym.getInt())
1057        // External to current translation unit.
1058        OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
1059      else
1060        // Internal to current translation unit.
1061        //
1062        // When we place the LSDA into the TEXT section, the type info pointers
1063        // need to be indirect and pc-rel. We accomplish this by using NLPs.
1064        // However, sometimes the types are local to the file. So we need to
1065        // fill in the value for the NLP in those cases.
1066        OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1067                                                      OutContext),
1068                              isPPC64 ? 8 : 4/*size*/);
1069    }
1070
1071    Stubs.clear();
1072    OutStreamer.AddBlankLine();
1073  }
1074
1075  Stubs = MMIMacho.GetHiddenGVStubList();
1076  if (!Stubs.empty()) {
1077    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1078    EmitAlignment(isPPC64 ? 3 : 2);
1079
1080    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1081      // L_foo$stub:
1082      OutStreamer.EmitLabel(Stubs[i].first);
1083      //   .long _foo
1084      OutStreamer.EmitValue(MCSymbolRefExpr::
1085                            Create(Stubs[i].second.getPointer(),
1086                                   OutContext),
1087                            isPPC64 ? 8 : 4/*size*/);
1088    }
1089
1090    Stubs.clear();
1091    OutStreamer.AddBlankLine();
1092  }
1093
1094  // Funny Darwin hack: This flag tells the linker that no global symbols
1095  // contain code that falls through to other global symbols (e.g. the obvious
1096  // implementation of multiple entry points).  If this doesn't occur, the
1097  // linker can safely perform dead code stripping.  Since LLVM never generates
1098  // code that does this, it is always safe to set.
1099  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1100
1101  return AsmPrinter::doFinalization(M);
1102}
1103
1104/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1105/// for a MachineFunction to the given output stream, in a format that the
1106/// Darwin assembler can deal with.
1107///
1108static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
1109                                           MCStreamer &Streamer) {
1110  const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
1111
1112  if (Subtarget->isDarwin())
1113    return new PPCDarwinAsmPrinter(tm, Streamer);
1114  return new PPCLinuxAsmPrinter(tm, Streamer);
1115}
1116
1117// Force static initialization.
1118extern "C" void LLVMInitializePowerPCAsmPrinter() {
1119  TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
1120  TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
1121}
1122