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