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