PPCAsmPrinter.cpp revision ed9e442cf098663ce213cb16778b44be466b441f
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 "PPCTargetMachine.h"
22#include "PPCSubtarget.h"
23#include "InstPrinter/PPCInstPrinter.h"
24#include "MCTargetDesc/PPCPredicates.h"
25#include "llvm/Constants.h"
26#include "llvm/DebugInfo.h"
27#include "llvm/DerivedTypes.h"
28#include "llvm/Module.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/MC/MCAsmInfo.h"
37#include "llvm/MC/MCContext.h"
38#include "llvm/MC/MCExpr.h"
39#include "llvm/MC/MCInst.h"
40#include "llvm/MC/MCInstBuilder.h"
41#include "llvm/MC/MCSectionMachO.h"
42#include "llvm/MC/MCStreamer.h"
43#include "llvm/MC/MCSymbol.h"
44#include "llvm/MC/MCSectionELF.h"
45#include "llvm/Target/Mangler.h"
46#include "llvm/Target/TargetRegisterInfo.h"
47#include "llvm/Target/TargetInstrInfo.h"
48#include "llvm/Target/TargetOptions.h"
49#include "llvm/Support/CommandLine.h"
50#include "llvm/Support/Debug.h"
51#include "llvm/Support/MathExtras.h"
52#include "llvm/Support/ErrorHandling.h"
53#include "llvm/Support/TargetRegistry.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/Support/ELF.h"
56#include "llvm/ADT/StringExtras.h"
57#include "llvm/ADT/SmallString.h"
58#include "llvm/ADT/MapVector.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
77    virtual void EmitInstruction(const MachineInstr *MI);
78
79    void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
80
81    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
82                         unsigned AsmVariant, const char *ExtraCode,
83                         raw_ostream &O);
84    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
85                               unsigned AsmVariant, const char *ExtraCode,
86                               raw_ostream &O);
87
88    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
89      MachineLocation Location;
90      assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
91      // Frame address.  Currently handles register +- offset only.
92      if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
93        Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
94      else {
95        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
96      }
97      return Location;
98    }
99  };
100
101  /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
102  class PPCLinuxAsmPrinter : public PPCAsmPrinter {
103  public:
104    explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
105      : PPCAsmPrinter(TM, Streamer) {}
106
107    virtual const char *getPassName() const {
108      return "Linux PPC Assembly Printer";
109    }
110
111    bool doFinalization(Module &M);
112
113    virtual void EmitFunctionEntryLabel();
114
115    void EmitFunctionBodyEnd();
116  };
117
118  /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
119  /// OS X
120  class PPCDarwinAsmPrinter : public PPCAsmPrinter {
121  public:
122    explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
123      : PPCAsmPrinter(TM, Streamer) {}
124
125    virtual const char *getPassName() const {
126      return "Darwin PPC Assembly Printer";
127    }
128
129    bool doFinalization(Module &M);
130    void EmitStartOfAsmFile(Module &M);
131
132    void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
133  };
134} // end of anonymous namespace
135
136/// stripRegisterPrefix - This method strips the character prefix from a
137/// register name so that only the number is left.  Used by for linux asm.
138static const char *stripRegisterPrefix(const char *RegName) {
139  switch (RegName[0]) {
140    case 'r':
141    case 'f':
142    case 'v': return RegName + 1;
143    case 'c': if (RegName[1] == 'r') return RegName + 2;
144  }
145
146  return RegName;
147}
148
149void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
150                                 raw_ostream &O) {
151  const MachineOperand &MO = MI->getOperand(OpNo);
152
153  switch (MO.getType()) {
154  case MachineOperand::MO_Register: {
155    const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
156    // Linux assembler (Others?) does not take register mnemonics.
157    // FIXME - What about special registers used in mfspr/mtspr?
158    if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
159    O << RegName;
160    return;
161  }
162  case MachineOperand::MO_Immediate:
163    O << MO.getImm();
164    return;
165
166  case MachineOperand::MO_MachineBasicBlock:
167    O << *MO.getMBB()->getSymbol();
168    return;
169  case MachineOperand::MO_JumpTableIndex:
170    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
171      << '_' << MO.getIndex();
172    // FIXME: PIC relocation model
173    return;
174  case MachineOperand::MO_ConstantPoolIndex:
175    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
176      << '_' << MO.getIndex();
177    return;
178  case MachineOperand::MO_BlockAddress:
179    O << *GetBlockAddressSymbol(MO.getBlockAddress());
180    return;
181  case MachineOperand::MO_ExternalSymbol: {
182    // Computing the address of an external symbol, not calling it.
183    if (TM.getRelocationModel() == Reloc::Static) {
184      O << *GetExternalSymbolSymbol(MO.getSymbolName());
185      return;
186    }
187
188    MCSymbol *NLPSym =
189      OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
190                                   MO.getSymbolName()+"$non_lazy_ptr");
191    MachineModuleInfoImpl::StubValueTy &StubSym =
192      MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
193    if (StubSym.getPointer() == 0)
194      StubSym = MachineModuleInfoImpl::
195        StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
196
197    O << *NLPSym;
198    return;
199  }
200  case MachineOperand::MO_GlobalAddress: {
201    // Computing the address of a global symbol, not calling it.
202    const GlobalValue *GV = MO.getGlobal();
203    MCSymbol *SymToPrint;
204
205    // External or weakly linked global variables need non-lazily-resolved stubs
206    if (TM.getRelocationModel() != Reloc::Static &&
207        (GV->isDeclaration() || GV->isWeakForLinker())) {
208      if (!GV->hasHiddenVisibility()) {
209        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
210        MachineModuleInfoImpl::StubValueTy &StubSym =
211          MMI->getObjFileInfo<MachineModuleInfoMachO>()
212            .getGVStubEntry(SymToPrint);
213        if (StubSym.getPointer() == 0)
214          StubSym = MachineModuleInfoImpl::
215            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
216      } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
217                 GV->hasAvailableExternallyLinkage()) {
218        SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
219
220        MachineModuleInfoImpl::StubValueTy &StubSym =
221          MMI->getObjFileInfo<MachineModuleInfoMachO>().
222                    getHiddenGVStubEntry(SymToPrint);
223        if (StubSym.getPointer() == 0)
224          StubSym = MachineModuleInfoImpl::
225            StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
226      } else {
227        SymToPrint = Mang->getSymbol(GV);
228      }
229    } else {
230      SymToPrint = Mang->getSymbol(GV);
231    }
232
233    O << *SymToPrint;
234
235    printOffset(MO.getOffset(), O);
236    return;
237  }
238
239  default:
240    O << "<unknown operand type: " << MO.getType() << ">";
241    return;
242  }
243}
244
245/// PrintAsmOperand - Print out an operand for an inline asm expression.
246///
247bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
248                                    unsigned AsmVariant,
249                                    const char *ExtraCode, raw_ostream &O) {
250  // Does this asm operand have a single letter operand modifier?
251  if (ExtraCode && ExtraCode[0]) {
252    if (ExtraCode[1] != 0) return true; // Unknown modifier.
253
254    switch (ExtraCode[0]) {
255    default:
256      // See if this is a generic print operand
257      return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
258    case 'c': // Don't print "$" before a global var name or constant.
259      break; // PPC never has a prefix.
260    case 'L': // Write second word of DImode reference.
261      // Verify that this operand has two consecutive registers.
262      if (!MI->getOperand(OpNo).isReg() ||
263          OpNo+1 == MI->getNumOperands() ||
264          !MI->getOperand(OpNo+1).isReg())
265        return true;
266      ++OpNo;   // Return the high-part.
267      break;
268    case 'I':
269      // Write 'i' if an integer constant, otherwise nothing.  Used to print
270      // addi vs add, etc.
271      if (MI->getOperand(OpNo).isImm())
272        O << "i";
273      return false;
274    }
275  }
276
277  printOperand(MI, OpNo, O);
278  return false;
279}
280
281// At the moment, all inline asm memory operands are a single register.
282// In any case, the output of this routine should always be just one
283// assembler operand.
284
285bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
286                                          unsigned AsmVariant,
287                                          const char *ExtraCode,
288                                          raw_ostream &O) {
289  if (ExtraCode && ExtraCode[0]) {
290    if (ExtraCode[1] != 0) return true; // Unknown modifier.
291
292    switch (ExtraCode[0]) {
293    default: return true;  // Unknown modifier.
294    case 'y': // A memory reference for an X-form instruction
295      {
296        const char *RegName = "r0";
297        if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
298        O << RegName << ", ";
299        printOperand(MI, OpNo, O);
300        return false;
301      }
302    }
303  }
304
305  assert(MI->getOperand(OpNo).isReg());
306  O << "0(";
307  printOperand(MI, OpNo, O);
308  O << ")";
309  return false;
310}
311
312
313/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
314/// the current output stream.
315///
316void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
317  MCInst TmpInst;
318
319  // Lower multi-instruction pseudo operations.
320  switch (MI->getOpcode()) {
321  default: break;
322  case TargetOpcode::DBG_VALUE: {
323    if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
324
325    SmallString<32> Str;
326    raw_svector_ostream O(Str);
327    unsigned NOps = MI->getNumOperands();
328    assert(NOps==4);
329    O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
330    // cast away const; DIetc do not take const operands for some reason.
331    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
332    O << V.getName();
333    O << " <- ";
334    // Frame address.  Currently handles register +- offset only.
335    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
336    O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
337    O << ']';
338    O << "+";
339    printOperand(MI, NOps-2, O);
340    OutStreamer.EmitRawText(O.str());
341    return;
342  }
343
344  case PPC::MovePCtoLR:
345  case PPC::MovePCtoLR8: {
346    // Transform %LR = MovePCtoLR
347    // Into this, where the label is the PIC base:
348    //     bl L1$pb
349    // L1$pb:
350    MCSymbol *PICBase = MF->getPICBaseSymbol();
351
352    // Emit the 'bl'.
353    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
354      // FIXME: We would like an efficient form for this, so we don't have to do
355      // a lot of extra uniquing.
356      .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
357
358    // Emit the label.
359    OutStreamer.EmitLabel(PICBase);
360    return;
361  }
362  case PPC::LDtocJTI:
363  case PPC::LDtocCPT:
364  case PPC::LDtoc: {
365    // Transform %X3 = LDtoc <ga:@min1>, %X2
366    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
367
368    // Change the opcode to LD, and the global address operand to be a
369    // reference to the TOC entry we will synthesize later.
370    TmpInst.setOpcode(PPC::LD);
371    const MachineOperand &MO = MI->getOperand(1);
372
373    // Map symbol -> label of TOC entry
374    assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
375    MCSymbol *MOSymbol = 0;
376    if (MO.isGlobal())
377      MOSymbol = Mang->getSymbol(MO.getGlobal());
378    else if (MO.isCPI())
379      MOSymbol = GetCPISymbol(MO.getIndex());
380    else if (MO.isJTI())
381      MOSymbol = GetJTISymbol(MO.getIndex());
382    MCSymbol *&TOCEntry = TOC[MOSymbol];
383    // To avoid name clash check if the name already exists.
384    while (TOCEntry == 0) {
385      if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
386                                  "C" + Twine(TOCLabelID++)) == 0) {
387        TOCEntry = GetTempSymbol("C", TOCLabelID);
388      }
389    }
390
391    const MCExpr *Exp =
392      MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
393                              OutContext);
394    TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
395    OutStreamer.EmitInstruction(TmpInst);
396    return;
397  }
398
399  case PPC::MFCRpseud:
400  case PPC::MFCR8pseud:
401    // Transform: %R3 = MFCRpseud %CR7
402    // Into:      %R3 = MFCR      ;; cr7
403    OutStreamer.AddComment(PPCInstPrinter::
404                           getRegisterName(MI->getOperand(1).getReg()));
405    OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
406      .addReg(MI->getOperand(0).getReg()));
407    return;
408  case PPC::SYNC:
409    // In Book E sync is called msync, handle this special case here...
410    if (Subtarget.isBookE()) {
411      OutStreamer.EmitRawText(StringRef("\tmsync"));
412      return;
413    }
414  }
415
416  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
417  OutStreamer.EmitInstruction(TmpInst);
418}
419
420void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
421  if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
422    return AsmPrinter::EmitFunctionEntryLabel();
423
424  // Emit an official procedure descriptor.
425  const MCSection *Current = OutStreamer.getCurrentSection();
426  const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
427      ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
428      SectionKind::getReadOnly());
429  OutStreamer.SwitchSection(Section);
430  OutStreamer.EmitLabel(CurrentFnSym);
431  OutStreamer.EmitValueToAlignment(8);
432  MCSymbol *Symbol1 =
433    OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
434  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
435  // entry point.
436  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
437                        8/*size*/, 0/*addrspace*/);
438  MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
439  // Generates a R_PPC64_TOC relocation for TOC base insertion.
440  OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
441                        MCSymbolRefExpr::VK_PPC_TOC, OutContext),
442                        8/*size*/, 0/*addrspace*/);
443  // Emit a null environment pointer.
444  OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */);
445  OutStreamer.SwitchSection(Current);
446
447  MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
448                          ".L." + Twine(CurrentFnSym->getName()));
449  OutStreamer.EmitLabel(RealFnSym);
450  CurrentFnSymForSize = RealFnSym;
451}
452
453
454bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
455  const DataLayout *TD = TM.getDataLayout();
456
457  bool isPPC64 = TD->getPointerSizeInBits() == 64;
458
459  if (isPPC64 && !TOC.empty()) {
460    const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
461        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
462        SectionKind::getReadOnly());
463    OutStreamer.SwitchSection(Section);
464
465    for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
466         E = TOC.end(); I != E; ++I) {
467      OutStreamer.EmitLabel(I->second);
468      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
469      OutStreamer.EmitTCEntry(*S);
470    }
471  }
472
473  return AsmPrinter::doFinalization(M);
474}
475
476/// EmitFunctionBodyEnd - Print the traceback table before the .size
477/// directive.
478///
479void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
480  // Only the 64-bit target requires a traceback table.  For now,
481  // we only emit the word of zeroes that GDB requires to find
482  // the end of the function, and zeroes for the eight-byte
483  // mandatory fields.
484  // FIXME: We should fill in the eight-byte mandatory fields as described in
485  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
486  // currently make use of these fields).
487  if (Subtarget.isPPC64()) {
488    OutStreamer.EmitIntValue(0, 4/*size*/);
489    OutStreamer.EmitIntValue(0, 8/*size*/);
490  }
491}
492
493void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
494  static const char *const CPUDirectives[] = {
495    "",
496    "ppc",
497    "ppc440",
498    "ppc601",
499    "ppc602",
500    "ppc603",
501    "ppc7400",
502    "ppc750",
503    "ppc970",
504    "ppcA2",
505    "ppce500mc",
506    "ppce5500",
507    "power6",
508    "power7",
509    "ppc64"
510  };
511
512  unsigned Directive = Subtarget.getDarwinDirective();
513  if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
514    Directive = PPC::DIR_970;
515  if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
516    Directive = PPC::DIR_7400;
517  if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
518    Directive = PPC::DIR_64;
519  assert(Directive <= PPC::DIR_64 && "Directive out of range.");
520
521  // FIXME: This is a total hack, finish mc'izing the PPC backend.
522  if (OutStreamer.hasRawTextSupport())
523    OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
524
525  // Prime text sections so they are adjacent.  This reduces the likelihood a
526  // large data or debug section causes a branch to exceed 16M limit.
527  const TargetLoweringObjectFileMachO &TLOFMacho =
528    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
529  OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
530  if (TM.getRelocationModel() == Reloc::PIC_) {
531    OutStreamer.SwitchSection(
532           OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
533                                      MCSectionMachO::S_SYMBOL_STUBS |
534                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
535                                      32, SectionKind::getText()));
536  } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
537    OutStreamer.SwitchSection(
538           OutContext.getMachOSection("__TEXT","__symbol_stub1",
539                                      MCSectionMachO::S_SYMBOL_STUBS |
540                                      MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
541                                      16, SectionKind::getText()));
542  }
543  OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
544}
545
546static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
547  // Remove $stub suffix, add $lazy_ptr.
548  StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
549  return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
550}
551
552static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
553  // Add $tmp suffix to $stub, yielding $stub$tmp.
554  return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
555}
556
557void PPCDarwinAsmPrinter::
558EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
559  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
560
561  const TargetLoweringObjectFileMachO &TLOFMacho =
562    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
563
564  // .lazy_symbol_pointer
565  const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
566
567  // Output stubs for dynamically-linked functions
568  if (TM.getRelocationModel() == Reloc::PIC_) {
569    const MCSection *StubSection =
570    OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
571                               MCSectionMachO::S_SYMBOL_STUBS |
572                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
573                               32, SectionKind::getText());
574    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
575      OutStreamer.SwitchSection(StubSection);
576      EmitAlignment(4);
577
578      MCSymbol *Stub = Stubs[i].first;
579      MCSymbol *RawSym = Stubs[i].second.getPointer();
580      MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
581      MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
582
583      OutStreamer.EmitLabel(Stub);
584      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
585
586      // mflr r0
587      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
588      // FIXME: MCize this.
589      OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
590      OutStreamer.EmitLabel(AnonSymbol);
591      // mflr r11
592      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
593      // addis r11, r11, ha16(LazyPtr - AnonSymbol)
594      const MCExpr *Sub =
595        MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
596                                MCSymbolRefExpr::Create(AnonSymbol, OutContext),
597                                OutContext);
598      OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
599        .addReg(PPC::R11)
600        .addReg(PPC::R11)
601        .addExpr(Sub));
602      // mtlr r0
603      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
604
605      // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
606      // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
607      OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
608        .addReg(PPC::R12)
609        .addExpr(Sub).addExpr(Sub)
610        .addReg(PPC::R11));
611      // mtctr r12
612      OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
613      // bctr
614      OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
615
616      OutStreamer.SwitchSection(LSPSection);
617      OutStreamer.EmitLabel(LazyPtr);
618      OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
619
620      MCSymbol *DyldStubBindingHelper =
621        OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
622      if (isPPC64) {
623        // .quad dyld_stub_binding_helper
624        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
625      } else {
626        // .long dyld_stub_binding_helper
627        OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
628      }
629    }
630    OutStreamer.AddBlankLine();
631    return;
632  }
633
634  const MCSection *StubSection =
635    OutContext.getMachOSection("__TEXT","__symbol_stub1",
636                               MCSectionMachO::S_SYMBOL_STUBS |
637                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
638                               16, SectionKind::getText());
639  for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
640    MCSymbol *Stub = Stubs[i].first;
641    MCSymbol *RawSym = Stubs[i].second.getPointer();
642    MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
643
644    OutStreamer.SwitchSection(StubSection);
645    EmitAlignment(4);
646    OutStreamer.EmitLabel(Stub);
647    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
648    // lis r11, ha16(LazyPtr)
649    const MCExpr *LazyPtrHa16 =
650      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
651                              OutContext);
652    OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
653      .addReg(PPC::R11)
654      .addExpr(LazyPtrHa16));
655
656    const MCExpr *LazyPtrLo16 =
657      MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
658                              OutContext);
659    // ldu r12, lo16(LazyPtr)(r11)
660    // lwzu r12, lo16(LazyPtr)(r11)
661    OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
662      .addReg(PPC::R12)
663      .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
664      .addReg(PPC::R11));
665
666    // mtctr r12
667    OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
668    // bctr
669    OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
670
671    OutStreamer.SwitchSection(LSPSection);
672    OutStreamer.EmitLabel(LazyPtr);
673    OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
674
675    MCSymbol *DyldStubBindingHelper =
676      OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
677    if (isPPC64) {
678      // .quad dyld_stub_binding_helper
679      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
680    } else {
681      // .long dyld_stub_binding_helper
682      OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
683    }
684  }
685
686  OutStreamer.AddBlankLine();
687}
688
689
690bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
691  bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
692
693  // Darwin/PPC always uses mach-o.
694  const TargetLoweringObjectFileMachO &TLOFMacho =
695    static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
696  MachineModuleInfoMachO &MMIMacho =
697    MMI->getObjFileInfo<MachineModuleInfoMachO>();
698
699  MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
700  if (!Stubs.empty())
701    EmitFunctionStubs(Stubs);
702
703  if (MAI->doesSupportExceptionHandling() && MMI) {
704    // Add the (possibly multiple) personalities to the set of global values.
705    // Only referenced functions get into the Personalities list.
706    const std::vector<const Function*> &Personalities = MMI->getPersonalities();
707    for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
708         E = Personalities.end(); I != E; ++I) {
709      if (*I) {
710        MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
711        MachineModuleInfoImpl::StubValueTy &StubSym =
712          MMIMacho.getGVStubEntry(NLPSym);
713        StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
714      }
715    }
716  }
717
718  // Output stubs for dynamically-linked functions.
719  Stubs = MMIMacho.GetGVStubList();
720
721  // Output macho stubs for external and common global variables.
722  if (!Stubs.empty()) {
723    // Switch with ".non_lazy_symbol_pointer" directive.
724    OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
725    EmitAlignment(isPPC64 ? 3 : 2);
726
727    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
728      // L_foo$stub:
729      OutStreamer.EmitLabel(Stubs[i].first);
730      //   .indirect_symbol _foo
731      MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
732      OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
733
734      if (MCSym.getInt())
735        // External to current translation unit.
736        OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
737      else
738        // Internal to current translation unit.
739        //
740        // When we place the LSDA into the TEXT section, the type info pointers
741        // need to be indirect and pc-rel. We accomplish this by using NLPs.
742        // However, sometimes the types are local to the file. So we need to
743        // fill in the value for the NLP in those cases.
744        OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
745                                                      OutContext),
746                              isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
747    }
748
749    Stubs.clear();
750    OutStreamer.AddBlankLine();
751  }
752
753  Stubs = MMIMacho.GetHiddenGVStubList();
754  if (!Stubs.empty()) {
755    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
756    EmitAlignment(isPPC64 ? 3 : 2);
757
758    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
759      // L_foo$stub:
760      OutStreamer.EmitLabel(Stubs[i].first);
761      //   .long _foo
762      OutStreamer.EmitValue(MCSymbolRefExpr::
763                            Create(Stubs[i].second.getPointer(),
764                                   OutContext),
765                            isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
766    }
767
768    Stubs.clear();
769    OutStreamer.AddBlankLine();
770  }
771
772  // Funny Darwin hack: This flag tells the linker that no global symbols
773  // contain code that falls through to other global symbols (e.g. the obvious
774  // implementation of multiple entry points).  If this doesn't occur, the
775  // linker can safely perform dead code stripping.  Since LLVM never generates
776  // code that does this, it is always safe to set.
777  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
778
779  return AsmPrinter::doFinalization(M);
780}
781
782/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
783/// for a MachineFunction to the given output stream, in a format that the
784/// Darwin assembler can deal with.
785///
786static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
787                                           MCStreamer &Streamer) {
788  const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
789
790  if (Subtarget->isDarwin())
791    return new PPCDarwinAsmPrinter(tm, Streamer);
792  return new PPCLinuxAsmPrinter(tm, Streamer);
793}
794
795// Force static initialization.
796extern "C" void LLVMInitializePowerPCAsmPrinter() {
797  TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
798  TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
799}
800