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 "InstPrinter/PPCInstPrinter.h" 22 #include "MCTargetDesc/PPCPredicates.h" 23 #include "PPCSubtarget.h" 24 #include "PPCTargetMachine.h" 25 #include "llvm/ADT/MapVector.h" 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/Assembly/Writer.h" 29 #include "llvm/CodeGen/AsmPrinter.h" 30 #include "llvm/CodeGen/MachineFunctionPass.h" 31 #include "llvm/CodeGen/MachineInstr.h" 32 #include "llvm/CodeGen/MachineInstrBuilder.h" 33 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 34 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 35 #include "llvm/DebugInfo.h" 36 #include "llvm/IR/Constants.h" 37 #include "llvm/IR/DerivedTypes.h" 38 #include "llvm/IR/Module.h" 39 #include "llvm/MC/MCAsmInfo.h" 40 #include "llvm/MC/MCContext.h" 41 #include "llvm/MC/MCExpr.h" 42 #include "llvm/MC/MCInst.h" 43 #include "llvm/MC/MCInstBuilder.h" 44 #include "llvm/MC/MCSectionELF.h" 45 #include "llvm/MC/MCSectionMachO.h" 46 #include "llvm/MC/MCStreamer.h" 47 #include "llvm/MC/MCSymbol.h" 48 #include "llvm/Support/CommandLine.h" 49 #include "llvm/Support/Debug.h" 50 #include "llvm/Support/ELF.h" 51 #include "llvm/Support/ErrorHandling.h" 52 #include "llvm/Support/MathExtras.h" 53 #include "llvm/Support/TargetRegistry.h" 54 #include "llvm/Support/raw_ostream.h" 55 #include "llvm/Target/Mangler.h" 56 #include "llvm/Target/TargetInstrInfo.h" 57 #include "llvm/Target/TargetOptions.h" 58 #include "llvm/Target/TargetRegisterInfo.h" 59 using namespace llvm; 60 61 namespace { 62 class PPCAsmPrinter : public AsmPrinter { 63 protected: 64 MapVector<MCSymbol*, MCSymbol*> TOC; 65 const PPCSubtarget &Subtarget; 66 uint64_t TOCLabelID; 67 public: 68 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 69 : AsmPrinter(TM, Streamer), 70 Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0) {} 71 72 virtual const char *getPassName() const { 73 return "PowerPC Assembly Printer"; 74 } 75 76 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym); 77 78 virtual void EmitInstruction(const MachineInstr *MI); 79 80 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 81 82 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 83 unsigned AsmVariant, const char *ExtraCode, 84 raw_ostream &O); 85 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 86 unsigned AsmVariant, const char *ExtraCode, 87 raw_ostream &O); 88 89 MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 90 MachineLocation Location; 91 assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 92 // Frame address. Currently handles register +- offset only. 93 if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm()) 94 Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm()); 95 else { 96 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 97 } 98 return Location; 99 } 100 }; 101 102 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 103 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 104 public: 105 explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 106 : PPCAsmPrinter(TM, Streamer) {} 107 108 virtual const char *getPassName() const { 109 return "Linux PPC Assembly Printer"; 110 } 111 112 bool doFinalization(Module &M); 113 114 virtual void EmitFunctionEntryLabel(); 115 116 void EmitFunctionBodyEnd(); 117 }; 118 119 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 120 /// OS X 121 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 122 public: 123 explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 124 : PPCAsmPrinter(TM, Streamer) {} 125 126 virtual const char *getPassName() const { 127 return "Darwin PPC Assembly Printer"; 128 } 129 130 bool doFinalization(Module &M); 131 void EmitStartOfAsmFile(Module &M); 132 133 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 134 }; 135 } // end of anonymous namespace 136 137 /// stripRegisterPrefix - This method strips the character prefix from a 138 /// register name so that only the number is left. Used by for linux asm. 139 static const char *stripRegisterPrefix(const char *RegName) { 140 switch (RegName[0]) { 141 case 'r': 142 case 'f': 143 case 'v': return RegName + 1; 144 case 'c': if (RegName[1] == 'r') return RegName + 2; 145 } 146 147 return RegName; 148 } 149 150 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 151 raw_ostream &O) { 152 const MachineOperand &MO = MI->getOperand(OpNo); 153 154 switch (MO.getType()) { 155 case MachineOperand::MO_Register: { 156 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 157 // Linux assembler (Others?) does not take register mnemonics. 158 // FIXME - What about special registers used in mfspr/mtspr? 159 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 160 O << RegName; 161 return; 162 } 163 case MachineOperand::MO_Immediate: 164 O << MO.getImm(); 165 return; 166 167 case MachineOperand::MO_MachineBasicBlock: 168 O << *MO.getMBB()->getSymbol(); 169 return; 170 case MachineOperand::MO_JumpTableIndex: 171 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 172 << '_' << MO.getIndex(); 173 // FIXME: PIC relocation model 174 return; 175 case MachineOperand::MO_ConstantPoolIndex: 176 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 177 << '_' << MO.getIndex(); 178 return; 179 case MachineOperand::MO_BlockAddress: 180 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 181 return; 182 case MachineOperand::MO_ExternalSymbol: { 183 // Computing the address of an external symbol, not calling it. 184 if (TM.getRelocationModel() == Reloc::Static) { 185 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 186 return; 187 } 188 189 MCSymbol *NLPSym = 190 OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+ 191 MO.getSymbolName()+"$non_lazy_ptr"); 192 MachineModuleInfoImpl::StubValueTy &StubSym = 193 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym); 194 if (StubSym.getPointer() == 0) 195 StubSym = MachineModuleInfoImpl:: 196 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 197 198 O << *NLPSym; 199 return; 200 } 201 case MachineOperand::MO_GlobalAddress: { 202 // Computing the address of a global symbol, not calling it. 203 const GlobalValue *GV = MO.getGlobal(); 204 MCSymbol *SymToPrint; 205 206 // External or weakly linked global variables need non-lazily-resolved stubs 207 if (TM.getRelocationModel() != Reloc::Static && 208 (GV->isDeclaration() || GV->isWeakForLinker())) { 209 if (!GV->hasHiddenVisibility()) { 210 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 211 MachineModuleInfoImpl::StubValueTy &StubSym = 212 MMI->getObjFileInfo<MachineModuleInfoMachO>() 213 .getGVStubEntry(SymToPrint); 214 if (StubSym.getPointer() == 0) 215 StubSym = MachineModuleInfoImpl:: 216 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 217 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 218 GV->hasAvailableExternallyLinkage()) { 219 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 220 221 MachineModuleInfoImpl::StubValueTy &StubSym = 222 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 223 getHiddenGVStubEntry(SymToPrint); 224 if (StubSym.getPointer() == 0) 225 StubSym = MachineModuleInfoImpl:: 226 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 227 } else { 228 SymToPrint = Mang->getSymbol(GV); 229 } 230 } else { 231 SymToPrint = Mang->getSymbol(GV); 232 } 233 234 O << *SymToPrint; 235 236 printOffset(MO.getOffset(), O); 237 return; 238 } 239 240 default: 241 O << "<unknown operand type: " << MO.getType() << ">"; 242 return; 243 } 244 } 245 246 /// PrintAsmOperand - Print out an operand for an inline asm expression. 247 /// 248 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 249 unsigned AsmVariant, 250 const char *ExtraCode, raw_ostream &O) { 251 // Does this asm operand have a single letter operand modifier? 252 if (ExtraCode && ExtraCode[0]) { 253 if (ExtraCode[1] != 0) return true; // Unknown modifier. 254 255 switch (ExtraCode[0]) { 256 default: 257 // See if this is a generic print operand 258 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 259 case 'c': // Don't print "$" before a global var name or constant. 260 break; // PPC never has a prefix. 261 case 'L': // Write second word of DImode reference. 262 // Verify that this operand has two consecutive registers. 263 if (!MI->getOperand(OpNo).isReg() || 264 OpNo+1 == MI->getNumOperands() || 265 !MI->getOperand(OpNo+1).isReg()) 266 return true; 267 ++OpNo; // Return the high-part. 268 break; 269 case 'I': 270 // Write 'i' if an integer constant, otherwise nothing. Used to print 271 // addi vs add, etc. 272 if (MI->getOperand(OpNo).isImm()) 273 O << "i"; 274 return false; 275 } 276 } 277 278 printOperand(MI, OpNo, O); 279 return false; 280 } 281 282 // At the moment, all inline asm memory operands are a single register. 283 // In any case, the output of this routine should always be just one 284 // assembler operand. 285 286 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 287 unsigned AsmVariant, 288 const char *ExtraCode, 289 raw_ostream &O) { 290 if (ExtraCode && ExtraCode[0]) { 291 if (ExtraCode[1] != 0) return true; // Unknown modifier. 292 293 switch (ExtraCode[0]) { 294 default: return true; // Unknown modifier. 295 case 'y': // A memory reference for an X-form instruction 296 { 297 const char *RegName = "r0"; 298 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 299 O << RegName << ", "; 300 printOperand(MI, OpNo, O); 301 return false; 302 } 303 } 304 } 305 306 assert(MI->getOperand(OpNo).isReg()); 307 O << "0("; 308 printOperand(MI, OpNo, O); 309 O << ")"; 310 return false; 311 } 312 313 314 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 315 /// exists for it. If not, create one. Then return a symbol that references 316 /// the TOC entry. 317 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { 318 319 MCSymbol *&TOCEntry = TOC[Sym]; 320 321 // To avoid name clash check if the name already exists. 322 while (TOCEntry == 0) { 323 if (OutContext.LookupSymbol(Twine(MAI->getPrivateGlobalPrefix()) + 324 "C" + Twine(TOCLabelID++)) == 0) { 325 TOCEntry = GetTempSymbol("C", TOCLabelID); 326 } 327 } 328 329 return TOCEntry; 330 } 331 332 333 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 334 /// the current output stream. 335 /// 336 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 337 MCInst TmpInst; 338 339 // Lower multi-instruction pseudo operations. 340 switch (MI->getOpcode()) { 341 default: break; 342 case TargetOpcode::DBG_VALUE: { 343 if (!isVerbose() || !OutStreamer.hasRawTextSupport()) return; 344 345 SmallString<32> Str; 346 raw_svector_ostream O(Str); 347 unsigned NOps = MI->getNumOperands(); 348 assert(NOps==4); 349 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 350 // cast away const; DIetc do not take const operands for some reason. 351 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 352 O << V.getName(); 353 O << " <- "; 354 // Frame address. Currently handles register +- offset only. 355 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 356 O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O); 357 O << ']'; 358 O << "+"; 359 printOperand(MI, NOps-2, O); 360 OutStreamer.EmitRawText(O.str()); 361 return; 362 } 363 364 case PPC::MovePCtoLR: 365 case PPC::MovePCtoLR8: { 366 // Transform %LR = MovePCtoLR 367 // Into this, where the label is the PIC base: 368 // bl L1$pb 369 // L1$pb: 370 MCSymbol *PICBase = MF->getPICBaseSymbol(); 371 372 // Emit the 'bl'. 373 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL_Darwin) // Darwin vs SVR4 doesn't matter here. 374 // FIXME: We would like an efficient form for this, so we don't have to do 375 // a lot of extra uniquing. 376 .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 377 378 // Emit the label. 379 OutStreamer.EmitLabel(PICBase); 380 return; 381 } 382 case PPC::LDtocJTI: 383 case PPC::LDtocCPT: 384 case PPC::LDtoc: { 385 // Transform %X3 = LDtoc <ga:@min1>, %X2 386 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 387 388 // Change the opcode to LD, and the global address operand to be a 389 // reference to the TOC entry we will synthesize later. 390 TmpInst.setOpcode(PPC::LD); 391 const MachineOperand &MO = MI->getOperand(1); 392 393 // Map symbol -> label of TOC entry 394 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI()); 395 MCSymbol *MOSymbol = 0; 396 if (MO.isGlobal()) 397 MOSymbol = Mang->getSymbol(MO.getGlobal()); 398 else if (MO.isCPI()) 399 MOSymbol = GetCPISymbol(MO.getIndex()); 400 else if (MO.isJTI()) 401 MOSymbol = GetJTISymbol(MO.getIndex()); 402 403 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 404 405 const MCExpr *Exp = 406 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY, 407 OutContext); 408 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 409 OutStreamer.EmitInstruction(TmpInst); 410 return; 411 } 412 413 case PPC::ADDIStocHA: { 414 // Transform %Xd = ADDIStocHA %X2, <ga:@sym> 415 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 416 417 // Change the opcode to ADDIS8. If the global address is external, 418 // has common linkage, is a function address, or is a jump table 419 // address, then generate a TOC entry and reference that. Otherwise 420 // reference the symbol directly. 421 TmpInst.setOpcode(PPC::ADDIS8); 422 const MachineOperand &MO = MI->getOperand(2); 423 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI()) && 424 "Invalid operand for ADDIStocHA!"); 425 MCSymbol *MOSymbol = 0; 426 bool IsExternal = false; 427 bool IsFunction = false; 428 bool IsCommon = false; 429 bool IsAvailExt = false; 430 431 if (MO.isGlobal()) { 432 const GlobalValue *GValue = MO.getGlobal(); 433 const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue); 434 const GlobalValue *RealGValue = GAlias ? 435 GAlias->resolveAliasedGlobal(false) : GValue; 436 MOSymbol = Mang->getSymbol(RealGValue); 437 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue); 438 IsExternal = GVar && !GVar->hasInitializer(); 439 IsCommon = GVar && RealGValue->hasCommonLinkage(); 440 IsFunction = !GVar; 441 IsAvailExt = GVar && RealGValue->hasAvailableExternallyLinkage(); 442 } else if (MO.isCPI()) 443 MOSymbol = GetCPISymbol(MO.getIndex()); 444 else if (MO.isJTI()) 445 MOSymbol = GetJTISymbol(MO.getIndex()); 446 447 if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI()) 448 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 449 450 const MCExpr *Exp = 451 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_HA, 452 OutContext); 453 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 454 OutStreamer.EmitInstruction(TmpInst); 455 return; 456 } 457 case PPC::LDtocL: { 458 // Transform %Xd = LDtocL <ga:@sym>, %Xs 459 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 460 461 // Change the opcode to LDrs, which is a form of LD with the offset 462 // specified by a SymbolLo. If the global address is external, has 463 // common linkage, or is a jump table address, then reference the 464 // associated TOC entry. Otherwise reference the symbol directly. 465 TmpInst.setOpcode(PPC::LDrs); 466 const MachineOperand &MO = MI->getOperand(1); 467 assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) && 468 "Invalid operand for LDtocL!"); 469 MCSymbol *MOSymbol = 0; 470 471 if (MO.isJTI()) 472 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 473 else if (MO.isCPI()) 474 MOSymbol = GetCPISymbol(MO.getIndex()); 475 else if (MO.isGlobal()) { 476 const GlobalValue *GValue = MO.getGlobal(); 477 const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue); 478 const GlobalValue *RealGValue = GAlias ? 479 GAlias->resolveAliasedGlobal(false) : GValue; 480 MOSymbol = Mang->getSymbol(RealGValue); 481 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue); 482 483 if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() || 484 RealGValue->hasAvailableExternallyLinkage()) 485 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 486 } 487 488 const MCExpr *Exp = 489 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 490 OutContext); 491 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 492 OutStreamer.EmitInstruction(TmpInst); 493 return; 494 } 495 case PPC::ADDItocL: { 496 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 497 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 498 499 // Change the opcode to ADDI8L. If the global address is external, then 500 // generate a TOC entry and reference that. Otherwise reference the 501 // symbol directly. 502 TmpInst.setOpcode(PPC::ADDI8L); 503 const MachineOperand &MO = MI->getOperand(2); 504 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 505 MCSymbol *MOSymbol = 0; 506 bool IsExternal = false; 507 bool IsFunction = false; 508 509 if (MO.isGlobal()) { 510 const GlobalValue *GValue = MO.getGlobal(); 511 const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue); 512 const GlobalValue *RealGValue = GAlias ? 513 GAlias->resolveAliasedGlobal(false) : GValue; 514 MOSymbol = Mang->getSymbol(RealGValue); 515 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue); 516 IsExternal = GVar && !GVar->hasInitializer(); 517 IsFunction = !GVar; 518 } else if (MO.isCPI()) 519 MOSymbol = GetCPISymbol(MO.getIndex()); 520 521 if (IsFunction || IsExternal) 522 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 523 524 const MCExpr *Exp = 525 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 526 OutContext); 527 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 528 OutStreamer.EmitInstruction(TmpInst); 529 return; 530 } 531 case PPC::ADDISgotTprelHA: { 532 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 533 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 534 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 535 const MachineOperand &MO = MI->getOperand(2); 536 const GlobalValue *GValue = MO.getGlobal(); 537 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 538 const MCExpr *SymGotTprel = 539 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA, 540 OutContext); 541 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 542 .addReg(MI->getOperand(0).getReg()) 543 .addReg(PPC::X2) 544 .addExpr(SymGotTprel)); 545 return; 546 } 547 case PPC::LDgotTprelL: { 548 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 549 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 550 551 // Change the opcode to LDrs, which is a form of LD with the offset 552 // specified by a SymbolLo. 553 TmpInst.setOpcode(PPC::LDrs); 554 const MachineOperand &MO = MI->getOperand(1); 555 const GlobalValue *GValue = MO.getGlobal(); 556 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 557 const MCExpr *Exp = 558 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO, 559 OutContext); 560 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 561 OutStreamer.EmitInstruction(TmpInst); 562 return; 563 } 564 case PPC::ADDIStlsgdHA: { 565 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 566 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 567 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 568 const MachineOperand &MO = MI->getOperand(2); 569 const GlobalValue *GValue = MO.getGlobal(); 570 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 571 const MCExpr *SymGotTlsGD = 572 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA, 573 OutContext); 574 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 575 .addReg(MI->getOperand(0).getReg()) 576 .addReg(PPC::X2) 577 .addExpr(SymGotTlsGD)); 578 return; 579 } 580 case PPC::ADDItlsgdL: { 581 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 582 // Into: %Xd = ADDI8L %Xs, sym@got@tlsgd@l 583 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 584 const MachineOperand &MO = MI->getOperand(2); 585 const GlobalValue *GValue = MO.getGlobal(); 586 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 587 const MCExpr *SymGotTlsGD = 588 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO, 589 OutContext); 590 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 591 .addReg(MI->getOperand(0).getReg()) 592 .addReg(MI->getOperand(1).getReg()) 593 .addExpr(SymGotTlsGD)); 594 return; 595 } 596 case PPC::GETtlsADDR: { 597 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 598 // Into: BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd) 599 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 600 601 StringRef Name = "__tls_get_addr"; 602 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 603 const MCSymbolRefExpr *TlsRef = 604 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 605 const MachineOperand &MO = MI->getOperand(2); 606 const GlobalValue *GValue = MO.getGlobal(); 607 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 608 const MCExpr *SymVar = 609 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, 610 OutContext); 611 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD) 612 .addExpr(TlsRef) 613 .addExpr(SymVar)); 614 return; 615 } 616 case PPC::ADDIStlsldHA: { 617 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 618 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 619 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 620 const MachineOperand &MO = MI->getOperand(2); 621 const GlobalValue *GValue = MO.getGlobal(); 622 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 623 const MCExpr *SymGotTlsLD = 624 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA, 625 OutContext); 626 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 627 .addReg(MI->getOperand(0).getReg()) 628 .addReg(PPC::X2) 629 .addExpr(SymGotTlsLD)); 630 return; 631 } 632 case PPC::ADDItlsldL: { 633 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 634 // Into: %Xd = ADDI8L %Xs, sym@got@tlsld@l 635 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 636 const MachineOperand &MO = MI->getOperand(2); 637 const GlobalValue *GValue = MO.getGlobal(); 638 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 639 const MCExpr *SymGotTlsLD = 640 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO, 641 OutContext); 642 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 643 .addReg(MI->getOperand(0).getReg()) 644 .addReg(MI->getOperand(1).getReg()) 645 .addExpr(SymGotTlsLD)); 646 return; 647 } 648 case PPC::GETtlsldADDR: { 649 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 650 // Into: BL8_NOP_ELF_TLSLD __tls_get_addr(sym@tlsld) 651 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 652 653 StringRef Name = "__tls_get_addr"; 654 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 655 const MCSymbolRefExpr *TlsRef = 656 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 657 const MachineOperand &MO = MI->getOperand(2); 658 const GlobalValue *GValue = MO.getGlobal(); 659 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 660 const MCExpr *SymVar = 661 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, 662 OutContext); 663 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSLD) 664 .addExpr(TlsRef) 665 .addExpr(SymVar)); 666 return; 667 } 668 case PPC::ADDISdtprelHA: { 669 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 670 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 671 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 672 const MachineOperand &MO = MI->getOperand(2); 673 const GlobalValue *GValue = MO.getGlobal(); 674 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 675 const MCExpr *SymDtprel = 676 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA, 677 OutContext); 678 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 679 .addReg(MI->getOperand(0).getReg()) 680 .addReg(PPC::X3) 681 .addExpr(SymDtprel)); 682 return; 683 } 684 case PPC::ADDIdtprelL: { 685 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 686 // Into: %Xd = ADDI8L %Xs, sym@dtprel@l 687 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 688 const MachineOperand &MO = MI->getOperand(2); 689 const GlobalValue *GValue = MO.getGlobal(); 690 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 691 const MCExpr *SymDtprel = 692 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO, 693 OutContext); 694 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L) 695 .addReg(MI->getOperand(0).getReg()) 696 .addReg(MI->getOperand(1).getReg()) 697 .addExpr(SymDtprel)); 698 return; 699 } 700 case PPC::MFCRpseud: 701 case PPC::MFCR8pseud: 702 // Transform: %R3 = MFCRpseud %CR7 703 // Into: %R3 = MFCR ;; cr7 704 OutStreamer.AddComment(PPCInstPrinter:: 705 getRegisterName(MI->getOperand(1).getReg())); 706 OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR) 707 .addReg(MI->getOperand(0).getReg())); 708 return; 709 case PPC::SYNC: 710 // In Book E sync is called msync, handle this special case here... 711 if (Subtarget.isBookE()) { 712 OutStreamer.EmitRawText(StringRef("\tmsync")); 713 return; 714 } 715 } 716 717 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 718 OutStreamer.EmitInstruction(TmpInst); 719 } 720 721 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 722 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 723 return AsmPrinter::EmitFunctionEntryLabel(); 724 725 // Emit an official procedure descriptor. 726 const MCSection *Current = OutStreamer.getCurrentSection(); 727 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 728 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 729 SectionKind::getReadOnly()); 730 OutStreamer.SwitchSection(Section); 731 OutStreamer.EmitLabel(CurrentFnSym); 732 OutStreamer.EmitValueToAlignment(8); 733 MCSymbol *Symbol1 = 734 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 735 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 736 // entry point. 737 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 738 8 /*size*/); 739 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 740 // Generates a R_PPC64_TOC relocation for TOC base insertion. 741 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 742 MCSymbolRefExpr::VK_PPC_TOC, OutContext), 743 8/*size*/); 744 // Emit a null environment pointer. 745 OutStreamer.EmitIntValue(0, 8 /* size */); 746 OutStreamer.SwitchSection(Current); 747 748 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 749 ".L." + Twine(CurrentFnSym->getName())); 750 OutStreamer.EmitLabel(RealFnSym); 751 CurrentFnSymForSize = RealFnSym; 752 } 753 754 755 bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 756 const DataLayout *TD = TM.getDataLayout(); 757 758 bool isPPC64 = TD->getPointerSizeInBits() == 64; 759 760 if (isPPC64 && !TOC.empty()) { 761 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 762 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 763 SectionKind::getReadOnly()); 764 OutStreamer.SwitchSection(Section); 765 766 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 767 E = TOC.end(); I != E; ++I) { 768 OutStreamer.EmitLabel(I->second); 769 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 770 OutStreamer.EmitTCEntry(*S); 771 } 772 } 773 774 MachineModuleInfoELF &MMIELF = 775 MMI->getObjFileInfo<MachineModuleInfoELF>(); 776 777 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 778 if (!Stubs.empty()) { 779 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 780 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 781 // L_foo$stub: 782 OutStreamer.EmitLabel(Stubs[i].first); 783 // .long _foo 784 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 785 OutContext), 786 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 787 } 788 789 Stubs.clear(); 790 OutStreamer.AddBlankLine(); 791 } 792 793 return AsmPrinter::doFinalization(M); 794 } 795 796 /// EmitFunctionBodyEnd - Print the traceback table before the .size 797 /// directive. 798 /// 799 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 800 // Only the 64-bit target requires a traceback table. For now, 801 // we only emit the word of zeroes that GDB requires to find 802 // the end of the function, and zeroes for the eight-byte 803 // mandatory fields. 804 // FIXME: We should fill in the eight-byte mandatory fields as described in 805 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 806 // currently make use of these fields). 807 if (Subtarget.isPPC64()) { 808 OutStreamer.EmitIntValue(0, 4/*size*/); 809 OutStreamer.EmitIntValue(0, 8/*size*/); 810 } 811 } 812 813 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 814 static const char *const CPUDirectives[] = { 815 "", 816 "ppc", 817 "ppc440", 818 "ppc601", 819 "ppc602", 820 "ppc603", 821 "ppc7400", 822 "ppc750", 823 "ppc970", 824 "ppcA2", 825 "ppce500mc", 826 "ppce5500", 827 "power3", 828 "power4", 829 "power5", 830 "power5x", 831 "power6", 832 "power6x", 833 "power7", 834 "ppc64" 835 }; 836 837 unsigned Directive = Subtarget.getDarwinDirective(); 838 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 839 Directive = PPC::DIR_970; 840 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 841 Directive = PPC::DIR_7400; 842 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 843 Directive = PPC::DIR_64; 844 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 845 846 // FIXME: This is a total hack, finish mc'izing the PPC backend. 847 if (OutStreamer.hasRawTextSupport()) { 848 assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) && 849 "CPUDirectives[] might not be up-to-date!"); 850 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 851 } 852 853 // Prime text sections so they are adjacent. This reduces the likelihood a 854 // large data or debug section causes a branch to exceed 16M limit. 855 const TargetLoweringObjectFileMachO &TLOFMacho = 856 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 857 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 858 if (TM.getRelocationModel() == Reloc::PIC_) { 859 OutStreamer.SwitchSection( 860 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 861 MCSectionMachO::S_SYMBOL_STUBS | 862 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 863 32, SectionKind::getText())); 864 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 865 OutStreamer.SwitchSection( 866 OutContext.getMachOSection("__TEXT","__symbol_stub1", 867 MCSectionMachO::S_SYMBOL_STUBS | 868 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 869 16, SectionKind::getText())); 870 } 871 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 872 } 873 874 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 875 // Remove $stub suffix, add $lazy_ptr. 876 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 877 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 878 } 879 880 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 881 // Add $tmp suffix to $stub, yielding $stub$tmp. 882 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 883 } 884 885 void PPCDarwinAsmPrinter:: 886 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 887 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 888 889 const TargetLoweringObjectFileMachO &TLOFMacho = 890 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 891 892 // .lazy_symbol_pointer 893 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 894 895 // Output stubs for dynamically-linked functions 896 if (TM.getRelocationModel() == Reloc::PIC_) { 897 const MCSection *StubSection = 898 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 899 MCSectionMachO::S_SYMBOL_STUBS | 900 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 901 32, SectionKind::getText()); 902 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 903 OutStreamer.SwitchSection(StubSection); 904 EmitAlignment(4); 905 906 MCSymbol *Stub = Stubs[i].first; 907 MCSymbol *RawSym = Stubs[i].second.getPointer(); 908 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 909 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 910 911 OutStreamer.EmitLabel(Stub); 912 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 913 914 // mflr r0 915 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 916 // FIXME: MCize this. 917 OutStreamer.EmitRawText("\tbcl 20, 31, " + Twine(AnonSymbol->getName())); 918 OutStreamer.EmitLabel(AnonSymbol); 919 // mflr r11 920 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 921 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 922 const MCExpr *Sub = 923 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext), 924 MCSymbolRefExpr::Create(AnonSymbol, OutContext), 925 OutContext); 926 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) 927 .addReg(PPC::R11) 928 .addReg(PPC::R11) 929 .addExpr(Sub)); 930 // mtlr r0 931 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 932 933 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 934 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 935 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 936 .addReg(PPC::R12) 937 .addExpr(Sub).addExpr(Sub) 938 .addReg(PPC::R11)); 939 // mtctr r12 940 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 941 // bctr 942 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 943 944 OutStreamer.SwitchSection(LSPSection); 945 OutStreamer.EmitLabel(LazyPtr); 946 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 947 948 MCSymbol *DyldStubBindingHelper = 949 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 950 if (isPPC64) { 951 // .quad dyld_stub_binding_helper 952 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 953 } else { 954 // .long dyld_stub_binding_helper 955 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 956 } 957 } 958 OutStreamer.AddBlankLine(); 959 return; 960 } 961 962 const MCSection *StubSection = 963 OutContext.getMachOSection("__TEXT","__symbol_stub1", 964 MCSectionMachO::S_SYMBOL_STUBS | 965 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 966 16, SectionKind::getText()); 967 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 968 MCSymbol *Stub = Stubs[i].first; 969 MCSymbol *RawSym = Stubs[i].second.getPointer(); 970 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 971 972 OutStreamer.SwitchSection(StubSection); 973 EmitAlignment(4); 974 OutStreamer.EmitLabel(Stub); 975 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 976 // lis r11, ha16(LazyPtr) 977 const MCExpr *LazyPtrHa16 = 978 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16, 979 OutContext); 980 OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS) 981 .addReg(PPC::R11) 982 .addExpr(LazyPtrHa16)); 983 984 const MCExpr *LazyPtrLo16 = 985 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16, 986 OutContext); 987 // ldu r12, lo16(LazyPtr)(r11) 988 // lwzu r12, lo16(LazyPtr)(r11) 989 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 990 .addReg(PPC::R12) 991 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 992 .addReg(PPC::R11)); 993 994 // mtctr r12 995 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 996 // bctr 997 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 998 999 OutStreamer.SwitchSection(LSPSection); 1000 OutStreamer.EmitLabel(LazyPtr); 1001 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1002 1003 MCSymbol *DyldStubBindingHelper = 1004 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1005 if (isPPC64) { 1006 // .quad dyld_stub_binding_helper 1007 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1008 } else { 1009 // .long dyld_stub_binding_helper 1010 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1011 } 1012 } 1013 1014 OutStreamer.AddBlankLine(); 1015 } 1016 1017 1018 bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 1019 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1020 1021 // Darwin/PPC always uses mach-o. 1022 const TargetLoweringObjectFileMachO &TLOFMacho = 1023 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1024 MachineModuleInfoMachO &MMIMacho = 1025 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1026 1027 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 1028 if (!Stubs.empty()) 1029 EmitFunctionStubs(Stubs); 1030 1031 if (MAI->doesSupportExceptionHandling() && MMI) { 1032 // Add the (possibly multiple) personalities to the set of global values. 1033 // Only referenced functions get into the Personalities list. 1034 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 1035 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 1036 E = Personalities.end(); I != E; ++I) { 1037 if (*I) { 1038 MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 1039 MachineModuleInfoImpl::StubValueTy &StubSym = 1040 MMIMacho.getGVStubEntry(NLPSym); 1041 StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true); 1042 } 1043 } 1044 } 1045 1046 // Output stubs for dynamically-linked functions. 1047 Stubs = MMIMacho.GetGVStubList(); 1048 1049 // Output macho stubs for external and common global variables. 1050 if (!Stubs.empty()) { 1051 // Switch with ".non_lazy_symbol_pointer" directive. 1052 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 1053 EmitAlignment(isPPC64 ? 3 : 2); 1054 1055 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1056 // L_foo$stub: 1057 OutStreamer.EmitLabel(Stubs[i].first); 1058 // .indirect_symbol _foo 1059 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1060 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1061 1062 if (MCSym.getInt()) 1063 // External to current translation unit. 1064 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 1065 else 1066 // Internal to current translation unit. 1067 // 1068 // When we place the LSDA into the TEXT section, the type info pointers 1069 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1070 // However, sometimes the types are local to the file. So we need to 1071 // fill in the value for the NLP in those cases. 1072 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1073 OutContext), 1074 isPPC64 ? 8 : 4/*size*/); 1075 } 1076 1077 Stubs.clear(); 1078 OutStreamer.AddBlankLine(); 1079 } 1080 1081 Stubs = MMIMacho.GetHiddenGVStubList(); 1082 if (!Stubs.empty()) { 1083 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1084 EmitAlignment(isPPC64 ? 3 : 2); 1085 1086 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1087 // L_foo$stub: 1088 OutStreamer.EmitLabel(Stubs[i].first); 1089 // .long _foo 1090 OutStreamer.EmitValue(MCSymbolRefExpr:: 1091 Create(Stubs[i].second.getPointer(), 1092 OutContext), 1093 isPPC64 ? 8 : 4/*size*/); 1094 } 1095 1096 Stubs.clear(); 1097 OutStreamer.AddBlankLine(); 1098 } 1099 1100 // Funny Darwin hack: This flag tells the linker that no global symbols 1101 // contain code that falls through to other global symbols (e.g. the obvious 1102 // implementation of multiple entry points). If this doesn't occur, the 1103 // linker can safely perform dead code stripping. Since LLVM never generates 1104 // code that does this, it is always safe to set. 1105 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1106 1107 return AsmPrinter::doFinalization(M); 1108 } 1109 1110 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1111 /// for a MachineFunction to the given output stream, in a format that the 1112 /// Darwin assembler can deal with. 1113 /// 1114 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 1115 MCStreamer &Streamer) { 1116 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 1117 1118 if (Subtarget->isDarwin()) 1119 return new PPCDarwinAsmPrinter(tm, Streamer); 1120 return new PPCLinuxAsmPrinter(tm, Streamer); 1121 } 1122 1123 // Force static initialization. 1124 extern "C" void LLVMInitializePowerPCAsmPrinter() { 1125 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1126 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1127 } 1128