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