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