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