LLVM API Documentation

PPCAsmPrinter.cpp
Go to the documentation of this file.
00001 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains a printer that converts from our internal representation
00011 // of machine-dependent LLVM code to PowerPC assembly language. This printer is
00012 // the output mechanism used by `llc'.
00013 //
00014 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
00015 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #define DEBUG_TYPE "asmprinter"
00020 #include "PPC.h"
00021 #include "InstPrinter/PPCInstPrinter.h"
00022 #include "MCTargetDesc/PPCPredicates.h"
00023 #include "PPCSubtarget.h"
00024 #include "PPCTargetMachine.h"
00025 #include "llvm/ADT/MapVector.h"
00026 #include "llvm/ADT/SmallString.h"
00027 #include "llvm/ADT/StringExtras.h"
00028 #include "llvm/Assembly/Writer.h"
00029 #include "llvm/CodeGen/AsmPrinter.h"
00030 #include "llvm/CodeGen/MachineFunctionPass.h"
00031 #include "llvm/CodeGen/MachineInstr.h"
00032 #include "llvm/CodeGen/MachineInstrBuilder.h"
00033 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
00034 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
00035 #include "llvm/DebugInfo.h"
00036 #include "llvm/IR/Constants.h"
00037 #include "llvm/IR/DerivedTypes.h"
00038 #include "llvm/IR/Module.h"
00039 #include "llvm/MC/MCAsmInfo.h"
00040 #include "llvm/MC/MCContext.h"
00041 #include "llvm/MC/MCExpr.h"
00042 #include "llvm/MC/MCInst.h"
00043 #include "llvm/MC/MCInstBuilder.h"
00044 #include "llvm/MC/MCSectionELF.h"
00045 #include "llvm/MC/MCSectionMachO.h"
00046 #include "llvm/MC/MCStreamer.h"
00047 #include "llvm/MC/MCSymbol.h"
00048 #include "llvm/Support/CommandLine.h"
00049 #include "llvm/Support/Debug.h"
00050 #include "llvm/Support/ELF.h"
00051 #include "llvm/Support/ErrorHandling.h"
00052 #include "llvm/Support/MathExtras.h"
00053 #include "llvm/Support/TargetRegistry.h"
00054 #include "llvm/Support/raw_ostream.h"
00055 #include "llvm/Target/Mangler.h"
00056 #include "llvm/Target/TargetInstrInfo.h"
00057 #include "llvm/Target/TargetOptions.h"
00058 #include "llvm/Target/TargetRegisterInfo.h"
00059 using namespace llvm;
00060 
00061 namespace {
00062   class PPCAsmPrinter : public AsmPrinter {
00063   protected:
00064     MapVector<MCSymbol*, MCSymbol*> TOC;
00065     const PPCSubtarget &Subtarget;
00066     uint64_t TOCLabelID;
00067   public:
00068     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00069       : AsmPrinter(TM, Streamer),
00070         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
00071 
00072     virtual const char *getPassName() const {
00073       return "PowerPC Assembly Printer";
00074     }
00075 
00076     MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
00077 
00078     virtual void EmitInstruction(const MachineInstr *MI);
00079 
00080     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
00081 
00082     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00083                          unsigned AsmVariant, const char *ExtraCode,
00084                          raw_ostream &O);
00085     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00086                                unsigned AsmVariant, const char *ExtraCode,
00087                                raw_ostream &O);
00088 
00089     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
00090       MachineLocation Location;
00091       assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
00092       // Frame address.  Currently handles register +- offset only.
00093       if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm())
00094         Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm());
00095       else {
00096         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
00097       }
00098       return Location;
00099     }
00100   };
00101 
00102   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
00103   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
00104   public:
00105     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00106       : PPCAsmPrinter(TM, Streamer) {}
00107 
00108     virtual const char *getPassName() const {
00109       return "Linux PPC Assembly Printer";
00110     }
00111 
00112     bool doFinalization(Module &M);
00113 
00114     virtual void EmitFunctionEntryLabel();
00115 
00116     void EmitFunctionBodyEnd();
00117   };
00118 
00119   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
00120   /// OS X
00121   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
00122   public:
00123     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00124       : PPCAsmPrinter(TM, Streamer) {}
00125 
00126     virtual const char *getPassName() const {
00127       return "Darwin PPC Assembly Printer";
00128     }
00129 
00130     bool doFinalization(Module &M);
00131     void EmitStartOfAsmFile(Module &M);
00132 
00133     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
00134   };
00135 } // end of anonymous namespace
00136 
00137 /// stripRegisterPrefix - This method strips the character prefix from a
00138 /// register name so that only the number is left.  Used by for linux asm.
00139 static const char *stripRegisterPrefix(const char *RegName) {
00140   switch (RegName[0]) {
00141     case 'r':
00142     case 'f':
00143     case 'v': return RegName + 1;
00144     case 'c': if (RegName[1] == 'r') return RegName + 2;
00145   }
00146   
00147   return RegName;
00148 }
00149 
00150 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
00151                                  raw_ostream &O) {
00152   const MachineOperand &MO = MI->getOperand(OpNo);
00153   
00154   switch (MO.getType()) {
00155   case MachineOperand::MO_Register: {
00156     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
00157     // Linux assembler (Others?) does not take register mnemonics.
00158     // FIXME - What about special registers used in mfspr/mtspr?
00159     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
00160     O << RegName;
00161     return;
00162   }
00163   case MachineOperand::MO_Immediate:
00164     O << MO.getImm();
00165     return;
00166 
00167   case MachineOperand::MO_MachineBasicBlock:
00168     O << *MO.getMBB()->getSymbol();
00169     return;
00170   case MachineOperand::MO_JumpTableIndex:
00171     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
00172       << '_' << MO.getIndex();
00173     // FIXME: PIC relocation model
00174     return;
00175   case MachineOperand::MO_ConstantPoolIndex:
00176     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
00177       << '_' << MO.getIndex();
00178     return;
00179   case MachineOperand::MO_BlockAddress:
00180     O << *GetBlockAddressSymbol(MO.getBlockAddress());
00181     return;
00182   case MachineOperand::MO_ExternalSymbol: {
00183     // Computing the address of an external symbol, not calling it.
00184     if (TM.getRelocationModel() == Reloc::Static) {
00185       O << *GetExternalSymbolSymbol(MO.getSymbolName());
00186       return;
00187     }
00188 
00189     MCSymbol *NLPSym = 
00190       OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+
00191                                    MO.getSymbolName()+"$non_lazy_ptr");
00192     MachineModuleInfoImpl::StubValueTy &StubSym = 
00193       MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym);
00194     if (StubSym.getPointer() == 0)
00195       StubSym = MachineModuleInfoImpl::
00196         StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true);
00197     
00198     O << *NLPSym;
00199     return;
00200   }
00201   case MachineOperand::MO_GlobalAddress: {
00202     // Computing the address of a global symbol, not calling it.
00203     const GlobalValue *GV = MO.getGlobal();
00204     MCSymbol *SymToPrint;
00205 
00206     // External or weakly linked global variables need non-lazily-resolved stubs
00207     if (TM.getRelocationModel() != Reloc::Static &&
00208         (GV->isDeclaration() || GV->isWeakForLinker())) {
00209       if (!GV->hasHiddenVisibility()) {
00210         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
00211         MachineModuleInfoImpl::StubValueTy &StubSym = 
00212           MMI->getObjFileInfo<MachineModuleInfoMachO>()
00213             .getGVStubEntry(SymToPrint);
00214         if (StubSym.getPointer() == 0)
00215           StubSym = MachineModuleInfoImpl::
00216             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
00217       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
00218                  GV->hasAvailableExternallyLinkage()) {
00219         SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
00220         
00221         MachineModuleInfoImpl::StubValueTy &StubSym = 
00222           MMI->getObjFileInfo<MachineModuleInfoMachO>().
00223                     getHiddenGVStubEntry(SymToPrint);
00224         if (StubSym.getPointer() == 0)
00225           StubSym = MachineModuleInfoImpl::
00226             StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
00227       } else {
00228         SymToPrint = Mang->getSymbol(GV);
00229       }
00230     } else {
00231       SymToPrint = Mang->getSymbol(GV);
00232     }
00233     
00234     O << *SymToPrint;
00235 
00236     printOffset(MO.getOffset(), O);
00237     return;
00238   }
00239 
00240   default:
00241     O << "<unknown operand type: " << MO.getType() << ">";
00242     return;
00243   }
00244 }
00245 
00246 /// PrintAsmOperand - Print out an operand for an inline asm expression.
00247 ///
00248 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00249                                     unsigned AsmVariant,
00250                                     const char *ExtraCode, raw_ostream &O) {
00251   // Does this asm operand have a single letter operand modifier?
00252   if (ExtraCode && ExtraCode[0]) {
00253     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00254 
00255     switch (ExtraCode[0]) {
00256     default:
00257       // See if this is a generic print operand
00258       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
00259     case 'c': // Don't print "$" before a global var name or constant.
00260       break; // PPC never has a prefix.
00261     case 'L': // Write second word of DImode reference.
00262       // Verify that this operand has two consecutive registers.
00263       if (!MI->getOperand(OpNo).isReg() ||
00264           OpNo+1 == MI->getNumOperands() ||
00265           !MI->getOperand(OpNo+1).isReg())
00266         return true;
00267       ++OpNo;   // Return the high-part.
00268       break;
00269     case 'I':
00270       // Write 'i' if an integer constant, otherwise nothing.  Used to print
00271       // addi vs add, etc.
00272       if (MI->getOperand(OpNo).isImm())
00273         O << "i";
00274       return false;
00275     }
00276   }
00277 
00278   printOperand(MI, OpNo, O);
00279   return false;
00280 }
00281 
00282 // At the moment, all inline asm memory operands are a single register.
00283 // In any case, the output of this routine should always be just one
00284 // assembler operand.
00285 
00286 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00287                                           unsigned AsmVariant,
00288                                           const char *ExtraCode,
00289                                           raw_ostream &O) {
00290   if (ExtraCode && ExtraCode[0]) {
00291     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00292 
00293     switch (ExtraCode[0]) {
00294     default: return true;  // Unknown modifier.
00295     case 'y': // A memory reference for an X-form instruction
00296       {
00297         const char *RegName = "r0";
00298         if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
00299         O << RegName << ", ";
00300         printOperand(MI, OpNo, O);
00301         return false;
00302       }
00303     }
00304   }
00305 
00306   assert(MI->getOperand(OpNo).isReg());
00307   O << "0(";
00308   printOperand(MI, OpNo, O);
00309   O << ")";
00310   return false;
00311 }
00312 
00313 
00314 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
00315 /// exists for it.  If not, create one.  Then return a symbol that references
00316 /// the TOC entry.
00317 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
00318 
00319   MCSymbol *&TOCEntry = TOC[Sym];
00320 
00321   // To avoid name clash check if the name already exists.
00322   while (TOCEntry == 0) {
00323     if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
00324                                 "C" + Twine(TOCLabelID++)) == 0) {
00325       TOCEntry = GetTempSymbol("C", TOCLabelID);
00326     }
00327   }
00328 
00329   return TOCEntry;
00330 }
00331 
00332 
00333 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
00334 /// the current output stream.
00335 ///
00336 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
00337   MCInst TmpInst;
00338   
00339   // Lower multi-instruction pseudo operations.
00340   switch (MI->getOpcode()) {
00341   default: break;
00342   case TargetOpcode::DBG_VALUE: {
00343     if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return;
00344       
00345     SmallString<32> Str;
00346     raw_svector_ostream O(Str);
00347     unsigned NOps = MI->getNumOperands();
00348     assert(NOps==4);
00349     O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
00350     // cast away const; DIetc do not take const operands for some reason.
00351     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
00352     O << V.getName();
00353     O << " <- ";
00354     // Frame address.  Currently handles register +- offset only.
00355     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
00356     O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O);
00357     O << ']';
00358     O << "+";
00359     printOperand(MI, NOps-2, O);
00360     OutStreamer.EmitRawText(O.str());
00361     return;
00362   }
00363       
00364   case PPC::MovePCtoLR:
00365   case PPC::MovePCtoLR8: {
00366     // Transform %LR = MovePCtoLR
00367     // Into this, where the label is the PIC base: 
00368     //     bl L1$pb
00369     // L1$pb:
00370     MCSymbol *PICBase = MF->getPICBaseSymbol();
00371     
00372     // Emit the 'bl'.
00373     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL)
00374       // FIXME: We would like an efficient form for this, so we don't have to do
00375       // a lot of extra uniquing.
00376       .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
00377     
00378     // Emit the label.
00379     OutStreamer.EmitLabel(PICBase);
00380     return;
00381   }
00382   case PPC::LDtocJTI:
00383   case PPC::LDtocCPT:
00384   case PPC::LDtoc: {
00385     // Transform %X3 = LDtoc <ga:@min1>, %X2
00386     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00387 
00388     // Change the opcode to LD, and the global address operand to be a
00389     // reference to the TOC entry we will synthesize later.
00390     TmpInst.setOpcode(PPC::LD);
00391     const MachineOperand &MO = MI->getOperand(1);
00392 
00393     // Map symbol -> label of TOC entry
00394     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
00395     MCSymbol *MOSymbol = 0;
00396     if (MO.isGlobal())
00397       MOSymbol = Mang->getSymbol(MO.getGlobal());
00398     else if (MO.isCPI())
00399       MOSymbol = GetCPISymbol(MO.getIndex());
00400     else if (MO.isJTI())
00401       MOSymbol = GetJTISymbol(MO.getIndex());
00402 
00403     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
00404 
00405     const MCExpr *Exp =
00406       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
00407                               OutContext);
00408     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00409     OutStreamer.EmitInstruction(TmpInst);
00410     return;
00411   }
00412       
00413   case PPC::ADDIStocHA: {
00414     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
00415     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00416 
00417     // Change the opcode to ADDIS8.  If the global address is external,
00418     // has common linkage, is a function address, or is a jump table
00419     // address, then generate a TOC entry and reference that.  Otherwise
00420     // reference the symbol directly.
00421     TmpInst.setOpcode(PPC::ADDIS8);
00422     const MachineOperand &MO = MI->getOperand(2);
00423     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
00424            "Invalid operand for ADDIStocHA!");
00425     MCSymbol *MOSymbol = 0;
00426     bool IsExternal = false;
00427     bool IsFunction = false;
00428     bool IsCommon = false;
00429     bool IsAvailExt = false;
00430 
00431     if (MO.isGlobal()) {
00432       const GlobalValue *GValue = MO.getGlobal();
00433       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
00434       const GlobalValue *RealGValue = GAlias ?
00435         GAlias->resolveAliasedGlobal(false) : GValue;
00436       MOSymbol = Mang->getSymbol(RealGValue);
00437       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
00438       IsExternal = GVar && !GVar->hasInitializer();
00439       IsCommon = GVar && RealGValue->hasCommonLinkage();
00440       IsFunction = !GVar;
00441       IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage();
00442     } else if (MO.isCPI())
00443       MOSymbol = GetCPISymbol(MO.getIndex());
00444     else if (MO.isJTI())
00445       MOSymbol = GetJTISymbol(MO.getIndex());
00446 
00447     if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI())
00448       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00449 
00450     const MCExpr *Exp =
00451       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA,
00452                               OutContext);
00453     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
00454     OutStreamer.EmitInstruction(TmpInst);
00455     return;
00456   }
00457   case PPC::LDtocL: {
00458     // Transform %Xd = LDtocL <ga:@sym>, %Xs
00459     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00460 
00461     // Change the opcode to LD.  If the global address is external, has
00462     // common linkage, or is a jump table address, then reference the
00463     // associated TOC entry.  Otherwise reference the symbol directly.
00464     TmpInst.setOpcode(PPC::LD);
00465     const MachineOperand &MO = MI->getOperand(1);
00466     assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) &&
00467            "Invalid operand for LDtocL!");
00468     MCSymbol *MOSymbol = 0;
00469 
00470     if (MO.isJTI())
00471       MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
00472     else if (MO.isCPI())
00473       MOSymbol = GetCPISymbol(MO.getIndex());
00474     else if (MO.isGlobal()) {
00475       const GlobalValue *GValue = MO.getGlobal();
00476       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
00477       const GlobalValue *RealGValue = GAlias ?
00478         GAlias->resolveAliasedGlobal(false) : GValue;
00479       MOSymbol = Mang->getSymbol(RealGValue);
00480       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
00481     
00482       if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() ||
00483           RealGValue->hasAvailableExternallyLinkage())
00484         MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00485     }
00486 
00487     const MCExpr *Exp =
00488       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
00489                               OutContext);
00490     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00491     OutStreamer.EmitInstruction(TmpInst);
00492     return;
00493   }
00494   case PPC::ADDItocL: {
00495     // Transform %Xd = ADDItocL %Xs, <ga:@sym>
00496     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00497 
00498     // Change the opcode to ADDI8.  If the global address is external, then
00499     // generate a TOC entry and reference that.  Otherwise reference the
00500     // symbol directly.
00501     TmpInst.setOpcode(PPC::ADDI8);
00502     const MachineOperand &MO = MI->getOperand(2);
00503     assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
00504     MCSymbol *MOSymbol = 0;
00505     bool IsExternal = false;
00506     bool IsFunction = false;
00507 
00508     if (MO.isGlobal()) {
00509       const GlobalValue *GValue = MO.getGlobal();
00510       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
00511       const GlobalValue *RealGValue = GAlias ?
00512         GAlias->resolveAliasedGlobal(false) : GValue;
00513       MOSymbol = Mang->getSymbol(RealGValue);
00514       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
00515       IsExternal = GVar && !GVar->hasInitializer();
00516       IsFunction = !GVar;
00517     } else if (MO.isCPI())
00518       MOSymbol = GetCPISymbol(MO.getIndex());
00519 
00520     if (IsFunction || IsExternal)
00521       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00522 
00523     const MCExpr *Exp =
00524       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO,
00525                               OutContext);
00526     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
00527     OutStreamer.EmitInstruction(TmpInst);
00528     return;
00529   }
00530   case PPC::ADDISgotTprelHA: {
00531     // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
00532     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
00533     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00534     const MachineOperand &MO = MI->getOperand(2);
00535     const GlobalValue *GValue = MO.getGlobal();
00536     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00537     const MCExpr *SymGotTprel =
00538       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA,
00539                               OutContext);
00540     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
00541                                 .addReg(MI->getOperand(0).getReg())
00542                                 .addReg(PPC::X2)
00543                                 .addExpr(SymGotTprel));
00544     return;
00545   }
00546   case PPC::LDgotTprelL: {
00547     // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
00548     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00549 
00550     // Change the opcode to LD.
00551     TmpInst.setOpcode(PPC::LD);
00552     const MachineOperand &MO = MI->getOperand(1);
00553     const GlobalValue *GValue = MO.getGlobal();
00554     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00555     const MCExpr *Exp =
00556       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO,
00557                               OutContext);
00558     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00559     OutStreamer.EmitInstruction(TmpInst);
00560     return;
00561   }
00562   case PPC::ADDIStlsgdHA: {
00563     // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
00564     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
00565     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00566     const MachineOperand &MO = MI->getOperand(2);
00567     const GlobalValue *GValue = MO.getGlobal();
00568     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00569     const MCExpr *SymGotTlsGD =
00570       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA,
00571                               OutContext);
00572     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
00573                                 .addReg(MI->getOperand(0).getReg())
00574                                 .addReg(PPC::X2)
00575                                 .addExpr(SymGotTlsGD));
00576     return;
00577   }
00578   case PPC::ADDItlsgdL: {
00579     // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
00580     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsgd@l
00581     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00582     const MachineOperand &MO = MI->getOperand(2);
00583     const GlobalValue *GValue = MO.getGlobal();
00584     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00585     const MCExpr *SymGotTlsGD =
00586       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO,
00587                               OutContext);
00588     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
00589                                 .addReg(MI->getOperand(0).getReg())
00590                                 .addReg(MI->getOperand(1).getReg())
00591                                 .addExpr(SymGotTlsGD));
00592     return;
00593   }
00594   case PPC::GETtlsADDR: {
00595     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
00596     // Into:      BL8_NOP_TLSGD __tls_get_addr(sym@tlsgd)
00597     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00598 
00599     StringRef Name = "__tls_get_addr";
00600     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
00601     const MCSymbolRefExpr *TlsRef = 
00602       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
00603     const MachineOperand &MO = MI->getOperand(2);
00604     const GlobalValue *GValue = MO.getGlobal();
00605     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00606     const MCExpr *SymVar =
00607       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
00608                               OutContext);
00609     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSGD)
00610                                 .addExpr(TlsRef)
00611                                 .addExpr(SymVar));
00612     return;
00613   }
00614   case PPC::ADDIStlsldHA: {
00615     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
00616     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
00617     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00618     const MachineOperand &MO = MI->getOperand(2);
00619     const GlobalValue *GValue = MO.getGlobal();
00620     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00621     const MCExpr *SymGotTlsLD =
00622       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA,
00623                               OutContext);
00624     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
00625                                 .addReg(MI->getOperand(0).getReg())
00626                                 .addReg(PPC::X2)
00627                                 .addExpr(SymGotTlsLD));
00628     return;
00629   }
00630   case PPC::ADDItlsldL: {
00631     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
00632     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
00633     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00634     const MachineOperand &MO = MI->getOperand(2);
00635     const GlobalValue *GValue = MO.getGlobal();
00636     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00637     const MCExpr *SymGotTlsLD =
00638       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO,
00639                               OutContext);
00640     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
00641                                 .addReg(MI->getOperand(0).getReg())
00642                                 .addReg(MI->getOperand(1).getReg())
00643                                 .addExpr(SymGotTlsLD));
00644     return;
00645   }
00646   case PPC::GETtlsldADDR: {
00647     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
00648     // Into:      BL8_NOP_TLSLD __tls_get_addr(sym@tlsld)
00649     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00650 
00651     StringRef Name = "__tls_get_addr";
00652     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
00653     const MCSymbolRefExpr *TlsRef = 
00654       MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
00655     const MachineOperand &MO = MI->getOperand(2);
00656     const GlobalValue *GValue = MO.getGlobal();
00657     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00658     const MCExpr *SymVar =
00659       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
00660                               OutContext);
00661     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSLD)
00662                                 .addExpr(TlsRef)
00663                                 .addExpr(SymVar));
00664     return;
00665   }
00666   case PPC::ADDISdtprelHA: {
00667     // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
00668     // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
00669     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00670     const MachineOperand &MO = MI->getOperand(2);
00671     const GlobalValue *GValue = MO.getGlobal();
00672     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00673     const MCExpr *SymDtprel =
00674       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA,
00675                               OutContext);
00676     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
00677                                 .addReg(MI->getOperand(0).getReg())
00678                                 .addReg(PPC::X3)
00679                                 .addExpr(SymDtprel));
00680     return;
00681   }
00682   case PPC::ADDIdtprelL: {
00683     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
00684     // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
00685     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00686     const MachineOperand &MO = MI->getOperand(2);
00687     const GlobalValue *GValue = MO.getGlobal();
00688     MCSymbol *MOSymbol = Mang->getSymbol(GValue);
00689     const MCExpr *SymDtprel =
00690       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO,
00691                               OutContext);
00692     OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8)
00693                                 .addReg(MI->getOperand(0).getReg())
00694                                 .addReg(MI->getOperand(1).getReg())
00695                                 .addExpr(SymDtprel));
00696     return;
00697   }
00698   case PPC::MFCRpseud:
00699   case PPC::MFCR8pseud:
00700     // Transform: %R3 = MFCRpseud %CR7
00701     // Into:      %R3 = MFCR      ;; cr7
00702     OutStreamer.AddComment(PPCInstPrinter::
00703                            getRegisterName(MI->getOperand(1).getReg()));
00704     OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR)
00705       .addReg(MI->getOperand(0).getReg()));
00706     return;
00707   case PPC::SYNC:
00708     // In Book E sync is called msync, handle this special case here...
00709     if (Subtarget.isBookE()) {
00710       OutStreamer.EmitRawText(StringRef("\tmsync"));
00711       return;
00712     }
00713   }
00714 
00715   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00716   OutStreamer.EmitInstruction(TmpInst);
00717 }
00718 
00719 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
00720   if (!Subtarget.isPPC64())  // linux/ppc32 - Normal entry label.
00721     return AsmPrinter::EmitFunctionEntryLabel();
00722     
00723   // Emit an official procedure descriptor.
00724   MCSectionSubPair Current = OutStreamer.getCurrentSection();
00725   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
00726       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00727       SectionKind::getReadOnly());
00728   OutStreamer.SwitchSection(Section);
00729   OutStreamer.EmitLabel(CurrentFnSym);
00730   OutStreamer.EmitValueToAlignment(8);
00731   MCSymbol *Symbol1 = 
00732     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
00733   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
00734   // entry point.
00735   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
00736       8 /*size*/);
00737   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
00738   // Generates a R_PPC64_TOC relocation for TOC base insertion.
00739   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
00740                         MCSymbolRefExpr::VK_PPC_TOC, OutContext),
00741                         8/*size*/);
00742   // Emit a null environment pointer.
00743   OutStreamer.EmitIntValue(0, 8 /* size */);
00744   OutStreamer.SwitchSection(Current.first, Current.second);
00745 
00746   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
00747                           ".L." + Twine(CurrentFnSym->getName()));
00748   OutStreamer.EmitLabel(RealFnSym);
00749   CurrentFnSymForSize = RealFnSym;
00750 }
00751 
00752 
00753 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
00754   const DataLayout *TD = TM.getDataLayout();
00755 
00756   bool isPPC64 = TD->getPointerSizeInBits() == 64;
00757 
00758   if (isPPC64 && !TOC.empty()) {
00759     const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
00760         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00761         SectionKind::getReadOnly());
00762     OutStreamer.SwitchSection(Section);
00763 
00764     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
00765          E = TOC.end(); I != E; ++I) {
00766       OutStreamer.EmitLabel(I->second);
00767       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
00768       OutStreamer.EmitTCEntry(*S);
00769     }
00770   }
00771 
00772   MachineModuleInfoELF &MMIELF =
00773     MMI->getObjFileInfo<MachineModuleInfoELF>();
00774 
00775   MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
00776   if (!Stubs.empty()) {
00777     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
00778     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
00779       // L_foo$stub:
00780       OutStreamer.EmitLabel(Stubs[i].first);
00781       //   .long _foo
00782       OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
00783                                                     OutContext),
00784                             isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
00785     }
00786 
00787     Stubs.clear();
00788     OutStreamer.AddBlankLine();
00789   }
00790 
00791   return AsmPrinter::doFinalization(M);
00792 }
00793 
00794 /// EmitFunctionBodyEnd - Print the traceback table before the .size
00795 /// directive.
00796 ///
00797 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
00798   // Only the 64-bit target requires a traceback table.  For now,
00799   // we only emit the word of zeroes that GDB requires to find
00800   // the end of the function, and zeroes for the eight-byte
00801   // mandatory fields.
00802   // FIXME: We should fill in the eight-byte mandatory fields as described in
00803   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
00804   // currently make use of these fields).
00805   if (Subtarget.isPPC64()) {
00806     OutStreamer.EmitIntValue(0, 4/*size*/);
00807     OutStreamer.EmitIntValue(0, 8/*size*/);
00808   }
00809 }
00810 
00811 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
00812   static const char *const CPUDirectives[] = {
00813     "",
00814     "ppc",
00815     "ppc440",
00816     "ppc601",
00817     "ppc602",
00818     "ppc603",
00819     "ppc7400",
00820     "ppc750",
00821     "ppc970",
00822     "ppcA2",
00823     "ppce500mc",
00824     "ppce5500",
00825     "power3",
00826     "power4",
00827     "power5",
00828     "power5x",
00829     "power6",
00830     "power6x",
00831     "power7",
00832     "ppc64"
00833   };
00834 
00835   unsigned Directive = Subtarget.getDarwinDirective();
00836   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
00837     Directive = PPC::DIR_970;
00838   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
00839     Directive = PPC::DIR_7400;
00840   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
00841     Directive = PPC::DIR_64;
00842   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
00843   
00844   // FIXME: This is a total hack, finish mc'izing the PPC backend.
00845   if (OutStreamer.hasRawTextSupport()) {
00846     assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) &&
00847            "CPUDirectives[] might not be up-to-date!");
00848     OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive]));
00849   }
00850 
00851   // Prime text sections so they are adjacent.  This reduces the likelihood a
00852   // large data or debug section causes a branch to exceed 16M limit.
00853   const TargetLoweringObjectFileMachO &TLOFMacho = 
00854     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
00855   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
00856   if (TM.getRelocationModel() == Reloc::PIC_) {
00857     OutStreamer.SwitchSection(
00858            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
00859                                       MCSectionMachO::S_SYMBOL_STUBS |
00860                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
00861                                       32, SectionKind::getText()));
00862   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
00863     OutStreamer.SwitchSection(
00864            OutContext.getMachOSection("__TEXT","__symbol_stub1",
00865                                       MCSectionMachO::S_SYMBOL_STUBS |
00866                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
00867                                       16, SectionKind::getText()));
00868   }
00869   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
00870 }
00871 
00872 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
00873   // Remove $stub suffix, add $lazy_ptr.
00874   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
00875   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
00876 }
00877 
00878 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
00879   // Add $tmp suffix to $stub, yielding $stub$tmp.
00880   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
00881 }
00882 
00883 void PPCDarwinAsmPrinter::
00884 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
00885   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
00886   
00887   const TargetLoweringObjectFileMachO &TLOFMacho = 
00888     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
00889 
00890   // .lazy_symbol_pointer
00891   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
00892   
00893   // Output stubs for dynamically-linked functions
00894   if (TM.getRelocationModel() == Reloc::PIC_) {
00895     const MCSection *StubSection = 
00896     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
00897                                MCSectionMachO::S_SYMBOL_STUBS |
00898                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
00899                                32, SectionKind::getText());
00900     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
00901       OutStreamer.SwitchSection(StubSection);
00902       EmitAlignment(4);
00903       
00904       MCSymbol *Stub = Stubs[i].first;
00905       MCSymbol *RawSym = Stubs[i].second.getPointer();
00906       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
00907       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
00908                                            
00909       OutStreamer.EmitLabel(Stub);
00910       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
00911 
00912       const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
00913 
00914       // mflr r0
00915       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
00916       // bcl 20, 31, AnonSymbol
00917       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon));
00918       OutStreamer.EmitLabel(AnonSymbol);
00919       // mflr r11
00920       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
00921       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
00922       const MCExpr *Sub =
00923         MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext),
00924                                 Anon, OutContext);
00925       OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS)
00926         .addReg(PPC::R11)
00927         .addReg(PPC::R11)
00928         .addExpr(Sub));
00929       // mtlr r0
00930       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
00931 
00932       // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
00933       // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
00934       OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
00935         .addReg(PPC::R12)
00936         .addExpr(Sub).addExpr(Sub)
00937         .addReg(PPC::R11));
00938       // mtctr r12
00939       OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
00940       // bctr
00941       OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
00942 
00943       OutStreamer.SwitchSection(LSPSection);
00944       OutStreamer.EmitLabel(LazyPtr);
00945       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
00946 
00947       MCSymbol *DyldStubBindingHelper =
00948         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
00949       if (isPPC64) {
00950         // .quad dyld_stub_binding_helper
00951         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
00952       } else {
00953         // .long dyld_stub_binding_helper
00954         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
00955       }
00956     }
00957     OutStreamer.AddBlankLine();
00958     return;
00959   }
00960   
00961   const MCSection *StubSection =
00962     OutContext.getMachOSection("__TEXT","__symbol_stub1",
00963                                MCSectionMachO::S_SYMBOL_STUBS |
00964                                MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
00965                                16, SectionKind::getText());
00966   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
00967     MCSymbol *Stub = Stubs[i].first;
00968     MCSymbol *RawSym = Stubs[i].second.getPointer();
00969     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
00970 
00971     OutStreamer.SwitchSection(StubSection);
00972     EmitAlignment(4);
00973     OutStreamer.EmitLabel(Stub);
00974     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
00975     // lis r11, ha16(LazyPtr)
00976     const MCExpr *LazyPtrHa16 =
00977       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16,
00978                               OutContext);
00979     OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS)
00980       .addReg(PPC::R11)
00981       .addExpr(LazyPtrHa16));
00982 
00983     const MCExpr *LazyPtrLo16 =
00984       MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16,
00985                               OutContext);
00986     // ldu r12, lo16(LazyPtr)(r11)
00987     // lwzu r12, lo16(LazyPtr)(r11)
00988     OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
00989       .addReg(PPC::R12)
00990       .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
00991       .addReg(PPC::R11));
00992 
00993     // mtctr r12
00994     OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
00995     // bctr
00996     OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR));
00997 
00998     OutStreamer.SwitchSection(LSPSection);
00999     OutStreamer.EmitLabel(LazyPtr);
01000     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
01001 
01002     MCSymbol *DyldStubBindingHelper =
01003       OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
01004     if (isPPC64) {
01005       // .quad dyld_stub_binding_helper
01006       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
01007     } else {
01008       // .long dyld_stub_binding_helper
01009       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
01010     }
01011   }
01012   
01013   OutStreamer.AddBlankLine();
01014 }
01015 
01016 
01017 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
01018   bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64;
01019 
01020   // Darwin/PPC always uses mach-o.
01021   const TargetLoweringObjectFileMachO &TLOFMacho = 
01022     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
01023   MachineModuleInfoMachO &MMIMacho =
01024     MMI->getObjFileInfo<MachineModuleInfoMachO>();
01025   
01026   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
01027   if (!Stubs.empty())
01028     EmitFunctionStubs(Stubs);
01029 
01030   if (MAI->doesSupportExceptionHandling() && MMI) {
01031     // Add the (possibly multiple) personalities to the set of global values.
01032     // Only referenced functions get into the Personalities list.
01033     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
01034     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
01035          E = Personalities.end(); I != E; ++I) {
01036       if (*I) {
01037         MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
01038         MachineModuleInfoImpl::StubValueTy &StubSym =
01039           MMIMacho.getGVStubEntry(NLPSym);
01040         StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true);
01041       }
01042     }
01043   }
01044 
01045   // Output stubs for dynamically-linked functions.
01046   Stubs = MMIMacho.GetGVStubList();
01047   
01048   // Output macho stubs for external and common global variables.
01049   if (!Stubs.empty()) {
01050     // Switch with ".non_lazy_symbol_pointer" directive.
01051     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
01052     EmitAlignment(isPPC64 ? 3 : 2);
01053     
01054     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01055       // L_foo$stub:
01056       OutStreamer.EmitLabel(Stubs[i].first);
01057       //   .indirect_symbol _foo
01058       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
01059       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
01060 
01061       if (MCSym.getInt())
01062         // External to current translation unit.
01063         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
01064       else
01065         // Internal to current translation unit.
01066         //
01067         // When we place the LSDA into the TEXT section, the type info pointers
01068         // need to be indirect and pc-rel. We accomplish this by using NLPs.
01069         // However, sometimes the types are local to the file. So we need to
01070         // fill in the value for the NLP in those cases.
01071         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
01072                                                       OutContext),
01073                               isPPC64 ? 8 : 4/*size*/);
01074     }
01075 
01076     Stubs.clear();
01077     OutStreamer.AddBlankLine();
01078   }
01079 
01080   Stubs = MMIMacho.GetHiddenGVStubList();
01081   if (!Stubs.empty()) {
01082     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
01083     EmitAlignment(isPPC64 ? 3 : 2);
01084     
01085     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01086       // L_foo$stub:
01087       OutStreamer.EmitLabel(Stubs[i].first);
01088       //   .long _foo
01089       OutStreamer.EmitValue(MCSymbolRefExpr::
01090                             Create(Stubs[i].second.getPointer(),
01091                                    OutContext),
01092                             isPPC64 ? 8 : 4/*size*/);
01093     }
01094 
01095     Stubs.clear();
01096     OutStreamer.AddBlankLine();
01097   }
01098 
01099   // Funny Darwin hack: This flag tells the linker that no global symbols
01100   // contain code that falls through to other global symbols (e.g. the obvious
01101   // implementation of multiple entry points).  If this doesn't occur, the
01102   // linker can safely perform dead code stripping.  Since LLVM never generates
01103   // code that does this, it is always safe to set.
01104   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
01105 
01106   return AsmPrinter::doFinalization(M);
01107 }
01108 
01109 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
01110 /// for a MachineFunction to the given output stream, in a format that the
01111 /// Darwin assembler can deal with.
01112 ///
01113 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
01114                                            MCStreamer &Streamer) {
01115   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
01116 
01117   if (Subtarget->isDarwin())
01118     return new PPCDarwinAsmPrinter(tm, Streamer);
01119   return new PPCLinuxAsmPrinter(tm, Streamer);
01120 }
01121 
01122 // Force static initialization.
01123 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
01124   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
01125   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
01126 }