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