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 "InstPrinter/PPCInstPrinter.h"
     22 #include "MCTargetDesc/PPCPredicates.h"
     23 #include "PPCSubtarget.h"
     24 #include "PPCTargetMachine.h"
     25 #include "llvm/ADT/MapVector.h"
     26 #include "llvm/ADT/SmallString.h"
     27 #include "llvm/ADT/StringExtras.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/DebugInfo.h"
     36 #include "llvm/IR/Constants.h"
     37 #include "llvm/IR/DerivedTypes.h"
     38 #include "llvm/IR/Module.h"
     39 #include "llvm/MC/MCAsmInfo.h"
     40 #include "llvm/MC/MCContext.h"
     41 #include "llvm/MC/MCExpr.h"
     42 #include "llvm/MC/MCInst.h"
     43 #include "llvm/MC/MCInstBuilder.h"
     44 #include "llvm/MC/MCSectionELF.h"
     45 #include "llvm/MC/MCSectionMachO.h"
     46 #include "llvm/MC/MCStreamer.h"
     47 #include "llvm/MC/MCSymbol.h"
     48 #include "llvm/Support/CommandLine.h"
     49 #include "llvm/Support/Debug.h"
     50 #include "llvm/Support/ELF.h"
     51 #include "llvm/Support/ErrorHandling.h"
     52 #include "llvm/Support/MathExtras.h"
     53 #include "llvm/Support/TargetRegistry.h"
     54 #include "llvm/Support/raw_ostream.h"
     55 #include "llvm/Target/Mangler.h"
     56 #include "llvm/Target/TargetInstrInfo.h"
     57 #include "llvm/Target/TargetOptions.h"
     58 #include "llvm/Target/TargetRegisterInfo.h"
     59 using namespace llvm;
     60 
     61 namespace {
     62   class PPCAsmPrinter : public AsmPrinter {
     63   protected:
     64     MapVector<MCSymbol*, MCSymbol*> TOC;
     65     const PPCSubtarget &Subtarget;
     66     uint64_t TOCLabelID;
     67   public:
     68     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
     69       : AsmPrinter(TM, Streamer),
     70         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
     71 
     72     virtual const char *getPassName() const {
     73       return "PowerPC Assembly Printer";
     74     }
     75 
     76     MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
     77 
     78     virtual void EmitInstruction(const MachineInstr *MI);
     79 
     80     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
     81 
     82     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
     83                          unsigned AsmVariant, const char *ExtraCode,
     84                          raw_ostream &O);
     85     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
     86                                unsigned AsmVariant, const char *ExtraCode,
     87                                raw_ostream &O);
     88 
     89     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
     90       MachineLocation Location;
     91       assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
     92       // Frame address.  Currently handles register +- offset only.
     93       if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
     94         Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
     95       else {
     96         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
     97       }
     98       return Location;
     99     }
    100   };
    101 
    102   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
    103   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
    104   public:
    105     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
    106       : PPCAsmPrinter(TM, Streamer) {}
    107 
    108     virtual const char *getPassName() const {
    109       return "Linux PPC Assembly Printer";
    110     }
    111 
    112     bool doFinalization(Module &M);
    113 
    114     virtual void EmitFunctionEntryLabel();
    115 
    116     void EmitFunctionBodyEnd();
    117   };
    118 
    119   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
    120   /// OS X
    121   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
    122   public:
    123     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
    124       : PPCAsmPrinter(TM, Streamer) {}
    125 
    126     virtual const char *getPassName() const {
    127       return "Darwin PPC Assembly Printer";
    128     }
    129 
    130     bool doFinalization(Module &M);
    131     void EmitStartOfAsmFile(Module &M);
    132 
    133     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
    134   };
    135 } // end of anonymous namespace
    136 
    137 /// stripRegisterPrefix - This method strips the character prefix from a
    138 /// register name so that only the number is left.  Used by for linux asm.
    139 static const char *stripRegisterPrefix(const char *RegName) {
    140   switch (RegName[0]) {
    141     case 'r':
    142     case 'f':
    143     case 'v': return RegName + 1;
    144     case 'c': if (RegName[1] == 'r') return RegName + 2;
    145   }
    146 
    147   return RegName;
    148 }
    149 
    150 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
    151                                  raw_ostream &O) {
    152   const MachineOperand &MO = MI->getOperand(OpNo);
    153 
    154   switch (MO.getType()) {
    155   case MachineOperand::MO_Register: {
    156     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
    157     // Linux assembler (Others?) does not take register mnemonics.
    158     // FIXME - What about special registers used in mfspr/mtspr?
    159     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
    160     O << RegName;
    161     return;
    162   }
    163   case MachineOperand::MO_Immediate:
    164     O << MO.getImm();
    165     return;
    166 
    167   case MachineOperand::MO_MachineBasicBlock:
    168     O << *MO.getMBB()->getSymbol();
    169     return;
    170   case MachineOperand::MO_JumpTableIndex:
    171     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
    172       << '_' << MO.getIndex();
    173     // FIXME: PIC relocation model
    174     return;
    175   case MachineOperand::MO_ConstantPoolIndex:
    176     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
    177       << '_' << MO.getIndex();
    178     return;
    179   case MachineOperand::MO_BlockAddress:
    180     O << *GetBlockAddressSymbol(MO.getBlockAddress());
    181     return;
    182   case MachineOperand::MO_ExternalSymbol: {
    183     // Computing the address of an external symbol, not calling it.
    184     if (TM.getRelocationModel() == Reloc::Static) {
    185       O << *GetExternalSymbolSymbol(MO.getSymbolName());
    186       return;
    187     }
    188 
    189     MCSymbol *NLPSym =
    190       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
    191                                    MO.getSymbolName()+"$non_lazy_ptr");
    192     MachineModuleInfoImpl::StubValueTy &StubSym =
    193       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
    194     if (StubSym.getPointer() == 0)
    195       StubSym = MachineModuleInfoImpl::
    196         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
    197 
    198     O << *NLPSym;
    199     return;
    200   }
    201   case MachineOperand::MO_GlobalAddress: {
    202     // Computing the address of a global symbol, not calling it.
    203     const GlobalValue *GV = MO.getGlobal();
    204     MCSymbol *SymToPrint;
    205 
    206     // External or weakly linked global variables need non-lazily-resolved stubs
    207     if (TM.getRelocationModel() != Reloc::Static &&
    208         (GV->isDeclaration() || GV->isWeakForLinker())) {
    209       if (!GV->hasHiddenVisibility()) {
    210         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    211         MachineModuleInfoImpl::StubValueTy &StubSym =
    212           MMI->getObjFileInfo<MachineModuleInfoMachO>()
    213             .getGVStubEntry(SymToPrint);
    214         if (StubSym.getPointer() == 0)
    215           StubSym = MachineModuleInfoImpl::
    216             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
    217       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
    218                  GV->hasAvailableExternallyLinkage()) {
    219         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    220 
    221         MachineModuleInfoImpl::StubValueTy &StubSym =
    222           MMI->getObjFileInfo<MachineModuleInfoMachO>().
    223                     getHiddenGVStubEntry(SymToPrint);
    224         if (StubSym.getPointer() == 0)
    225           StubSym = MachineModuleInfoImpl::
    226             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
    227       } else {
    228         SymToPrint = Mang->getSymbol(GV);
    229       }
    230     } else {
    231       SymToPrint = Mang->getSymbol(GV);
    232     }
    233 
    234     O << *SymToPrint;
    235 
    236     printOffset(MO.getOffset(), O);
    237     return;
    238   }
    239 
    240   default:
    241     O << "<unknown operand type: " << MO.getType() << ">";
    242     return;
    243   }
    244 }
    245 
    246 /// PrintAsmOperand - Print out an operand for an inline asm expression.
    247 ///
    248 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
    249                                     unsigned AsmVariant,
    250                                     const char *ExtraCode, raw_ostream &O) {
    251   // Does this asm operand have a single letter operand modifier?
    252   if (ExtraCode && ExtraCode[0]) {
    253     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    254 
    255     switch (ExtraCode[0]) {
    256     default:
    257       // See if this is a generic print operand
    258       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
    259     case 'c': // Don't print "$" before a global var name or constant.
    260       break; // PPC never has a prefix.
    261     case 'L': // Write second word of DImode reference.
    262       // Verify that this operand has two consecutive registers.
    263       if (!MI->getOperand(OpNo).isReg() ||
    264           OpNo+1 == MI->getNumOperands() ||
    265           !MI->getOperand(OpNo+1).isReg())
    266         return true;
    267       ++OpNo;   // Return the high-part.
    268       break;
    269     case 'I':
    270       // Write 'i' if an integer constant, otherwise nothing.  Used to print
    271       // addi vs add, etc.
    272       if (MI->getOperand(OpNo).isImm())
    273         O << "i";
    274       return false;
    275     }
    276   }
    277 
    278   printOperand(MI, OpNo, O);
    279   return false;
    280 }
    281 
    282 // At the moment, all inline asm memory operands are a single register.
    283 // In any case, the output of this routine should always be just one
    284 // assembler operand.
    285 
    286 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
    287                                           unsigned AsmVariant,
    288                                           const char *ExtraCode,
    289                                           raw_ostream &O) {
    290   if (ExtraCode && ExtraCode[0]) {
    291     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    292 
    293     switch (ExtraCode[0]) {
    294     default: return true;  // Unknown modifier.
    295     case 'y': // A memory reference for an X-form instruction
    296       {
    297         const char *RegName = "r0";
    298         if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
    299         O << RegName << ", ";
    300         printOperand(MI, OpNo, O);
    301         return false;
    302       }
    303     }
    304   }
    305 
    306   assert(MI->getOperand(OpNo).isReg());
    307   O << "0(";
    308   printOperand(MI, OpNo, O);
    309   O << ")";
    310   return false;
    311 }
    312 
    313 
    314 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
    315 /// exists for it.  If not, create one.  Then return a symbol that references
    316 /// the TOC entry.
    317 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
    318 
    319   MCSymbol *&TOCEntry = TOC[Sym];
    320 
    321   // To avoid name clash check if the name already exists.
    322   while (TOCEntry == 0) {
    323     if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
    324                                 "C" + Twine(TOCLabelID++)) == 0) {
    325       TOCEntry = GetTempSymbol("C", TOCLabelID);
    326     }
    327   }
    328 
    329   return TOCEntry;
    330 }
    331 
    332 
    333 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
    334 /// the current output stream.
    335 ///
    336 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
    337   MCInst TmpInst;
    338 
    339   // Lower multi-instruction pseudo operations.
    340   switch (MI->getOpcode()) {
    341   default: break;
    342   case TargetOpcode::DBG_VALUE: {
    343     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
    344 
    345     SmallString<32> Str;
    346     raw_svector_ostream O(Str);
    347     unsigned NOps = MI->getNumOperands();
    348     assert(NOps==4);
    349     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
    350     // cast away const; DIetc do not take const operands for some reason.
    351     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
    352     O << V.getName();
    353     O << " <- ";
    354     // Frame address.  Currently handles register +- offset only.
    355     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
    356     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
    357     O << ']';
    358     O << "+";
    359     printOperand(MI, NOps-2, O);
    360     OutStreamer.EmitRawText(O.str());
    361     return;
    362   }
    363 
    364   case PPC::MovePCtoLR:
    365   case PPC::MovePCtoLR8: {
    366     // Transform %LR = MovePCtoLR
    367     // Into this, where the label is the PIC base:
    368     //     bl L1$pb
    369     // L1$pb:
    370     MCSymbol *PICBase = MF->getPICBaseSymbol();
    371 
    372     // Emit the 'bl'.
    373     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here.
    374       // FIXME: We would like an efficient form for this, so we don't have to do
    375       // a lot of extra uniquing.
    376       .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
    377 
    378     // Emit the label.
    379     OutStreamer.EmitLabel(PICBase);
    380     return;
    381   }
    382   case PPC::LDtocJTI:
    383   case PPC::LDtocCPT:
    384   case PPC::LDtoc: {
    385     // Transform %X3 = LDtoc <ga:@min1>, %X2
    386     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
    387 
    388     // Change the opcode to LD, and the global address operand to be a
    389     // reference to the TOC entry we will synthesize later.
    390     TmpInst.setOpcode(PPC::LD);
    391     const MachineOperand &MO = MI->getOperand(1);
    392 
    393     // Map symbol -> label of TOC entry
    394     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
    395     MCSymbol *MOSymbol = 0;
    396     if (MO.isGlobal())
    397       MOSymbol = Mang->getSymbol(MO.getGlobal());
    398     else if (MO.isCPI())
    399       MOSymbol = GetCPISymbol(MO.getIndex());
    400     else if (MO.isJTI())
    401       MOSymbol = GetJTISymbol(MO.getIndex());
    402 
    403     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
    404 
    405     const MCExpr *Exp =
    406       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
    407                               OutContext);
    408     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
    409     OutStreamer.EmitInstruction(TmpInst);
    410     return;
    411   }
    412 
    413   case PPC::ADDIStocHA: {
    414     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
    415     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
    416 
    417     // Change the opcode to ADDIS8.  If the global address is external,
    418     // has common linkage, is a function address, or is a jump table
    419     // address, then generate a TOC entry and reference that.  Otherwise
    420     // reference the symbol directly.
    421     TmpInst.setOpcode(PPC::ADDIS8);
    422     const MachineOperand &MO = MI->getOperand(2);
    423     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
    424            "Invalid operand for ADDIStocHA!");
    425     MCSymbol *MOSymbol = 0;
    426     bool IsExternal = false;
    427     bool IsFunction = false;
    428     bool IsCommon = false;
    429     bool IsAvailExt = false;
    430 
    431     if (MO.isGlobal()) {
    432       const GlobalValue *GValue = MO.getGlobal();
    433       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
    434       const GlobalValue *RealGValue = GAlias ?
    435         GAlias->resolveAliasedGlobal(false) : GValue;
    436       MOSymbol = Mang->getSymbol(RealGValue);
    437       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
    438       IsExternal = GVar && !GVar->hasInitializer();
    439       IsCommon = GVar && RealGValue->hasCommonLinkage();
    440       IsFunction = !GVar;
    441       IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
    442     } else if (MO.isCPI())
    443       MOSymbol = GetCPISymbol(MO.getIndex());
    444     else if (MO.isJTI())
    445       MOSymbol = GetJTISymbol(MO.getIndex());
    446 
    447     if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
    448       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
    449 
    450     const MCExpr *Exp =
    451       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA,
    452                               OutContext);
    453     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
    454     OutStreamer.EmitInstruction(TmpInst);
    455     return;
    456   }
    457   case PPC::LDtocL: {
    458     // Transform %Xd = LDtocL <ga:@sym>, %Xs
    459     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
    460 
    461     // Change the opcode to LDrs, which is a form of LD with the offset
    462     // specified by a SymbolLo.  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::LDrs);
    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 ADDI8L.  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::ADDI8L);
    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 LDrs, which is a form of LD with the offset
    552     // specified by a SymbolLo.
    553     TmpInst.setOpcode(PPC::LDrs);
    554     const MachineOperand &MO = MI->getOperand(1);
    555     const GlobalValue *GValue = MO.getGlobal();
    556     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    557     const MCExpr *Exp =
    558       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO,
    559                               OutContext);
    560     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
    561     OutStreamer.EmitInstruction(TmpInst);
    562     return;
    563   }
    564   case PPC::ADDIStlsgdHA: {
    565     // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
    566     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
    567     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    568     const MachineOperand &MO = MI->getOperand(2);
    569     const GlobalValue *GValue = MO.getGlobal();
    570     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    571     const MCExpr *SymGotTlsGD =
    572       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA,
    573                               OutContext);
    574     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
    575                                 .addReg(MI->getOperand(0).getReg())
    576                                 .addReg(PPC::X2)
    577                                 .addExpr(SymGotTlsGD));
    578     return;
    579   }
    580   case PPC::ADDItlsgdL: {
    581     // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
    582     // Into:      %Xd = ADDI8L %Xs, sym@got@tlsgd@l
    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 = Mang->getSymbol(GValue);
    587     const MCExpr *SymGotTlsGD =
    588       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO,
    589                               OutContext);
    590     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
    591                                 .addReg(MI->getOperand(0).getReg())
    592                                 .addReg(MI->getOperand(1).getReg())
    593                                 .addExpr(SymGotTlsGD));
    594     return;
    595   }
    596   case PPC::GETtlsADDR: {
    597     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
    598     // Into:      BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd)
    599     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    600 
    601     StringRef Name = "__tls_get_addr";
    602     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
    603     const MCSymbolRefExpr *TlsRef =
    604       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
    605     const MachineOperand &MO = MI->getOperand(2);
    606     const GlobalValue *GValue = MO.getGlobal();
    607     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    608     const MCExpr *SymVar =
    609       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
    610                               OutContext);
    611     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD)
    612                                 .addExpr(TlsRef)
    613                                 .addExpr(SymVar));
    614     return;
    615   }
    616   case PPC::ADDIStlsldHA: {
    617     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
    618     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
    619     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    620     const MachineOperand &MO = MI->getOperand(2);
    621     const GlobalValue *GValue = MO.getGlobal();
    622     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    623     const MCExpr *SymGotTlsLD =
    624       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA,
    625                               OutContext);
    626     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
    627                                 .addReg(MI->getOperand(0).getReg())
    628                                 .addReg(PPC::X2)
    629                                 .addExpr(SymGotTlsLD));
    630     return;
    631   }
    632   case PPC::ADDItlsldL: {
    633     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
    634     // Into:      %Xd = ADDI8L %Xs, sym@got@tlsld@l
    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 = Mang->getSymbol(GValue);
    639     const MCExpr *SymGotTlsLD =
    640       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO,
    641                               OutContext);
    642     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
    643                                 .addReg(MI->getOperand(0).getReg())
    644                                 .addReg(MI->getOperand(1).getReg())
    645                                 .addExpr(SymGotTlsLD));
    646     return;
    647   }
    648   case PPC::GETtlsldADDR: {
    649     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
    650     // Into:      BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld)
    651     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    652 
    653     StringRef Name = "__tls_get_addr";
    654     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
    655     const MCSymbolRefExpr *TlsRef =
    656       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
    657     const MachineOperand &MO = MI->getOperand(2);
    658     const GlobalValue *GValue = MO.getGlobal();
    659     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    660     const MCExpr *SymVar =
    661       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
    662                               OutContext);
    663     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD)
    664                                 .addExpr(TlsRef)
    665                                 .addExpr(SymVar));
    666     return;
    667   }
    668   case PPC::ADDISdtprelHA: {
    669     // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
    670     // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
    671     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    672     const MachineOperand &MO = MI->getOperand(2);
    673     const GlobalValue *GValue = MO.getGlobal();
    674     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    675     const MCExpr *SymDtprel =
    676       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA,
    677                               OutContext);
    678     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
    679                                 .addReg(MI->getOperand(0).getReg())
    680                                 .addReg(PPC::X3)
    681                                 .addExpr(SymDtprel));
    682     return;
    683   }
    684   case PPC::ADDIdtprelL: {
    685     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
    686     // Into:      %Xd = ADDI8L %Xs, sym@dtprel@l
    687     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
    688     const MachineOperand &MO = MI->getOperand(2);
    689     const GlobalValue *GValue = MO.getGlobal();
    690     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
    691     const MCExpr *SymDtprel =
    692       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO,
    693                               OutContext);
    694     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
    695                                 .addReg(MI->getOperand(0).getReg())
    696                                 .addReg(MI->getOperand(1).getReg())
    697                                 .addExpr(SymDtprel));
    698     return;
    699   }
    700   case PPC::MFCRpseud:
    701   case PPC::MFCR8pseud:
    702     // Transform: %R3 = MFCRpseud %CR7
    703     // Into:      %R3 = MFCR      ;; cr7
    704     OutStreamer.AddComment(PPCInstPrinter::
    705                            getRegisterName(MI->getOperand(1).getReg()));
    706     OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
    707       .addReg(MI->getOperand(0).getReg()));
    708     return;
    709   case PPC::SYNC:
    710     // In Book E sync is called msync, handle this special case here...
    711     if (Subtarget.isBookE()) {
    712       OutStreamer.EmitRawText(StringRef("\tmsync"));
    713       return;
    714     }
    715   }
    716 
    717   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
    718   OutStreamer.EmitInstruction(TmpInst);
    719 }
    720 
    721 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
    722   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
    723     return AsmPrinter::EmitFunctionEntryLabel();
    724 
    725   // Emit an official procedure descriptor.
    726   const MCSection *Current = OutStreamer.getCurrentSection();
    727   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
    728       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
    729       SectionKind::getReadOnly());
    730   OutStreamer.SwitchSection(Section);
    731   OutStreamer.EmitLabel(CurrentFnSym);
    732   OutStreamer.EmitValueToAlignment(8);
    733   MCSymbol *Symbol1 =
    734     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
    735   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
    736   // entry point.
    737   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
    738 			8 /*size*/);
    739   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
    740   // Generates a R_PPC64_TOC relocation for TOC base insertion.
    741   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
    742                         MCSymbolRefExpr::VK_PPC_TOC, OutContext),
    743                         8/*size*/);
    744   // Emit a null environment pointer.
    745   OutStreamer.EmitIntValue(0, 8 /* size */);
    746   OutStreamer.SwitchSection(Current);
    747 
    748   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
    749                           ".L." + Twine(CurrentFnSym->getName()));
    750   OutStreamer.EmitLabel(RealFnSym);
    751   CurrentFnSymForSize = RealFnSym;
    752 }
    753 
    754 
    755 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
    756   const DataLayout *TD = TM.getDataLayout();
    757 
    758   bool isPPC64 = TD->getPointerSizeInBits() == 64;
    759 
    760   if (isPPC64 && !TOC.empty()) {
    761     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
    762         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
    763         SectionKind::getReadOnly());
    764     OutStreamer.SwitchSection(Section);
    765 
    766     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
    767          E = TOC.end(); I != E; ++I) {
    768       OutStreamer.EmitLabel(I->second);
    769       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
    770       OutStreamer.EmitTCEntry(*S);
    771     }
    772   }
    773 
    774   MachineModuleInfoELF &MMIELF =
    775     MMI->getObjFileInfo<MachineModuleInfoELF>();
    776 
    777   MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
    778   if (!Stubs.empty()) {
    779     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
    780     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
    781       // L_foo$stub:
    782       OutStreamer.EmitLabel(Stubs[i].first);
    783       //   .long _foo
    784       OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
    785                                                     OutContext),
    786                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
    787     }
    788 
    789     Stubs.clear();
    790     OutStreamer.AddBlankLine();
    791   }
    792 
    793   return AsmPrinter::doFinalization(M);
    794 }
    795 
    796 /// EmitFunctionBodyEnd - Print the traceback table before the .size
    797 /// directive.
    798 ///
    799 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
    800   // Only the 64-bit target requires a traceback table.  For now,
    801   // we only emit the word of zeroes that GDB requires to find
    802   // the end of the function, and zeroes for the eight-byte
    803   // mandatory fields.
    804   // FIXME: We should fill in the eight-byte mandatory fields as described in
    805   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
    806   // currently make use of these fields).
    807   if (Subtarget.isPPC64()) {
    808     OutStreamer.EmitIntValue(0, 4/*size*/);
    809     OutStreamer.EmitIntValue(0, 8/*size*/);
    810   }
    811 }
    812 
    813 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
    814   static const char *const CPUDirectives[] = {
    815     "",
    816     "ppc",
    817     "ppc440",
    818     "ppc601",
    819     "ppc602",
    820     "ppc603",
    821     "ppc7400",
    822     "ppc750",
    823     "ppc970",
    824     "ppcA2",
    825     "ppce500mc",
    826     "ppce5500",
    827     "power3",
    828     "power4",
    829     "power5",
    830     "power5x",
    831     "power6",
    832     "power6x",
    833     "power7",
    834     "ppc64"
    835   };
    836 
    837   unsigned Directive = Subtarget.getDarwinDirective();
    838   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
    839     Directive = PPC::DIR_970;
    840   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
    841     Directive = PPC::DIR_7400;
    842   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
    843     Directive = PPC::DIR_64;
    844   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
    845 
    846   // FIXME: This is a total hack, finish mc'izing the PPC backend.
    847   if (OutStreamer.hasRawTextSupport()) {
    848     assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) &&
    849            "CPUDirectives[] might not be up-to-date!");
    850     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
    851   }
    852 
    853   // Prime text sections so they are adjacent.  This reduces the likelihood a
    854   // large data or debug section causes a branch to exceed 16M limit.
    855   const TargetLoweringObjectFileMachO &TLOFMacho =
    856     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
    857   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
    858   if (TM.getRelocationModel() == Reloc::PIC_) {
    859     OutStreamer.SwitchSection(
    860            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
    861                                       MCSectionMachO::S_SYMBOL_STUBS |
    862                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
    863                                       32, SectionKind::getText()));
    864   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
    865     OutStreamer.SwitchSection(
    866            OutContext.getMachOSection("__TEXT","__symbol_stub1",
    867                                       MCSectionMachO::S_SYMBOL_STUBS |
    868                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
    869                                       16, SectionKind::getText()));
    870   }
    871   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
    872 }
    873 
    874 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
    875   // Remove $stub suffix, add $lazy_ptr.
    876   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
    877   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
    878 }
    879 
    880 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
    881   // Add $tmp suffix to $stub, yielding $stub$tmp.
    882   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
    883 }
    884 
    885 void PPCDarwinAsmPrinter::
    886 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
    887   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
    888 
    889   const TargetLoweringObjectFileMachO &TLOFMacho =
    890     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
    891 
    892   // .lazy_symbol_pointer
    893   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
    894 
    895   // Output stubs for dynamically-linked functions
    896   if (TM.getRelocationModel() == Reloc::PIC_) {
    897     const MCSection *StubSection =
    898     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
    899                                MCSectionMachO::S_SYMBOL_STUBS |
    900                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
    901                                32, SectionKind::getText());
    902     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
    903       OutStreamer.SwitchSection(StubSection);
    904       EmitAlignment(4);
    905 
    906       MCSymbol *Stub = Stubs[i].first;
    907       MCSymbol *RawSym = Stubs[i].second.getPointer();
    908       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
    909       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
    910 
    911       OutStreamer.EmitLabel(Stub);
    912       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
    913 
    914       // mflr r0
    915       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
    916       // FIXME: MCize this.
    917       OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName()));
    918       OutStreamer.EmitLabel(AnonSymbol);
    919       // mflr r11
    920       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
    921       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
    922       const MCExpr *Sub =
    923         MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
    924                                 MCSymbolRefExpr::Create(AnonSymbol, OutContext),
    925                                 OutContext);
    926       OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
    927         .addReg(PPC::R11)
    928         .addReg(PPC::R11)
    929         .addExpr(Sub));
    930       // mtlr r0
    931       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
    932 
    933       // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
    934       // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
    935       OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
    936         .addReg(PPC::R12)
    937         .addExpr(Sub).addExpr(Sub)
    938         .addReg(PPC::R11));
    939       // mtctr r12
    940       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
    941       // bctr
    942       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
    943 
    944       OutStreamer.SwitchSection(LSPSection);
    945       OutStreamer.EmitLabel(LazyPtr);
    946       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
    947 
    948       MCSymbol *DyldStubBindingHelper =
    949         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
    950       if (isPPC64) {
    951         // .quad dyld_stub_binding_helper
    952         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
    953       } else {
    954         // .long dyld_stub_binding_helper
    955         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
    956       }
    957     }
    958     OutStreamer.AddBlankLine();
    959     return;
    960   }
    961 
    962   const MCSection *StubSection =
    963     OutContext.getMachOSection("__TEXT","__symbol_stub1",
    964                                MCSectionMachO::S_SYMBOL_STUBS |
    965                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
    966                                16, SectionKind::getText());
    967   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
    968     MCSymbol *Stub = Stubs[i].first;
    969     MCSymbol *RawSym = Stubs[i].second.getPointer();
    970     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
    971 
    972     OutStreamer.SwitchSection(StubSection);
    973     EmitAlignment(4);
    974     OutStreamer.EmitLabel(Stub);
    975     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
    976     // lis r11, ha16(LazyPtr)
    977     const MCExpr *LazyPtrHa16 =
    978       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
    979                               OutContext);
    980     OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
    981       .addReg(PPC::R11)
    982       .addExpr(LazyPtrHa16));
    983 
    984     const MCExpr *LazyPtrLo16 =
    985       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
    986                               OutContext);
    987     // ldu r12, lo16(LazyPtr)(r11)
    988     // lwzu r12, lo16(LazyPtr)(r11)
    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 
   1018 bool 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 ///
   1114 static 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.
   1124 extern "C" void LLVMInitializePowerPCAsmPrinter() {
   1125   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
   1126   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
   1127 }
   1128