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 #include "PPC.h"
00020 #include "InstPrinter/PPCInstPrinter.h"
00021 #include "PPCMachineFunctionInfo.h"
00022 #include "MCTargetDesc/PPCMCExpr.h"
00023 #include "MCTargetDesc/PPCPredicates.h"
00024 #include "PPCSubtarget.h"
00025 #include "PPCTargetMachine.h"
00026 #include "PPCTargetStreamer.h"
00027 #include "llvm/ADT/MapVector.h"
00028 #include "llvm/ADT/SmallString.h"
00029 #include "llvm/ADT/StringExtras.h"
00030 #include "llvm/CodeGen/AsmPrinter.h"
00031 #include "llvm/CodeGen/MachineConstantPool.h"
00032 #include "llvm/CodeGen/MachineFunctionPass.h"
00033 #include "llvm/CodeGen/MachineInstr.h"
00034 #include "llvm/CodeGen/MachineInstrBuilder.h"
00035 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
00036 #include "llvm/CodeGen/MachineRegisterInfo.h"
00037 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
00038 #include "llvm/IR/Constants.h"
00039 #include "llvm/IR/DebugInfo.h"
00040 #include "llvm/IR/DerivedTypes.h"
00041 #include "llvm/IR/Mangler.h"
00042 #include "llvm/IR/Module.h"
00043 #include "llvm/MC/MCAsmInfo.h"
00044 #include "llvm/MC/MCContext.h"
00045 #include "llvm/MC/MCExpr.h"
00046 #include "llvm/MC/MCInst.h"
00047 #include "llvm/MC/MCInstBuilder.h"
00048 #include "llvm/MC/MCSectionELF.h"
00049 #include "llvm/MC/MCSectionMachO.h"
00050 #include "llvm/MC/MCStreamer.h"
00051 #include "llvm/MC/MCSymbol.h"
00052 #include "llvm/Support/CommandLine.h"
00053 #include "llvm/Support/Debug.h"
00054 #include "llvm/Support/ELF.h"
00055 #include "llvm/Support/ErrorHandling.h"
00056 #include "llvm/Support/MathExtras.h"
00057 #include "llvm/Support/TargetRegistry.h"
00058 #include "llvm/Support/raw_ostream.h"
00059 #include "llvm/Target/TargetInstrInfo.h"
00060 #include "llvm/Target/TargetOptions.h"
00061 #include "llvm/Target/TargetRegisterInfo.h"
00062 using namespace llvm;
00063 
00064 #define DEBUG_TYPE "asmprinter"
00065 
00066 namespace {
00067   class PPCAsmPrinter : public AsmPrinter {
00068   protected:
00069     MapVector<MCSymbol*, MCSymbol*> TOC;
00070     const PPCSubtarget &Subtarget;
00071     uint64_t TOCLabelID;
00072   public:
00073     explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00074       : AsmPrinter(TM, Streamer),
00075         Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {}
00076 
00077     const char *getPassName() const override {
00078       return "PowerPC Assembly Printer";
00079     }
00080 
00081     MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
00082 
00083     void EmitInstruction(const MachineInstr *MI) override;
00084 
00085     void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
00086 
00087     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00088                          unsigned AsmVariant, const char *ExtraCode,
00089                          raw_ostream &O) override;
00090     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00091                                unsigned AsmVariant, const char *ExtraCode,
00092                                raw_ostream &O) override;
00093   };
00094 
00095   /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
00096   class PPCLinuxAsmPrinter : public PPCAsmPrinter {
00097   public:
00098     explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00099       : PPCAsmPrinter(TM, Streamer) {}
00100 
00101     const char *getPassName() const override {
00102       return "Linux PPC Assembly Printer";
00103     }
00104 
00105     bool doFinalization(Module &M) override;
00106     void EmitStartOfAsmFile(Module &M) override;
00107 
00108     void EmitFunctionEntryLabel() override;
00109 
00110     void EmitFunctionBodyStart() override;
00111     void EmitFunctionBodyEnd() override;
00112   };
00113 
00114   /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
00115   /// OS X
00116   class PPCDarwinAsmPrinter : public PPCAsmPrinter {
00117   public:
00118     explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
00119       : PPCAsmPrinter(TM, Streamer) {}
00120 
00121     const char *getPassName() const override {
00122       return "Darwin PPC Assembly Printer";
00123     }
00124 
00125     bool doFinalization(Module &M) override;
00126     void EmitStartOfAsmFile(Module &M) override;
00127 
00128     void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs);
00129   };
00130 } // end of anonymous namespace
00131 
00132 /// stripRegisterPrefix - This method strips the character prefix from a
00133 /// register name so that only the number is left.  Used by for linux asm.
00134 static const char *stripRegisterPrefix(const char *RegName) {
00135   switch (RegName[0]) {
00136     case 'r':
00137     case 'f':
00138     case 'v':
00139       if (RegName[1] == 's')
00140         return RegName + 2;
00141       return RegName + 1;
00142     case 'c': if (RegName[1] == 'r') return RegName + 2;
00143   }
00144   
00145   return RegName;
00146 }
00147 
00148 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
00149                                  raw_ostream &O) {
00150   const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
00151   const MachineOperand &MO = MI->getOperand(OpNo);
00152   
00153   switch (MO.getType()) {
00154   case MachineOperand::MO_Register: {
00155     const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
00156     // Linux assembler (Others?) does not take register mnemonics.
00157     // FIXME - What about special registers used in mfspr/mtspr?
00158     if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
00159     O << RegName;
00160     return;
00161   }
00162   case MachineOperand::MO_Immediate:
00163     O << MO.getImm();
00164     return;
00165 
00166   case MachineOperand::MO_MachineBasicBlock:
00167     O << *MO.getMBB()->getSymbol();
00168     return;
00169   case MachineOperand::MO_ConstantPoolIndex:
00170     O << DL->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
00171       << '_' << MO.getIndex();
00172     return;
00173   case MachineOperand::MO_BlockAddress:
00174     O << *GetBlockAddressSymbol(MO.getBlockAddress());
00175     return;
00176   case MachineOperand::MO_GlobalAddress: {
00177     // Computing the address of a global symbol, not calling it.
00178     const GlobalValue *GV = MO.getGlobal();
00179     MCSymbol *SymToPrint;
00180 
00181     // External or weakly linked global variables need non-lazily-resolved stubs
00182     if (TM.getRelocationModel() != Reloc::Static &&
00183         (GV->isDeclaration() || GV->isWeakForLinker())) {
00184       if (!GV->hasHiddenVisibility()) {
00185         SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
00186         MachineModuleInfoImpl::StubValueTy &StubSym = 
00187           MMI->getObjFileInfo<MachineModuleInfoMachO>()
00188             .getGVStubEntry(SymToPrint);
00189         if (!StubSym.getPointer())
00190           StubSym = MachineModuleInfoImpl::
00191             StubValueTy(getSymbol(GV), !GV->hasInternalLinkage());
00192       } else if (GV->isDeclaration() || GV->hasCommonLinkage() ||
00193                  GV->hasAvailableExternallyLinkage()) {
00194         SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
00195         
00196         MachineModuleInfoImpl::StubValueTy &StubSym = 
00197           MMI->getObjFileInfo<MachineModuleInfoMachO>().
00198                     getHiddenGVStubEntry(SymToPrint);
00199         if (!StubSym.getPointer())
00200           StubSym = MachineModuleInfoImpl::
00201             StubValueTy(getSymbol(GV), !GV->hasInternalLinkage());
00202       } else {
00203         SymToPrint = getSymbol(GV);
00204       }
00205     } else {
00206       SymToPrint = getSymbol(GV);
00207     }
00208     
00209     O << *SymToPrint;
00210 
00211     printOffset(MO.getOffset(), O);
00212     return;
00213   }
00214 
00215   default:
00216     O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
00217     return;
00218   }
00219 }
00220 
00221 /// PrintAsmOperand - Print out an operand for an inline asm expression.
00222 ///
00223 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00224                                     unsigned AsmVariant,
00225                                     const char *ExtraCode, raw_ostream &O) {
00226   // Does this asm operand have a single letter operand modifier?
00227   if (ExtraCode && ExtraCode[0]) {
00228     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00229 
00230     switch (ExtraCode[0]) {
00231     default:
00232       // See if this is a generic print operand
00233       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
00234     case 'c': // Don't print "$" before a global var name or constant.
00235       break; // PPC never has a prefix.
00236     case 'L': // Write second word of DImode reference.
00237       // Verify that this operand has two consecutive registers.
00238       if (!MI->getOperand(OpNo).isReg() ||
00239           OpNo+1 == MI->getNumOperands() ||
00240           !MI->getOperand(OpNo+1).isReg())
00241         return true;
00242       ++OpNo;   // Return the high-part.
00243       break;
00244     case 'I':
00245       // Write 'i' if an integer constant, otherwise nothing.  Used to print
00246       // addi vs add, etc.
00247       if (MI->getOperand(OpNo).isImm())
00248         O << "i";
00249       return false;
00250     }
00251   }
00252 
00253   printOperand(MI, OpNo, O);
00254   return false;
00255 }
00256 
00257 // At the moment, all inline asm memory operands are a single register.
00258 // In any case, the output of this routine should always be just one
00259 // assembler operand.
00260 
00261 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00262                                           unsigned AsmVariant,
00263                                           const char *ExtraCode,
00264                                           raw_ostream &O) {
00265   if (ExtraCode && ExtraCode[0]) {
00266     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00267 
00268     switch (ExtraCode[0]) {
00269     default: return true;  // Unknown modifier.
00270     case 'y': // A memory reference for an X-form instruction
00271       {
00272         const char *RegName = "r0";
00273         if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
00274         O << RegName << ", ";
00275         printOperand(MI, OpNo, O);
00276         return false;
00277       }
00278     case 'U': // Print 'u' for update form.
00279     case 'X': // Print 'x' for indexed form.
00280       {
00281   // FIXME: Currently for PowerPC memory operands are always loaded
00282   // into a register, so we never get an update or indexed form.
00283   // This is bad even for offset forms, since even if we know we
00284   // have a value in -16(r1), we will generate a load into r<n>
00285   // and then load from 0(r<n>).  Until that issue is fixed,
00286   // tolerate 'U' and 'X' but don't output anything.
00287   assert(MI->getOperand(OpNo).isReg());
00288   return false;
00289       }
00290     }
00291   }
00292 
00293   assert(MI->getOperand(OpNo).isReg());
00294   O << "0(";
00295   printOperand(MI, OpNo, O);
00296   O << ")";
00297   return false;
00298 }
00299 
00300 
00301 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
00302 /// exists for it.  If not, create one.  Then return a symbol that references
00303 /// the TOC entry.
00304 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
00305   const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
00306   MCSymbol *&TOCEntry = TOC[Sym];
00307 
00308   // To avoid name clash check if the name already exists.
00309   while (!TOCEntry) {
00310     if (OutContext.LookupSymbol(Twine(DL->getPrivateGlobalPrefix()) +
00311                                 "C" + Twine(TOCLabelID++)) == nullptr) {
00312       TOCEntry = GetTempSymbol("C", TOCLabelID);
00313     }
00314   }
00315 
00316   return TOCEntry;
00317 }
00318 
00319 
00320 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
00321 /// the current output stream.
00322 ///
00323 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
00324   MCInst TmpInst;
00325   bool isPPC64 = Subtarget.isPPC64();
00326   
00327   // Lower multi-instruction pseudo operations.
00328   switch (MI->getOpcode()) {
00329   default: break;
00330   case TargetOpcode::DBG_VALUE:
00331     llvm_unreachable("Should be handled target independently");
00332   case PPC::MovePCtoLR:
00333   case PPC::MovePCtoLR8: {
00334     // Transform %LR = MovePCtoLR
00335     // Into this, where the label is the PIC base: 
00336     //     bl L1$pb
00337     // L1$pb:
00338     MCSymbol *PICBase = MF->getPICBaseSymbol();
00339     
00340     // Emit the 'bl'.
00341     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL)
00342       // FIXME: We would like an efficient form for this, so we don't have to do
00343       // a lot of extra uniquing.
00344       .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
00345     
00346     // Emit the label.
00347     OutStreamer.EmitLabel(PICBase);
00348     return;
00349   }
00350   case PPC::GetGBRO: {
00351     // Get the offset from the GOT Base Register to the GOT
00352     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00353     MCSymbol *PICOffset = MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
00354     TmpInst.setOpcode(PPC::LWZ);
00355     const MCExpr *Exp =
00356       MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
00357     const MCExpr *PB =
00358       MCSymbolRefExpr::Create(MF->getPICBaseSymbol(),
00359                               MCSymbolRefExpr::VK_None,
00360                               OutContext);
00361     const MCOperand MO = TmpInst.getOperand(1);
00362     TmpInst.getOperand(1) = MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp,
00363                                                                           PB,
00364                                                                           OutContext));
00365     TmpInst.addOperand(MO);
00366     EmitToStreamer(OutStreamer, TmpInst);
00367     return;
00368   }
00369   case PPC::UpdateGBR: {
00370     // Update the GOT Base Register to point to the GOT.  It may be possible to
00371     // merge this with the PPC::GetGBRO, doing it all in one step.
00372     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00373     TmpInst.setOpcode(PPC::ADD4);
00374     TmpInst.addOperand(TmpInst.getOperand(0));
00375     EmitToStreamer(OutStreamer, TmpInst);
00376     return;
00377   }
00378   case PPC::LWZtoc: {
00379     // Transform %X3 = LWZtoc <ga:@min1>, %X2
00380     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00381 
00382     // Change the opcode to LWZ, and the global address operand to be a
00383     // reference to the GOT entry we will synthesize later.
00384     TmpInst.setOpcode(PPC::LWZ);
00385     const MachineOperand &MO = MI->getOperand(1);
00386 
00387     // Map symbol -> label of TOC entry
00388     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
00389     MCSymbol *MOSymbol = nullptr;
00390     if (MO.isGlobal())
00391       MOSymbol = getSymbol(MO.getGlobal());
00392     else if (MO.isCPI())
00393       MOSymbol = GetCPISymbol(MO.getIndex());
00394     else if (MO.isJTI())
00395       MOSymbol = GetJTISymbol(MO.getIndex());
00396 
00397     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
00398 
00399     const MCExpr *Exp =
00400       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None,
00401                               OutContext);
00402     const MCExpr *PB =
00403       MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
00404                                                            OutContext);
00405     Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext);
00406     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00407     EmitToStreamer(OutStreamer, TmpInst);
00408     return;
00409   }
00410   case PPC::LDtocJTI:
00411   case PPC::LDtocCPT:
00412   case PPC::LDtoc: {
00413     // Transform %X3 = LDtoc <ga:@min1>, %X2
00414     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00415 
00416     // Change the opcode to LD, and the global address operand to be a
00417     // reference to the TOC entry we will synthesize later.
00418     TmpInst.setOpcode(PPC::LD);
00419     const MachineOperand &MO = MI->getOperand(1);
00420 
00421     // Map symbol -> label of TOC entry
00422     assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
00423     MCSymbol *MOSymbol = nullptr;
00424     if (MO.isGlobal())
00425       MOSymbol = getSymbol(MO.getGlobal());
00426     else if (MO.isCPI())
00427       MOSymbol = GetCPISymbol(MO.getIndex());
00428     else if (MO.isJTI())
00429       MOSymbol = GetJTISymbol(MO.getIndex());
00430 
00431     MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
00432 
00433     const MCExpr *Exp =
00434       MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
00435                               OutContext);
00436     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00437     EmitToStreamer(OutStreamer, TmpInst);
00438     return;
00439   }
00440       
00441   case PPC::ADDIStocHA: {
00442     // Transform %Xd = ADDIStocHA %X2, <ga:@sym>
00443     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00444 
00445     // Change the opcode to ADDIS8.  If the global address is external, has
00446     // common linkage, is a non-local function address, or is a jump table
00447     // address, then generate a TOC entry and reference that.  Otherwise
00448     // reference the symbol directly.
00449     TmpInst.setOpcode(PPC::ADDIS8);
00450     const MachineOperand &MO = MI->getOperand(2);
00451     assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) &&
00452            "Invalid operand for ADDIStocHA!");
00453     MCSymbol *MOSymbol = nullptr;
00454     bool IsExternal = false;
00455     bool IsNonLocalFunction = false;
00456     bool IsCommon = false;
00457     bool IsAvailExt = false;
00458 
00459     if (MO.isGlobal()) {
00460       const GlobalValue *GV = MO.getGlobal();
00461       MOSymbol = getSymbol(GV);
00462       IsExternal = GV->isDeclaration();
00463       IsCommon = GV->hasCommonLinkage();
00464       IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
00465         (GV->isDeclaration() || GV->isWeakForLinker());
00466       IsAvailExt = GV->hasAvailableExternallyLinkage();
00467     } else if (MO.isCPI())
00468       MOSymbol = GetCPISymbol(MO.getIndex());
00469     else if (MO.isJTI())
00470       MOSymbol = GetJTISymbol(MO.getIndex());
00471 
00472     if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt ||
00473         MO.isJTI() || TM.getCodeModel() == CodeModel::Large)
00474       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00475 
00476     const MCExpr *Exp =
00477       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
00478                               OutContext);
00479     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
00480     EmitToStreamer(OutStreamer, TmpInst);
00481     return;
00482   }
00483   case PPC::LDtocL: {
00484     // Transform %Xd = LDtocL <ga:@sym>, %Xs
00485     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00486 
00487     // Change the opcode to LD.  If the global address is external, has
00488     // common linkage, or is a jump table address, then reference the
00489     // associated TOC entry.  Otherwise reference the symbol directly.
00490     TmpInst.setOpcode(PPC::LD);
00491     const MachineOperand &MO = MI->getOperand(1);
00492     assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) &&
00493            "Invalid operand for LDtocL!");
00494     MCSymbol *MOSymbol = nullptr;
00495 
00496     if (MO.isJTI())
00497       MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
00498     else if (MO.isCPI()) {
00499       MOSymbol = GetCPISymbol(MO.getIndex());
00500       if (TM.getCodeModel() == CodeModel::Large)
00501         MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00502     }
00503     else if (MO.isGlobal()) {
00504       const GlobalValue *GValue = MO.getGlobal();
00505       MOSymbol = getSymbol(GValue);
00506       if (GValue->getType()->getElementType()->isFunctionTy() ||
00507           GValue->isDeclaration() || GValue->hasCommonLinkage() ||
00508           GValue->hasAvailableExternallyLinkage() ||
00509           TM.getCodeModel() == CodeModel::Large)
00510         MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00511     }
00512 
00513     const MCExpr *Exp =
00514       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
00515                               OutContext);
00516     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00517     EmitToStreamer(OutStreamer, TmpInst);
00518     return;
00519   }
00520   case PPC::ADDItocL: {
00521     // Transform %Xd = ADDItocL %Xs, <ga:@sym>
00522     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00523 
00524     // Change the opcode to ADDI8.  If the global address is external, then
00525     // generate a TOC entry and reference that.  Otherwise reference the
00526     // symbol directly.
00527     TmpInst.setOpcode(PPC::ADDI8);
00528     const MachineOperand &MO = MI->getOperand(2);
00529     assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
00530     MCSymbol *MOSymbol = nullptr;
00531     bool IsExternal = false;
00532     bool IsNonLocalFunction = false;
00533 
00534     if (MO.isGlobal()) {
00535       const GlobalValue *GV = MO.getGlobal();
00536       MOSymbol = getSymbol(GV);
00537       IsExternal = GV->isDeclaration();
00538       IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() &&
00539         (GV->isDeclaration() || GV->isWeakForLinker());
00540     } else if (MO.isCPI())
00541       MOSymbol = GetCPISymbol(MO.getIndex());
00542 
00543     if (IsNonLocalFunction || IsExternal ||
00544         TM.getCodeModel() == CodeModel::Large)
00545       MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
00546 
00547     const MCExpr *Exp =
00548       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
00549                               OutContext);
00550     TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp);
00551     EmitToStreamer(OutStreamer, TmpInst);
00552     return;
00553   }
00554   case PPC::ADDISgotTprelHA: {
00555     // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
00556     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
00557     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00558     const MachineOperand &MO = MI->getOperand(2);
00559     const GlobalValue *GValue = MO.getGlobal();
00560     MCSymbol *MOSymbol = getSymbol(GValue);
00561     const MCExpr *SymGotTprel =
00562       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
00563                               OutContext);
00564     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8)
00565                                 .addReg(MI->getOperand(0).getReg())
00566                                 .addReg(PPC::X2)
00567                                 .addExpr(SymGotTprel));
00568     return;
00569   }
00570   case PPC::LDgotTprelL:
00571   case PPC::LDgotTprelL32: {
00572     // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
00573     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00574 
00575     // Change the opcode to LD.
00576     TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
00577     const MachineOperand &MO = MI->getOperand(1);
00578     const GlobalValue *GValue = MO.getGlobal();
00579     MCSymbol *MOSymbol = getSymbol(GValue);
00580     const MCExpr *Exp =
00581       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
00582                               OutContext);
00583     TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
00584     EmitToStreamer(OutStreamer, TmpInst);
00585     return;
00586   }
00587 
00588   case PPC::PPC32PICGOT: {
00589     MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
00590     MCSymbol *GOTRef = OutContext.CreateTempSymbol();
00591     MCSymbol *NextInstr = OutContext.CreateTempSymbol();
00592 
00593     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL)
00594       // FIXME: We would like an efficient form for this, so we don't have to do
00595       // a lot of extra uniquing.
00596       .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext)));
00597     const MCExpr *OffsExpr =
00598       MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext),
00599                                 MCSymbolRefExpr::Create(GOTRef, OutContext),
00600         OutContext);
00601     OutStreamer.EmitLabel(GOTRef);
00602     OutStreamer.EmitValue(OffsExpr, 4);
00603     OutStreamer.EmitLabel(NextInstr);
00604     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR)
00605                                 .addReg(MI->getOperand(0).getReg()));
00606     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LWZ)
00607                                 .addReg(MI->getOperand(1).getReg())
00608                                 .addImm(0)
00609                                 .addReg(MI->getOperand(0).getReg()));
00610     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADD4)
00611                                 .addReg(MI->getOperand(0).getReg())
00612                                 .addReg(MI->getOperand(1).getReg())
00613                                 .addReg(MI->getOperand(0).getReg()));
00614     return;
00615   }
00616   case PPC::PPC32GOT: {
00617     MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
00618     const MCExpr *SymGotTlsL =
00619       MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO,
00620                               OutContext);
00621     const MCExpr *SymGotTlsHA =                               
00622       MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA,
00623                               OutContext);
00624     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI)
00625                                 .addReg(MI->getOperand(0).getReg())
00626                                 .addExpr(SymGotTlsL));
00627     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS)
00628                                 .addReg(MI->getOperand(0).getReg())
00629                                 .addReg(MI->getOperand(0).getReg())
00630                                 .addExpr(SymGotTlsHA));
00631     return;
00632   }
00633   case PPC::ADDIStlsgdHA: {
00634     // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym>
00635     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
00636     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00637     const MachineOperand &MO = MI->getOperand(2);
00638     const GlobalValue *GValue = MO.getGlobal();
00639     MCSymbol *MOSymbol = getSymbol(GValue);
00640     const MCExpr *SymGotTlsGD =
00641       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
00642                               OutContext);
00643     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8)
00644                                 .addReg(MI->getOperand(0).getReg())
00645                                 .addReg(PPC::X2)
00646                                 .addExpr(SymGotTlsGD));
00647     return;
00648   }
00649   case PPC::ADDItlsgdL:
00650     // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym>
00651     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsgd@l
00652   case PPC::ADDItlsgdL32: {
00653     // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym>
00654     // Into:      %Rd = ADDI %Rs, sym@got@tlsgd
00655     const MachineOperand &MO = MI->getOperand(2);
00656     const GlobalValue *GValue = MO.getGlobal();
00657     MCSymbol *MOSymbol = getSymbol(GValue);
00658     const MCExpr *SymGotTlsGD =
00659       MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ?
00660                                          MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO :
00661                                          MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
00662                               OutContext);
00663     EmitToStreamer(OutStreamer,
00664                    MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
00665                    .addReg(MI->getOperand(0).getReg())
00666                    .addReg(MI->getOperand(1).getReg())
00667                    .addExpr(SymGotTlsGD));
00668     return;
00669   }
00670   case PPC::GETtlsADDR:
00671     // Transform: %X3 = GETtlsADDR %X3, <ga:@sym>
00672     // Into:      BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
00673   case PPC::GETtlsADDR32: {
00674     // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym>
00675     // Into:      BL_TLS __tls_get_addr(sym@tlsgd)@PLT
00676 
00677     StringRef Name = "__tls_get_addr";
00678     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
00679     MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
00680 
00681     if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
00682         TM.getRelocationModel() == Reloc::PIC_)
00683       Kind = MCSymbolRefExpr::VK_PLT;
00684     const MCSymbolRefExpr *TlsRef = 
00685       MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
00686     const MachineOperand &MO = MI->getOperand(2);
00687     const GlobalValue *GValue = MO.getGlobal();
00688     MCSymbol *MOSymbol = getSymbol(GValue);
00689     const MCExpr *SymVar =
00690       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
00691                               OutContext);
00692     EmitToStreamer(OutStreamer,
00693                    MCInstBuilder(Subtarget.isPPC64() ?
00694                                   PPC::BL8_NOP_TLS : PPC::BL_TLS)
00695                    .addExpr(TlsRef)
00696                    .addExpr(SymVar));
00697     return;
00698   }
00699   case PPC::ADDIStlsldHA: {
00700     // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym>
00701     // Into:      %Xd = ADDIS8 %X2, sym@got@tlsld@ha
00702     assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
00703     const MachineOperand &MO = MI->getOperand(2);
00704     const GlobalValue *GValue = MO.getGlobal();
00705     MCSymbol *MOSymbol = getSymbol(GValue);
00706     const MCExpr *SymGotTlsLD =
00707       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
00708                               OutContext);
00709     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8)
00710                                 .addReg(MI->getOperand(0).getReg())
00711                                 .addReg(PPC::X2)
00712                                 .addExpr(SymGotTlsLD));
00713     return;
00714   }
00715   case PPC::ADDItlsldL:
00716     // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym>
00717     // Into:      %Xd = ADDI8 %Xs, sym@got@tlsld@l
00718   case PPC::ADDItlsldL32: {
00719     // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym>
00720     // Into:      %Rd = ADDI %Rs, sym@got@tlsld
00721     const MachineOperand &MO = MI->getOperand(2);
00722     const GlobalValue *GValue = MO.getGlobal();
00723     MCSymbol *MOSymbol = getSymbol(GValue);
00724     const MCExpr *SymGotTlsLD =
00725       MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ?
00726                                          MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO :
00727                                          MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
00728                               OutContext);
00729     EmitToStreamer(OutStreamer,
00730                    MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
00731                    .addReg(MI->getOperand(0).getReg())
00732                    .addReg(MI->getOperand(1).getReg())
00733                    .addExpr(SymGotTlsLD));
00734     return;
00735   }
00736   case PPC::GETtlsldADDR:
00737     // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym>
00738     // Into:      BL8_NOP_TLS __tls_get_addr(sym@tlsld)
00739   case PPC::GETtlsldADDR32: {
00740     // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym>
00741     // Into:      BL_TLS __tls_get_addr(sym@tlsld)@PLT
00742 
00743     StringRef Name = "__tls_get_addr";
00744     MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
00745     MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
00746 
00747     if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
00748         TM.getRelocationModel() == Reloc::PIC_)
00749       Kind = MCSymbolRefExpr::VK_PLT;
00750 
00751     const MCSymbolRefExpr *TlsRef = 
00752       MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
00753     const MachineOperand &MO = MI->getOperand(2);
00754     const GlobalValue *GValue = MO.getGlobal();
00755     MCSymbol *MOSymbol = getSymbol(GValue);
00756     const MCExpr *SymVar =
00757       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
00758                               OutContext);
00759     EmitToStreamer(OutStreamer,
00760                    MCInstBuilder(Subtarget.isPPC64() ?
00761                                   PPC::BL8_NOP_TLS : PPC::BL_TLS)
00762                    .addExpr(TlsRef)
00763                    .addExpr(SymVar));
00764     return;
00765   }
00766   case PPC::ADDISdtprelHA:
00767     // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym>
00768     // Into:      %Xd = ADDIS8 %X3, sym@dtprel@ha
00769   case PPC::ADDISdtprelHA32: {
00770     // Transform: %Rd = ADDISdtprelHA32 %R3, <ga:@sym>
00771     // Into:      %Rd = ADDIS %R3, sym@dtprel@ha
00772     const MachineOperand &MO = MI->getOperand(2);
00773     const GlobalValue *GValue = MO.getGlobal();
00774     MCSymbol *MOSymbol = getSymbol(GValue);
00775     const MCExpr *SymDtprel =
00776       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
00777                               OutContext);
00778     EmitToStreamer(OutStreamer,
00779                    MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
00780                    .addReg(MI->getOperand(0).getReg())
00781                    .addReg(Subtarget.isPPC64() ? PPC::X3 : PPC::R3)
00782                    .addExpr(SymDtprel));
00783     return;
00784   }
00785   case PPC::ADDIdtprelL:
00786     // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym>
00787     // Into:      %Xd = ADDI8 %Xs, sym@dtprel@l
00788   case PPC::ADDIdtprelL32: {
00789     // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym>
00790     // Into:      %Rd = ADDI %Rs, sym@dtprel@l
00791     const MachineOperand &MO = MI->getOperand(2);
00792     const GlobalValue *GValue = MO.getGlobal();
00793     MCSymbol *MOSymbol = getSymbol(GValue);
00794     const MCExpr *SymDtprel =
00795       MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
00796                               OutContext);
00797     EmitToStreamer(OutStreamer,
00798                    MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI)
00799                    .addReg(MI->getOperand(0).getReg())
00800                    .addReg(MI->getOperand(1).getReg())
00801                    .addExpr(SymDtprel));
00802     return;
00803   }
00804   case PPC::MFOCRF:
00805   case PPC::MFOCRF8:
00806     if (!Subtarget.hasMFOCRF()) {
00807       // Transform: %R3 = MFOCRF %CR7
00808       // Into:      %R3 = MFCR   ;; cr7
00809       unsigned NewOpcode =
00810         MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
00811       OutStreamer.AddComment(PPCInstPrinter::
00812                              getRegisterName(MI->getOperand(1).getReg()));
00813       EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode)
00814                                   .addReg(MI->getOperand(0).getReg()));
00815       return;
00816     }
00817     break;
00818   case PPC::MTOCRF:
00819   case PPC::MTOCRF8:
00820     if (!Subtarget.hasMFOCRF()) {
00821       // Transform: %CR7 = MTOCRF %R3
00822       // Into:      MTCRF mask, %R3 ;; cr7
00823       unsigned NewOpcode =
00824         MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
00825       unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
00826                               ->getEncodingValue(MI->getOperand(0).getReg());
00827       OutStreamer.AddComment(PPCInstPrinter::
00828                              getRegisterName(MI->getOperand(0).getReg()));
00829       EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode)
00830                                   .addImm(Mask)
00831                                   .addReg(MI->getOperand(1).getReg()));
00832       return;
00833     }
00834     break;
00835   case PPC::LD:
00836   case PPC::STD:
00837   case PPC::LWA_32:
00838   case PPC::LWA: {
00839     // Verify alignment is legal, so we don't create relocations
00840     // that can't be supported.
00841     // FIXME:  This test is currently disabled for Darwin.  The test
00842     // suite shows a handful of test cases that fail this check for
00843     // Darwin.  Those need to be investigated before this sanity test
00844     // can be enabled for those subtargets.
00845     if (!Subtarget.isDarwin()) {
00846       unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
00847       const MachineOperand &MO = MI->getOperand(OpNum);
00848       if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
00849         llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
00850     }
00851     // Now process the instruction normally.
00852     break;
00853   }
00854   }
00855 
00856   LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
00857   EmitToStreamer(OutStreamer, TmpInst);
00858 }
00859 
00860 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
00861   if (Subtarget.isELFv2ABI()) {
00862     PPCTargetStreamer *TS =
00863       static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer());
00864 
00865     if (TS)
00866       TS->emitAbiVersion(2);
00867   }
00868 
00869   if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_)
00870     return AsmPrinter::EmitStartOfAsmFile(M);
00871 
00872   // FIXME: The use of .got2 assumes large GOT model (-fPIC), which is not
00873   // optimal for some cases.  We should consider supporting small model (-fpic)
00874   // as well in the future.
00875   assert(TM.getCodeModel() != CodeModel::Small &&
00876          "Small code model PIC is currently unsupported.");
00877   OutStreamer.SwitchSection(OutContext.getELFSection(".got2",
00878          ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00879          SectionKind::getReadOnly()));
00880 
00881   MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".L.TOC."));
00882   MCSymbol *CurrentPos = OutContext.CreateTempSymbol();
00883 
00884   OutStreamer.EmitLabel(CurrentPos);
00885 
00886   // The GOT pointer points to the middle of the GOT, in order to reference the
00887   // entire 64kB range.  0x8000 is the midpoint.
00888   const MCExpr *tocExpr =
00889     MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext),
00890                             MCConstantExpr::Create(0x8000, OutContext),
00891                             OutContext);
00892 
00893   OutStreamer.EmitAssignment(TOCSym, tocExpr);
00894 
00895   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
00896 }
00897 
00898 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
00899   // linux/ppc32 - Normal entry label.
00900   if (!Subtarget.isPPC64() && TM.getRelocationModel() != Reloc::PIC_)
00901     return AsmPrinter::EmitFunctionEntryLabel();
00902 
00903   if (!Subtarget.isPPC64()) {
00904     const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
00905     if (PPCFI->usesPICBase()) {
00906       MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
00907       MCSymbol *PICBase = MF->getPICBaseSymbol();
00908       OutStreamer.EmitLabel(RelocSymbol);
00909 
00910       const MCExpr *OffsExpr =
00911         MCBinaryExpr::CreateSub(
00912           MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".L.TOC.")),
00913                                                                OutContext),
00914                                   MCSymbolRefExpr::Create(PICBase, OutContext),
00915           OutContext);
00916       OutStreamer.EmitValue(OffsExpr, 4);
00917       OutStreamer.EmitLabel(CurrentFnSym);
00918       return;
00919     } else
00920       return AsmPrinter::EmitFunctionEntryLabel();
00921   }
00922 
00923   // ELFv2 ABI - Normal entry label.
00924   if (Subtarget.isELFv2ABI())
00925     return AsmPrinter::EmitFunctionEntryLabel();
00926 
00927   // Emit an official procedure descriptor.
00928   MCSectionSubPair Current = OutStreamer.getCurrentSection();
00929   const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd",
00930       ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00931       SectionKind::getReadOnly());
00932   OutStreamer.SwitchSection(Section);
00933   OutStreamer.EmitLabel(CurrentFnSym);
00934   OutStreamer.EmitValueToAlignment(8);
00935   MCSymbol *Symbol1 = 
00936     OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName()));
00937   // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
00938   // entry point.
00939   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext),
00940       8 /*size*/);
00941   MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
00942   // Generates a R_PPC64_TOC relocation for TOC base insertion.
00943   OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2,
00944                         MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
00945                         8/*size*/);
00946   // Emit a null environment pointer.
00947   OutStreamer.EmitIntValue(0, 8 /* size */);
00948   OutStreamer.SwitchSection(Current.first, Current.second);
00949 
00950   MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol(
00951                           ".L." + Twine(CurrentFnSym->getName()));
00952   OutStreamer.EmitLabel(RealFnSym);
00953   CurrentFnSymForSize = RealFnSym;
00954 }
00955 
00956 
00957 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
00958   const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout();
00959 
00960   bool isPPC64 = TD->getPointerSizeInBits() == 64;
00961 
00962   PPCTargetStreamer &TS =
00963       static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer());
00964 
00965   if (!TOC.empty()) {
00966     const MCSectionELF *Section;
00967     
00968     if (isPPC64)
00969       Section = OutStreamer.getContext().getELFSection(".toc",
00970         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00971         SectionKind::getReadOnly());
00972   else
00973       Section = OutStreamer.getContext().getELFSection(".got2",
00974         ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
00975         SectionKind::getReadOnly());
00976     OutStreamer.SwitchSection(Section);
00977 
00978     for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
00979          E = TOC.end(); I != E; ++I) {
00980       OutStreamer.EmitLabel(I->second);
00981       MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
00982       if (isPPC64)
00983         TS.emitTCEntry(*S);
00984       else
00985         OutStreamer.EmitSymbolValue(S, 4);
00986     }
00987   }
00988 
00989   MachineModuleInfoELF &MMIELF =
00990     MMI->getObjFileInfo<MachineModuleInfoELF>();
00991 
00992   MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
00993   if (!Stubs.empty()) {
00994     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
00995     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
00996       // L_foo$stub:
00997       OutStreamer.EmitLabel(Stubs[i].first);
00998       //   .long _foo
00999       OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
01000                                                     OutContext),
01001                             isPPC64 ? 8 : 4/*size*/);
01002     }
01003 
01004     Stubs.clear();
01005     OutStreamer.AddBlankLine();
01006   }
01007 
01008   return AsmPrinter::doFinalization(M);
01009 }
01010 
01011 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
01012 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
01013   // In the ELFv2 ABI, in functions that use the TOC register, we need to
01014   // provide two entry points.  The ABI guarantees that when calling the
01015   // local entry point, r2 is set up by the caller to contain the TOC base
01016   // for this function, and when calling the global entry point, r12 is set
01017   // up by the caller to hold the address of the global entry point.  We
01018   // thus emit a prefix sequence along the following lines:
01019   //
01020   // func:
01021   //         # global entry point
01022   //         addis r2,r12,(.TOC.-func)@ha
01023   //         addi  r2,r2,(.TOC.-func)@l
01024   //         .localentry func, .-func
01025   //         # local entry point, followed by function body
01026   //
01027   // This ensures we have r2 set up correctly while executing the function
01028   // body, no matter which entry point is called.
01029   if (Subtarget.isELFv2ABI()
01030       // Only do all that if the function uses r2 in the first place.
01031       && !MF->getRegInfo().use_empty(PPC::X2)) {
01032 
01033     MCSymbol *GlobalEntryLabel = OutContext.CreateTempSymbol();
01034     OutStreamer.EmitLabel(GlobalEntryLabel);
01035     const MCSymbolRefExpr *GlobalEntryLabelExp =
01036       MCSymbolRefExpr::Create(GlobalEntryLabel, OutContext);
01037 
01038     MCSymbol *TOCSymbol = OutContext.GetOrCreateSymbol(StringRef(".TOC."));
01039     const MCExpr *TOCDeltaExpr =
01040       MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(TOCSymbol, OutContext),
01041                               GlobalEntryLabelExp, OutContext);
01042 
01043     const MCExpr *TOCDeltaHi =
01044       PPCMCExpr::CreateHa(TOCDeltaExpr, false, OutContext);
01045     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS)
01046                                 .addReg(PPC::X2)
01047                                 .addReg(PPC::X12)
01048                                 .addExpr(TOCDeltaHi));
01049 
01050     const MCExpr *TOCDeltaLo =
01051       PPCMCExpr::CreateLo(TOCDeltaExpr, false, OutContext);
01052     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI)
01053                                 .addReg(PPC::X2)
01054                                 .addReg(PPC::X2)
01055                                 .addExpr(TOCDeltaLo));
01056 
01057     MCSymbol *LocalEntryLabel = OutContext.CreateTempSymbol();
01058     OutStreamer.EmitLabel(LocalEntryLabel);
01059     const MCSymbolRefExpr *LocalEntryLabelExp =
01060        MCSymbolRefExpr::Create(LocalEntryLabel, OutContext);
01061     const MCExpr *LocalOffsetExp =
01062       MCBinaryExpr::CreateSub(LocalEntryLabelExp,
01063                               GlobalEntryLabelExp, OutContext);
01064 
01065     PPCTargetStreamer *TS =
01066       static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer());
01067 
01068     if (TS)
01069       TS->emitLocalEntry(CurrentFnSym, LocalOffsetExp);
01070   }
01071 }
01072 
01073 /// EmitFunctionBodyEnd - Print the traceback table before the .size
01074 /// directive.
01075 ///
01076 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
01077   // Only the 64-bit target requires a traceback table.  For now,
01078   // we only emit the word of zeroes that GDB requires to find
01079   // the end of the function, and zeroes for the eight-byte
01080   // mandatory fields.
01081   // FIXME: We should fill in the eight-byte mandatory fields as described in
01082   // the PPC64 ELF ABI (this is a low-priority item because GDB does not
01083   // currently make use of these fields).
01084   if (Subtarget.isPPC64()) {
01085     OutStreamer.EmitIntValue(0, 4/*size*/);
01086     OutStreamer.EmitIntValue(0, 8/*size*/);
01087   }
01088 }
01089 
01090 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
01091   static const char *const CPUDirectives[] = {
01092     "",
01093     "ppc",
01094     "ppc440",
01095     "ppc601",
01096     "ppc602",
01097     "ppc603",
01098     "ppc7400",
01099     "ppc750",
01100     "ppc970",
01101     "ppcA2",
01102     "ppce500mc",
01103     "ppce5500",
01104     "power3",
01105     "power4",
01106     "power5",
01107     "power5x",
01108     "power6",
01109     "power6x",
01110     "power7",
01111     "ppc64",
01112     "ppc64le"
01113   };
01114 
01115   unsigned Directive = Subtarget.getDarwinDirective();
01116   if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970)
01117     Directive = PPC::DIR_970;
01118   if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400)
01119     Directive = PPC::DIR_7400;
01120   if (Subtarget.isPPC64() && Directive < PPC::DIR_64)
01121     Directive = PPC::DIR_64;
01122   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
01123 
01124   assert(Directive < array_lengthof(CPUDirectives) &&
01125          "CPUDirectives[] might not be up-to-date!");
01126   PPCTargetStreamer &TStreamer =
01127       *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer());
01128   TStreamer.emitMachine(CPUDirectives[Directive]);
01129 
01130   // Prime text sections so they are adjacent.  This reduces the likelihood a
01131   // large data or debug section causes a branch to exceed 16M limit.
01132   const TargetLoweringObjectFileMachO &TLOFMacho = 
01133     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
01134   OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
01135   if (TM.getRelocationModel() == Reloc::PIC_) {
01136     OutStreamer.SwitchSection(
01137            OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
01138                                       MachO::S_SYMBOL_STUBS |
01139                                       MachO::S_ATTR_PURE_INSTRUCTIONS,
01140                                       32, SectionKind::getText()));
01141   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
01142     OutStreamer.SwitchSection(
01143            OutContext.getMachOSection("__TEXT","__symbol_stub1",
01144                                       MachO::S_SYMBOL_STUBS |
01145                                       MachO::S_ATTR_PURE_INSTRUCTIONS,
01146                                       16, SectionKind::getText()));
01147   }
01148   OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
01149 }
01150 
01151 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) {
01152   // Remove $stub suffix, add $lazy_ptr.
01153   StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5);
01154   return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr");
01155 }
01156 
01157 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) {
01158   // Add $tmp suffix to $stub, yielding $stub$tmp.
01159   return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp");
01160 }
01161 
01162 void PPCDarwinAsmPrinter::
01163 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) {
01164   bool isPPC64 =
01165       TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64;
01166   bool isDarwin = Subtarget.isDarwin();
01167   
01168   const TargetLoweringObjectFileMachO &TLOFMacho = 
01169     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
01170 
01171   // .lazy_symbol_pointer
01172   const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection();
01173   
01174   // Output stubs for dynamically-linked functions
01175   if (TM.getRelocationModel() == Reloc::PIC_) {
01176     const MCSection *StubSection = 
01177     OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
01178                                MachO::S_SYMBOL_STUBS |
01179                                MachO::S_ATTR_PURE_INSTRUCTIONS,
01180                                32, SectionKind::getText());
01181     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01182       OutStreamer.SwitchSection(StubSection);
01183       EmitAlignment(4);
01184       
01185       MCSymbol *Stub = Stubs[i].first;
01186       MCSymbol *RawSym = Stubs[i].second.getPointer();
01187       MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
01188       MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext);
01189                                            
01190       OutStreamer.EmitLabel(Stub);
01191       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
01192 
01193       const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext);
01194       const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
01195       const MCExpr *Sub =
01196         MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext);
01197 
01198       // mflr r0
01199       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0));
01200       // bcl 20, 31, AnonSymbol
01201       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon));
01202       OutStreamer.EmitLabel(AnonSymbol);
01203       // mflr r11
01204       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11));
01205       // addis r11, r11, ha16(LazyPtr - AnonSymbol)
01206       const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext);
01207       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS)
01208         .addReg(PPC::R11)
01209         .addReg(PPC::R11)
01210         .addExpr(SubHa16));
01211       // mtlr r0
01212       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0));
01213 
01214       // ldu r12, lo16(LazyPtr - AnonSymbol)(r11)
01215       // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11)
01216       const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext);
01217       EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
01218         .addReg(PPC::R12)
01219         .addExpr(SubLo16).addExpr(SubLo16)
01220         .addReg(PPC::R11));
01221       // mtctr r12
01222       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
01223       // bctr
01224       EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR));
01225 
01226       OutStreamer.SwitchSection(LSPSection);
01227       OutStreamer.EmitLabel(LazyPtr);
01228       OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
01229 
01230       MCSymbol *DyldStubBindingHelper =
01231         OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
01232       if (isPPC64) {
01233         // .quad dyld_stub_binding_helper
01234         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
01235       } else {
01236         // .long dyld_stub_binding_helper
01237         OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
01238       }
01239     }
01240     OutStreamer.AddBlankLine();
01241     return;
01242   }
01243   
01244   const MCSection *StubSection =
01245     OutContext.getMachOSection("__TEXT","__symbol_stub1",
01246                                MachO::S_SYMBOL_STUBS |
01247                                MachO::S_ATTR_PURE_INSTRUCTIONS,
01248                                16, SectionKind::getText());
01249   for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01250     MCSymbol *Stub = Stubs[i].first;
01251     MCSymbol *RawSym = Stubs[i].second.getPointer();
01252     MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext);
01253     const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext);
01254 
01255     OutStreamer.SwitchSection(StubSection);
01256     EmitAlignment(4);
01257     OutStreamer.EmitLabel(Stub);
01258     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
01259 
01260     // lis r11, ha16(LazyPtr)
01261     const MCExpr *LazyPtrHa16 =
01262       PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext);
01263     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS)
01264       .addReg(PPC::R11)
01265       .addExpr(LazyPtrHa16));
01266 
01267     // ldu r12, lo16(LazyPtr)(r11)
01268     // lwzu r12, lo16(LazyPtr)(r11)
01269     const MCExpr *LazyPtrLo16 =
01270       PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext);
01271     EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU)
01272       .addReg(PPC::R12)
01273       .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16)
01274       .addReg(PPC::R11));
01275 
01276     // mtctr r12
01277     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12));
01278     // bctr
01279     EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR));
01280 
01281     OutStreamer.SwitchSection(LSPSection);
01282     OutStreamer.EmitLabel(LazyPtr);
01283     OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol);
01284 
01285     MCSymbol *DyldStubBindingHelper =
01286       OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper"));
01287     if (isPPC64) {
01288       // .quad dyld_stub_binding_helper
01289       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8);
01290     } else {
01291       // .long dyld_stub_binding_helper
01292       OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4);
01293     }
01294   }
01295   
01296   OutStreamer.AddBlankLine();
01297 }
01298 
01299 
01300 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
01301   bool isPPC64 =
01302       TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64;
01303 
01304   // Darwin/PPC always uses mach-o.
01305   const TargetLoweringObjectFileMachO &TLOFMacho = 
01306     static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
01307   MachineModuleInfoMachO &MMIMacho =
01308     MMI->getObjFileInfo<MachineModuleInfoMachO>();
01309   
01310   MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList();
01311   if (!Stubs.empty())
01312     EmitFunctionStubs(Stubs);
01313 
01314   if (MAI->doesSupportExceptionHandling() && MMI) {
01315     // Add the (possibly multiple) personalities to the set of global values.
01316     // Only referenced functions get into the Personalities list.
01317     const std::vector<const Function*> &Personalities = MMI->getPersonalities();
01318     for (std::vector<const Function*>::const_iterator I = Personalities.begin(),
01319          E = Personalities.end(); I != E; ++I) {
01320       if (*I) {
01321         MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr");
01322         MachineModuleInfoImpl::StubValueTy &StubSym =
01323           MMIMacho.getGVStubEntry(NLPSym);
01324         StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true);
01325       }
01326     }
01327   }
01328 
01329   // Output stubs for dynamically-linked functions.
01330   Stubs = MMIMacho.GetGVStubList();
01331   
01332   // Output macho stubs for external and common global variables.
01333   if (!Stubs.empty()) {
01334     // Switch with ".non_lazy_symbol_pointer" directive.
01335     OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
01336     EmitAlignment(isPPC64 ? 3 : 2);
01337     
01338     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01339       // L_foo$stub:
01340       OutStreamer.EmitLabel(Stubs[i].first);
01341       //   .indirect_symbol _foo
01342       MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
01343       OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
01344 
01345       if (MCSym.getInt())
01346         // External to current translation unit.
01347         OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/);
01348       else
01349         // Internal to current translation unit.
01350         //
01351         // When we place the LSDA into the TEXT section, the type info pointers
01352         // need to be indirect and pc-rel. We accomplish this by using NLPs.
01353         // However, sometimes the types are local to the file. So we need to
01354         // fill in the value for the NLP in those cases.
01355         OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
01356                                                       OutContext),
01357                               isPPC64 ? 8 : 4/*size*/);
01358     }
01359 
01360     Stubs.clear();
01361     OutStreamer.AddBlankLine();
01362   }
01363 
01364   Stubs = MMIMacho.GetHiddenGVStubList();
01365   if (!Stubs.empty()) {
01366     OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
01367     EmitAlignment(isPPC64 ? 3 : 2);
01368     
01369     for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
01370       // L_foo$stub:
01371       OutStreamer.EmitLabel(Stubs[i].first);
01372       //   .long _foo
01373       OutStreamer.EmitValue(MCSymbolRefExpr::
01374                             Create(Stubs[i].second.getPointer(),
01375                                    OutContext),
01376                             isPPC64 ? 8 : 4/*size*/);
01377     }
01378 
01379     Stubs.clear();
01380     OutStreamer.AddBlankLine();
01381   }
01382 
01383   // Funny Darwin hack: This flag tells the linker that no global symbols
01384   // contain code that falls through to other global symbols (e.g. the obvious
01385   // implementation of multiple entry points).  If this doesn't occur, the
01386   // linker can safely perform dead code stripping.  Since LLVM never generates
01387   // code that does this, it is always safe to set.
01388   OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
01389 
01390   return AsmPrinter::doFinalization(M);
01391 }
01392 
01393 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
01394 /// for a MachineFunction to the given output stream, in a format that the
01395 /// Darwin assembler can deal with.
01396 ///
01397 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm,
01398                                            MCStreamer &Streamer) {
01399   const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>();
01400 
01401   if (Subtarget->isDarwin())
01402     return new PPCDarwinAsmPrinter(tm, Streamer);
01403   return new PPCLinuxAsmPrinter(tm, Streamer);
01404 }
01405 
01406 // Force static initialization.
01407 extern "C" void LLVMInitializePowerPCAsmPrinter() { 
01408   TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass);
01409   TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass);
01410   TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass);
01411 }