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