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" 57using namespace llvm; 58 59namespace { 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. 136static 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 147void 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/// 245bool 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 283bool 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/// 300void 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 409void 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 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.@tocbase")); 424 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 425 8/*size*/, 0/*addrspace*/); 426 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, OutContext), 427 8/*size*/, 0/*addrspace*/); 428 // Emit a null environment pointer. 429 OutStreamer.EmitIntValue(0, 8 /* size */, 0 /* addrspace */); 430 OutStreamer.SwitchSection(Current); 431 432 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 433 ".L." + Twine(CurrentFnSym->getName())); 434 OutStreamer.EmitLabel(RealFnSym); 435 CurrentFnSymForSize = RealFnSym; 436} 437 438 439bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 440 const TargetData *TD = TM.getTargetData(); 441 442 bool isPPC64 = TD->getPointerSizeInBits() == 64; 443 444 if (isPPC64 && !TOC.empty()) { 445 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 446 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 447 SectionKind::getReadOnly()); 448 OutStreamer.SwitchSection(Section); 449 450 // FIXME: This is nondeterminstic! 451 for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 452 E = TOC.end(); I != E; ++I) { 453 OutStreamer.EmitLabel(I->second); 454 OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) + 455 "[TC]," + I->first->getName()); 456 } 457 } 458 459 return AsmPrinter::doFinalization(M); 460} 461 462/// EmitFunctionBodyEnd - Print the traceback table before the .size 463/// directive. 464/// 465void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 466 // Only the 64-bit target requires a traceback table. For now, 467 // we only emit the word of zeroes that GDB requires to find 468 // the end of the function, and zeroes for the eight-byte 469 // mandatory fields. 470 // FIXME: We should fill in the eight-byte mandatory fields as described in 471 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 472 // currently make use of these fields). 473 if (Subtarget.isPPC64()) { 474 OutStreamer.EmitIntValue(0, 4/*size*/); 475 OutStreamer.EmitIntValue(0, 8/*size*/); 476 } 477} 478 479void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 480 static const char *const CPUDirectives[] = { 481 "", 482 "ppc", 483 "ppc440", 484 "ppc601", 485 "ppc602", 486 "ppc603", 487 "ppc7400", 488 "ppc750", 489 "ppc970", 490 "ppcA2", 491 "ppce500mc", 492 "ppce5500", 493 "power6", 494 "power7", 495 "ppc64" 496 }; 497 498 unsigned Directive = Subtarget.getDarwinDirective(); 499 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 500 Directive = PPC::DIR_970; 501 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 502 Directive = PPC::DIR_7400; 503 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 504 Directive = PPC::DIR_64; 505 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 506 507 // FIXME: This is a total hack, finish mc'izing the PPC backend. 508 if (OutStreamer.hasRawTextSupport()) 509 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 510 511 // Prime text sections so they are adjacent. This reduces the likelihood a 512 // large data or debug section causes a branch to exceed 16M limit. 513 const TargetLoweringObjectFileMachO &TLOFMacho = 514 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 515 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 516 if (TM.getRelocationModel() == Reloc::PIC_) { 517 OutStreamer.SwitchSection( 518 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 519 MCSectionMachO::S_SYMBOL_STUBS | 520 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 521 32, SectionKind::getText())); 522 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 523 OutStreamer.SwitchSection( 524 OutContext.getMachOSection("__TEXT","__symbol_stub1", 525 MCSectionMachO::S_SYMBOL_STUBS | 526 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 527 16, SectionKind::getText())); 528 } 529 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 530} 531 532static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 533 // Remove $stub suffix, add $lazy_ptr. 534 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5); 535 TmpStr += "$lazy_ptr"; 536 return Ctx.GetOrCreateSymbol(TmpStr.str()); 537} 538 539static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 540 // Add $tmp suffix to $stub, yielding $stub$tmp. 541 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()); 542 TmpStr += "$tmp"; 543 return Ctx.GetOrCreateSymbol(TmpStr.str()); 544} 545 546void PPCDarwinAsmPrinter:: 547EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 548 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 549 550 const TargetLoweringObjectFileMachO &TLOFMacho = 551 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 552 553 // .lazy_symbol_pointer 554 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 555 556 // Output stubs for dynamically-linked functions 557 if (TM.getRelocationModel() == Reloc::PIC_) { 558 const MCSection *StubSection = 559 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 560 MCSectionMachO::S_SYMBOL_STUBS | 561 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 562 32, SectionKind::getText()); 563 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 564 OutStreamer.SwitchSection(StubSection); 565 EmitAlignment(4); 566 567 MCSymbol *Stub = Stubs[i].first; 568 MCSymbol *RawSym = Stubs[i].second.getPointer(); 569 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 570 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 571 572 OutStreamer.EmitLabel(Stub); 573 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 574 // FIXME: MCize this. 575 OutStreamer.EmitRawText(StringRef("\tmflr r0")); 576 OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName())); 577 OutStreamer.EmitLabel(AnonSymbol); 578 OutStreamer.EmitRawText(StringRef("\tmflr r11")); 579 OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+ 580 "-" + AnonSymbol->getName() + ")"); 581 OutStreamer.EmitRawText(StringRef("\tmtlr r0")); 582 583 if (isPPC64) 584 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 585 "-" + AnonSymbol->getName() + ")(r11)"); 586 else 587 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 588 "-" + AnonSymbol->getName() + ")(r11)"); 589 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 590 OutStreamer.EmitRawText(StringRef("\tbctr")); 591 592 OutStreamer.SwitchSection(LSPSection); 593 OutStreamer.EmitLabel(LazyPtr); 594 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 595 596 if (isPPC64) 597 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 598 else 599 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 600 } 601 OutStreamer.AddBlankLine(); 602 return; 603 } 604 605 const MCSection *StubSection = 606 OutContext.getMachOSection("__TEXT","__symbol_stub1", 607 MCSectionMachO::S_SYMBOL_STUBS | 608 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 609 16, SectionKind::getText()); 610 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 611 MCSymbol *Stub = Stubs[i].first; 612 MCSymbol *RawSym = Stubs[i].second.getPointer(); 613 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 614 615 OutStreamer.SwitchSection(StubSection); 616 EmitAlignment(4); 617 OutStreamer.EmitLabel(Stub); 618 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 619 OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")"); 620 if (isPPC64) 621 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 622 ")(r11)"); 623 else 624 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 625 ")(r11)"); 626 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 627 OutStreamer.EmitRawText(StringRef("\tbctr")); 628 OutStreamer.SwitchSection(LSPSection); 629 OutStreamer.EmitLabel(LazyPtr); 630 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 631 632 if (isPPC64) 633 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 634 else 635 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 636 } 637 638 OutStreamer.AddBlankLine(); 639} 640 641 642bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 643 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 644 645 // Darwin/PPC always uses mach-o. 646 const TargetLoweringObjectFileMachO &TLOFMacho = 647 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 648 MachineModuleInfoMachO &MMIMacho = 649 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 650 651 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 652 if (!Stubs.empty()) 653 EmitFunctionStubs(Stubs); 654 655 if (MAI->doesSupportExceptionHandling() && MMI) { 656 // Add the (possibly multiple) personalities to the set of global values. 657 // Only referenced functions get into the Personalities list. 658 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 659 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 660 E = Personalities.end(); I != E; ++I) { 661 if (*I) { 662 MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 663 MachineModuleInfoImpl::StubValueTy &StubSym = 664 MMIMacho.getGVStubEntry(NLPSym); 665 StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true); 666 } 667 } 668 } 669 670 // Output stubs for dynamically-linked functions. 671 Stubs = MMIMacho.GetGVStubList(); 672 673 // Output macho stubs for external and common global variables. 674 if (!Stubs.empty()) { 675 // Switch with ".non_lazy_symbol_pointer" directive. 676 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 677 EmitAlignment(isPPC64 ? 3 : 2); 678 679 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 680 // L_foo$stub: 681 OutStreamer.EmitLabel(Stubs[i].first); 682 // .indirect_symbol _foo 683 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 684 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 685 686 if (MCSym.getInt()) 687 // External to current translation unit. 688 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 689 else 690 // Internal to current translation unit. 691 // 692 // When we place the LSDA into the TEXT section, the type info pointers 693 // need to be indirect and pc-rel. We accomplish this by using NLPs. 694 // However, sometimes the types are local to the file. So we need to 695 // fill in the value for the NLP in those cases. 696 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 697 OutContext), 698 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 699 } 700 701 Stubs.clear(); 702 OutStreamer.AddBlankLine(); 703 } 704 705 Stubs = MMIMacho.GetHiddenGVStubList(); 706 if (!Stubs.empty()) { 707 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 708 EmitAlignment(isPPC64 ? 3 : 2); 709 710 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 711 // L_foo$stub: 712 OutStreamer.EmitLabel(Stubs[i].first); 713 // .long _foo 714 OutStreamer.EmitValue(MCSymbolRefExpr:: 715 Create(Stubs[i].second.getPointer(), 716 OutContext), 717 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 718 } 719 720 Stubs.clear(); 721 OutStreamer.AddBlankLine(); 722 } 723 724 // Funny Darwin hack: This flag tells the linker that no global symbols 725 // contain code that falls through to other global symbols (e.g. the obvious 726 // implementation of multiple entry points). If this doesn't occur, the 727 // linker can safely perform dead code stripping. Since LLVM never generates 728 // code that does this, it is always safe to set. 729 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 730 731 return AsmPrinter::doFinalization(M); 732} 733 734/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 735/// for a MachineFunction to the given output stream, in a format that the 736/// Darwin assembler can deal with. 737/// 738static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 739 MCStreamer &Streamer) { 740 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 741 742 if (Subtarget->isDarwin()) 743 return new PPCDarwinAsmPrinter(tm, Streamer); 744 return new PPCLinuxAsmPrinter(tm, Streamer); 745} 746 747// Force static initialization. 748extern "C" void LLVMInitializePowerPCAsmPrinter() { 749 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 750 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 751} 752