LLVM API Documentation
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 }