PPCAsmPrinter.cpp revision 68ca56285f9b6e82eb16ff8ea02a301f2c489fae
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  return AsmPrinter::doFinalization(M);
772}
773
774/// EmitFunctionBodyEnd - Print the traceback table before the .size
775/// directive.
776///
777void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
778  // Only the 64-bit target requires a traceback table.  For now,
779  // we only emit the word of zeroes that GDB requires to find
780  // the end of the function, and zeroes for the eight-byte
781  // mandatory fields.
782  // FIXME: We should fill in the eight-byte mandatory fields as described in
783  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
784  // currently make use of these fields).
785  if (Subtarget.isPPC64()) {
786    OutStreamer.EmitIntValue(0, 4/*size*/);
787    OutStreamer.EmitIntValue(0, 8/*size*/);
788  }
789}
790
791void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
792  static const char *const CPUDirectives[] = {
793    "",
794    "ppc",
795    "ppc440",
796    "ppc601",
797    "ppc602",
798    "ppc603",
799    "ppc7400",
800    "ppc750",
801    "ppc970",
802    "ppcA2",
803    "ppce500mc",
804    "ppce5500",
805    "power6",
806    "power7",
807    "ppc64"
808  };
809
810  unsigned Directive = Subtarget.getDarwinDirective();
811  if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
812    Directive = PPC::DIR_970;
813  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
814    Directive = PPC::DIR_7400;
815  if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
816    Directive = PPC::DIR_64;
817  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
818
819  // FIXME: This is a total hack, finish mc'izing the PPC backend.
820  if (OutStreamer.hasRawTextSupport())
821    OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
822
823  // Prime text sections so they are adjacent.  This reduces the likelihood a
824  // large data or debug section causes a branch to exceed 16M limit.
825  const TargetLoweringObjectFileMachO &TLOFMacho =
826    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
827  OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
828  if (TM.getRelocationModel() == Reloc::PIC_) {
829    OutStreamer.SwitchSection(
830           OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
831                                      MCSectionMachO::S_SYMBOL_STUBS |
832                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
833                                      32, SectionKind::getText()));
834  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
835    OutStreamer.SwitchSection(
836           OutContext.getMachOSection("__TEXT","__symbol_stub1",
837                                      MCSectionMachO::S_SYMBOL_STUBS |
838                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
839                                      16, SectionKind::getText()));
840  }
841  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
842}
843
844static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
845  // Remove $stub suffix, add $lazy_ptr.
846  StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
847  return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
848}
849
850static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
851  // Add $tmp suffix to $stub, yielding $stub$tmp.
852  return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
853}
854
855void PPCDarwinAsmPrinter::
856EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
857  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
858
859  const TargetLoweringObjectFileMachO &TLOFMacho =
860    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
861
862  // .lazy_symbol_pointer
863  const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
864
865  // Output stubs for dynamically-linked functions
866  if (TM.getRelocationModel() == Reloc::PIC_) {
867    const MCSection *StubSection =
868    OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
869                               MCSectionMachO::S_SYMBOL_STUBS |
870                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
871                               32, SectionKind::getText());
872    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
873      OutStreamer.SwitchSection(StubSection);
874      EmitAlignment(4);
875
876      MCSymbol *Stub = Stubs[i].first;
877      MCSymbol *RawSym = Stubs[i].second.getPointer();
878      MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
879      MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
880
881      OutStreamer.EmitLabel(Stub);
882      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
883
884      // mflr r0
885      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
886      // FIXME: MCize this.
887      OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
888      OutStreamer.EmitLabel(AnonSymbol);
889      // mflr r11
890      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
891      // addis r11, r11, ha16(LazyPtr - AnonSymbol)
892      const MCExpr *Sub =
893        MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
894                                MCSymbolRefExpr::Create(AnonSymbol, OutContext),
895                                OutContext);
896      OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
897        .addReg(PPC::R11)
898        .addReg(PPC::R11)
899        .addExpr(Sub));
900      // mtlr r0
901      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
902
903      // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
904      // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
905      OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
906        .addReg(PPC::R12)
907        .addExpr(Sub).addExpr(Sub)
908        .addReg(PPC::R11));
909      // mtctr r12
910      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
911      // bctr
912      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
913
914      OutStreamer.SwitchSection(LSPSection);
915      OutStreamer.EmitLabel(LazyPtr);
916      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
917
918      MCSymbol *DyldStubBindingHelper =
919        OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
920      if (isPPC64) {
921        // .quad dyld_stub_binding_helper
922        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
923      } else {
924        // .long dyld_stub_binding_helper
925        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
926      }
927    }
928    OutStreamer.AddBlankLine();
929    return;
930  }
931
932  const MCSection *StubSection =
933    OutContext.getMachOSection("__TEXT","__symbol_stub1",
934                               MCSectionMachO::S_SYMBOL_STUBS |
935                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
936                               16, SectionKind::getText());
937  for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
938    MCSymbol *Stub = Stubs[i].first;
939    MCSymbol *RawSym = Stubs[i].second.getPointer();
940    MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
941
942    OutStreamer.SwitchSection(StubSection);
943    EmitAlignment(4);
944    OutStreamer.EmitLabel(Stub);
945    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
946    // lis r11, ha16(LazyPtr)
947    const MCExpr *LazyPtrHa16 =
948      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
949                              OutContext);
950    OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
951      .addReg(PPC::R11)
952      .addExpr(LazyPtrHa16));
953
954    const MCExpr *LazyPtrLo16 =
955      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
956                              OutContext);
957    // ldu r12, lo16(LazyPtr)(r11)
958    // lwzu r12, lo16(LazyPtr)(r11)
959    OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
960      .addReg(PPC::R12)
961      .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
962      .addReg(PPC::R11));
963
964    // mtctr r12
965    OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
966    // bctr
967    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
968
969    OutStreamer.SwitchSection(LSPSection);
970    OutStreamer.EmitLabel(LazyPtr);
971    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
972
973    MCSymbol *DyldStubBindingHelper =
974      OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
975    if (isPPC64) {
976      // .quad dyld_stub_binding_helper
977      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
978    } else {
979      // .long dyld_stub_binding_helper
980      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
981    }
982  }
983
984  OutStreamer.AddBlankLine();
985}
986
987
988bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
989  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
990
991  // Darwin/PPC always uses mach-o.
992  const TargetLoweringObjectFileMachO &TLOFMacho =
993    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
994  MachineModuleInfoMachO &MMIMacho =
995    MMI->getObjFileInfo<MachineModuleInfoMachO>();
996
997  MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
998  if (!Stubs.empty())
999    EmitFunctionStubs(Stubs);
1000
1001  if (MAI->doesSupportExceptionHandling() && MMI) {
1002    // Add the (possibly multiple) personalities to the set of global values.
1003    // Only referenced functions get into the Personalities list.
1004    const std::vector<const Function*> &Personalities = MMI->getPersonalities();
1005    for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
1006         E = Personalities.end(); I != E; ++I) {
1007      if (*I) {
1008        MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
1009        MachineModuleInfoImpl::StubValueTy &StubSym =
1010          MMIMacho.getGVStubEntry(NLPSym);
1011        StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
1012      }
1013    }
1014  }
1015
1016  // Output stubs for dynamically-linked functions.
1017  Stubs = MMIMacho.GetGVStubList();
1018
1019  // Output macho stubs for external and common global variables.
1020  if (!Stubs.empty()) {
1021    // Switch with ".non_lazy_symbol_pointer" directive.
1022    OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1023    EmitAlignment(isPPC64 ? 3 : 2);
1024
1025    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1026      // L_foo$stub:
1027      OutStreamer.EmitLabel(Stubs[i].first);
1028      //   .indirect_symbol _foo
1029      MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1030      OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
1031
1032      if (MCSym.getInt())
1033        // External to current translation unit.
1034        OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
1035      else
1036        // Internal to current translation unit.
1037        //
1038        // When we place the LSDA into the TEXT section, the type info pointers
1039        // need to be indirect and pc-rel. We accomplish this by using NLPs.
1040        // However, sometimes the types are local to the file. So we need to
1041        // fill in the value for the NLP in those cases.
1042        OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1043                                                      OutContext),
1044                              isPPC64 ? 8 : 4/*size*/);
1045    }
1046
1047    Stubs.clear();
1048    OutStreamer.AddBlankLine();
1049  }
1050
1051  Stubs = MMIMacho.GetHiddenGVStubList();
1052  if (!Stubs.empty()) {
1053    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1054    EmitAlignment(isPPC64 ? 3 : 2);
1055
1056    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1057      // L_foo$stub:
1058      OutStreamer.EmitLabel(Stubs[i].first);
1059      //   .long _foo
1060      OutStreamer.EmitValue(MCSymbolRefExpr::
1061                            Create(Stubs[i].second.getPointer(),
1062                                   OutContext),
1063                            isPPC64 ? 8 : 4/*size*/);
1064    }
1065
1066    Stubs.clear();
1067    OutStreamer.AddBlankLine();
1068  }
1069
1070  // Funny Darwin hack: This flag tells the linker that no global symbols
1071  // contain code that falls through to other global symbols (e.g. the obvious
1072  // implementation of multiple entry points).  If this doesn't occur, the
1073  // linker can safely perform dead code stripping.  Since LLVM never generates
1074  // code that does this, it is always safe to set.
1075  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1076
1077  return AsmPrinter::doFinalization(M);
1078}
1079
1080/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1081/// for a MachineFunction to the given output stream, in a format that the
1082/// Darwin assembler can deal with.
1083///
1084static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
1085                                           MCStreamer &Streamer) {
1086  const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
1087
1088  if (Subtarget->isDarwin())
1089    return new PPCDarwinAsmPrinter(tm, Streamer);
1090  return new PPCLinuxAsmPrinter(tm, Streamer);
1091}
1092
1093// Force static initialization.
1094extern "C" void LLVMInitializePowerPCAsmPrinter() {
1095  TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
1096  TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
1097}
1098