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