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