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