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 #include "PPC.h" 20 #include "InstPrinter/PPCInstPrinter.h" 21 #include "MCTargetDesc/PPCMCExpr.h" 22 #include "MCTargetDesc/PPCPredicates.h" 23 #include "PPCMachineFunctionInfo.h" 24 #include "PPCSubtarget.h" 25 #include "PPCTargetMachine.h" 26 #include "PPCTargetStreamer.h" 27 #include "llvm/ADT/MapVector.h" 28 #include "llvm/ADT/SmallString.h" 29 #include "llvm/ADT/StringExtras.h" 30 #include "llvm/CodeGen/AsmPrinter.h" 31 #include "llvm/CodeGen/MachineConstantPool.h" 32 #include "llvm/CodeGen/MachineFunctionPass.h" 33 #include "llvm/CodeGen/MachineInstr.h" 34 #include "llvm/CodeGen/MachineInstrBuilder.h" 35 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 36 #include "llvm/CodeGen/MachineRegisterInfo.h" 37 #include "llvm/CodeGen/StackMaps.h" 38 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 39 #include "llvm/IR/Constants.h" 40 #include "llvm/IR/DebugInfo.h" 41 #include "llvm/IR/DerivedTypes.h" 42 #include "llvm/IR/Mangler.h" 43 #include "llvm/IR/Module.h" 44 #include "llvm/MC/MCAsmInfo.h" 45 #include "llvm/MC/MCContext.h" 46 #include "llvm/MC/MCExpr.h" 47 #include "llvm/MC/MCInst.h" 48 #include "llvm/MC/MCInstBuilder.h" 49 #include "llvm/MC/MCSectionELF.h" 50 #include "llvm/MC/MCSectionMachO.h" 51 #include "llvm/MC/MCStreamer.h" 52 #include "llvm/MC/MCSymbol.h" 53 #include "llvm/Support/CommandLine.h" 54 #include "llvm/Support/Debug.h" 55 #include "llvm/Support/ELF.h" 56 #include "llvm/Support/ErrorHandling.h" 57 #include "llvm/Support/MathExtras.h" 58 #include "llvm/Support/TargetRegistry.h" 59 #include "llvm/Support/raw_ostream.h" 60 #include "llvm/Target/TargetInstrInfo.h" 61 #include "llvm/Target/TargetOptions.h" 62 #include "llvm/Target/TargetRegisterInfo.h" 63 using namespace llvm; 64 65 #define DEBUG_TYPE "asmprinter" 66 67 namespace { 68 class PPCAsmPrinter : public AsmPrinter { 69 protected: 70 MapVector<MCSymbol*, MCSymbol*> TOC; 71 const PPCSubtarget *Subtarget; 72 uint64_t TOCLabelID; 73 StackMaps SM; 74 public: 75 explicit PPCAsmPrinter(TargetMachine &TM, 76 std::unique_ptr<MCStreamer> Streamer) 77 : AsmPrinter(TM, std::move(Streamer)), TOCLabelID(0), SM(*this) {} 78 79 const char *getPassName() const override { 80 return "PowerPC Assembly Printer"; 81 } 82 83 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym); 84 85 void EmitInstruction(const MachineInstr *MI) override; 86 87 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 88 89 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 90 unsigned AsmVariant, const char *ExtraCode, 91 raw_ostream &O) override; 92 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 93 unsigned AsmVariant, const char *ExtraCode, 94 raw_ostream &O) override; 95 96 void EmitEndOfAsmFile(Module &M) override; 97 98 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM, 99 const MachineInstr &MI); 100 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, 101 const MachineInstr &MI); 102 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); 103 bool runOnMachineFunction(MachineFunction &MF) override { 104 Subtarget = &MF.getSubtarget<PPCSubtarget>(); 105 return AsmPrinter::runOnMachineFunction(MF); 106 } 107 }; 108 109 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 110 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 111 public: 112 explicit PPCLinuxAsmPrinter(TargetMachine &TM, 113 std::unique_ptr<MCStreamer> Streamer) 114 : PPCAsmPrinter(TM, std::move(Streamer)) {} 115 116 const char *getPassName() const override { 117 return "Linux PPC Assembly Printer"; 118 } 119 120 bool doFinalization(Module &M) override; 121 void EmitStartOfAsmFile(Module &M) override; 122 123 void EmitFunctionEntryLabel() override; 124 125 void EmitFunctionBodyStart() override; 126 void EmitFunctionBodyEnd() override; 127 }; 128 129 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 130 /// OS X 131 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 132 public: 133 explicit PPCDarwinAsmPrinter(TargetMachine &TM, 134 std::unique_ptr<MCStreamer> Streamer) 135 : PPCAsmPrinter(TM, std::move(Streamer)) {} 136 137 const char *getPassName() const override { 138 return "Darwin PPC Assembly Printer"; 139 } 140 141 bool doFinalization(Module &M) override; 142 void EmitStartOfAsmFile(Module &M) override; 143 144 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 145 }; 146 } // end of anonymous namespace 147 148 /// stripRegisterPrefix - This method strips the character prefix from a 149 /// register name so that only the number is left. Used by for linux asm. 150 static const char *stripRegisterPrefix(const char *RegName) { 151 switch (RegName[0]) { 152 case 'r': 153 case 'f': 154 case 'q': // for QPX 155 case 'v': 156 if (RegName[1] == 's') 157 return RegName + 2; 158 return RegName + 1; 159 case 'c': if (RegName[1] == 'r') return RegName + 2; 160 } 161 162 return RegName; 163 } 164 165 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 166 raw_ostream &O) { 167 const DataLayout *DL = TM.getDataLayout(); 168 const MachineOperand &MO = MI->getOperand(OpNo); 169 170 switch (MO.getType()) { 171 case MachineOperand::MO_Register: { 172 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 173 // Linux assembler (Others?) does not take register mnemonics. 174 // FIXME - What about special registers used in mfspr/mtspr? 175 if (!Subtarget->isDarwin()) 176 RegName = stripRegisterPrefix(RegName); 177 O << RegName; 178 return; 179 } 180 case MachineOperand::MO_Immediate: 181 O << MO.getImm(); 182 return; 183 184 case MachineOperand::MO_MachineBasicBlock: 185 O << *MO.getMBB()->getSymbol(); 186 return; 187 case MachineOperand::MO_ConstantPoolIndex: 188 O << DL->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 189 << '_' << MO.getIndex(); 190 return; 191 case MachineOperand::MO_BlockAddress: 192 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 193 return; 194 case MachineOperand::MO_GlobalAddress: { 195 // Computing the address of a global symbol, not calling it. 196 const GlobalValue *GV = MO.getGlobal(); 197 MCSymbol *SymToPrint; 198 199 // External or weakly linked global variables need non-lazily-resolved stubs 200 if (TM.getRelocationModel() != Reloc::Static && 201 (GV->isDeclaration() || GV->isWeakForLinker())) { 202 if (!GV->hasHiddenVisibility()) { 203 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 204 MachineModuleInfoImpl::StubValueTy &StubSym = 205 MMI->getObjFileInfo<MachineModuleInfoMachO>() 206 .getGVStubEntry(SymToPrint); 207 if (!StubSym.getPointer()) 208 StubSym = MachineModuleInfoImpl:: 209 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 210 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 211 GV->hasAvailableExternallyLinkage()) { 212 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 213 214 MachineModuleInfoImpl::StubValueTy &StubSym = 215 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 216 getHiddenGVStubEntry(SymToPrint); 217 if (!StubSym.getPointer()) 218 StubSym = MachineModuleInfoImpl:: 219 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 220 } else { 221 SymToPrint = getSymbol(GV); 222 } 223 } else { 224 SymToPrint = getSymbol(GV); 225 } 226 227 O << *SymToPrint; 228 229 printOffset(MO.getOffset(), O); 230 return; 231 } 232 233 default: 234 O << "<unknown operand type: " << (unsigned)MO.getType() << ">"; 235 return; 236 } 237 } 238 239 /// PrintAsmOperand - Print out an operand for an inline asm expression. 240 /// 241 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 242 unsigned AsmVariant, 243 const char *ExtraCode, raw_ostream &O) { 244 // Does this asm operand have a single letter operand modifier? 245 if (ExtraCode && ExtraCode[0]) { 246 if (ExtraCode[1] != 0) return true; // Unknown modifier. 247 248 switch (ExtraCode[0]) { 249 default: 250 // See if this is a generic print operand 251 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 252 case 'c': // Don't print "$" before a global var name or constant. 253 break; // PPC never has a prefix. 254 case 'L': // Write second word of DImode reference. 255 // Verify that this operand has two consecutive registers. 256 if (!MI->getOperand(OpNo).isReg() || 257 OpNo+1 == MI->getNumOperands() || 258 !MI->getOperand(OpNo+1).isReg()) 259 return true; 260 ++OpNo; // Return the high-part. 261 break; 262 case 'I': 263 // Write 'i' if an integer constant, otherwise nothing. Used to print 264 // addi vs add, etc. 265 if (MI->getOperand(OpNo).isImm()) 266 O << "i"; 267 return false; 268 } 269 } 270 271 printOperand(MI, OpNo, O); 272 return false; 273 } 274 275 // At the moment, all inline asm memory operands are a single register. 276 // In any case, the output of this routine should always be just one 277 // assembler operand. 278 279 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 280 unsigned AsmVariant, 281 const char *ExtraCode, 282 raw_ostream &O) { 283 if (ExtraCode && ExtraCode[0]) { 284 if (ExtraCode[1] != 0) return true; // Unknown modifier. 285 286 switch (ExtraCode[0]) { 287 default: return true; // Unknown modifier. 288 case 'y': // A memory reference for an X-form instruction 289 { 290 const char *RegName = "r0"; 291 if (!Subtarget->isDarwin()) 292 RegName = stripRegisterPrefix(RegName); 293 O << RegName << ", "; 294 printOperand(MI, OpNo, O); 295 return false; 296 } 297 case 'U': // Print 'u' for update form. 298 case 'X': // Print 'x' for indexed form. 299 { 300 // FIXME: Currently for PowerPC memory operands are always loaded 301 // into a register, so we never get an update or indexed form. 302 // This is bad even for offset forms, since even if we know we 303 // have a value in -16(r1), we will generate a load into r<n> 304 // and then load from 0(r<n>). Until that issue is fixed, 305 // tolerate 'U' and 'X' but don't output anything. 306 assert(MI->getOperand(OpNo).isReg()); 307 return false; 308 } 309 } 310 } 311 312 assert(MI->getOperand(OpNo).isReg()); 313 O << "0("; 314 printOperand(MI, OpNo, O); 315 O << ")"; 316 return false; 317 } 318 319 320 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 321 /// exists for it. If not, create one. Then return a symbol that references 322 /// the TOC entry. 323 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { 324 const DataLayout *DL = TM.getDataLayout(); 325 MCSymbol *&TOCEntry = TOC[Sym]; 326 327 // To avoid name clash check if the name already exists. 328 while (!TOCEntry) { 329 if (OutContext.LookupSymbol(Twine(DL->getPrivateGlobalPrefix()) + 330 "C" + Twine(TOCLabelID++)) == nullptr) { 331 TOCEntry = GetTempSymbol("C", TOCLabelID); 332 } 333 } 334 335 return TOCEntry; 336 } 337 338 void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) { 339 SM.serializeToStackMapSection(); 340 } 341 342 void PPCAsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM, 343 const MachineInstr &MI) { 344 unsigned NumNOPBytes = MI.getOperand(1).getImm(); 345 346 SM.recordStackMap(MI); 347 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 348 349 // Scan ahead to trim the shadow. 350 const MachineBasicBlock &MBB = *MI.getParent(); 351 MachineBasicBlock::const_iterator MII(MI); 352 ++MII; 353 while (NumNOPBytes > 0) { 354 if (MII == MBB.end() || MII->isCall() || 355 MII->getOpcode() == PPC::DBG_VALUE || 356 MII->getOpcode() == TargetOpcode::PATCHPOINT || 357 MII->getOpcode() == TargetOpcode::STACKMAP) 358 break; 359 ++MII; 360 NumNOPBytes -= 4; 361 } 362 363 // Emit nops. 364 for (unsigned i = 0; i < NumNOPBytes; i += 4) 365 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP)); 366 } 367 368 // Lower a patchpoint of the form: 369 // [<def>], <id>, <numBytes>, <target>, <numArgs> 370 void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, 371 const MachineInstr &MI) { 372 SM.recordPatchPoint(MI); 373 PatchPointOpers Opers(&MI); 374 375 int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm(); 376 unsigned EncodedBytes = 0; 377 if (CallTarget) { 378 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && 379 "High 16 bits of call target should be zero."); 380 unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg(); 381 EncodedBytes = 6*4; 382 // Materialize the jump address: 383 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8) 384 .addReg(ScratchReg) 385 .addImm((CallTarget >> 32) & 0xFFFF)); 386 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC) 387 .addReg(ScratchReg) 388 .addReg(ScratchReg) 389 .addImm(32).addImm(16)); 390 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8) 391 .addReg(ScratchReg) 392 .addReg(ScratchReg) 393 .addImm((CallTarget >> 16) & 0xFFFF)); 394 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8) 395 .addReg(ScratchReg) 396 .addReg(ScratchReg) 397 .addImm(CallTarget & 0xFFFF)); 398 399 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg)); 400 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8)); 401 } 402 403 // Emit padding. 404 unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm(); 405 assert(NumBytes >= EncodedBytes && 406 "Patchpoint can't request size less than the length of a call."); 407 assert((NumBytes - EncodedBytes) % 4 == 0 && 408 "Invalid number of NOP bytes requested!"); 409 for (unsigned i = EncodedBytes; i < NumBytes; i += 4) 410 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP)); 411 } 412 413 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a 414 /// call to __tls_get_addr to the current output stream. 415 void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, 416 MCSymbolRefExpr::VariantKind VK) { 417 StringRef Name = "__tls_get_addr"; 418 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 419 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 420 421 assert(MI->getOperand(0).isReg() && 422 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || 423 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && 424 "GETtls[ld]ADDR[32] must define GPR3"); 425 assert(MI->getOperand(1).isReg() && 426 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || 427 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && 428 "GETtls[ld]ADDR[32] must read GPR3"); 429 430 if (!Subtarget->isPPC64() && !Subtarget->isDarwin() && 431 TM.getRelocationModel() == Reloc::PIC_) 432 Kind = MCSymbolRefExpr::VK_PLT; 433 const MCSymbolRefExpr *TlsRef = 434 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); 435 const MachineOperand &MO = MI->getOperand(2); 436 const GlobalValue *GValue = MO.getGlobal(); 437 MCSymbol *MOSymbol = getSymbol(GValue); 438 const MCExpr *SymVar = MCSymbolRefExpr::Create(MOSymbol, VK, OutContext); 439 EmitToStreamer(OutStreamer, 440 MCInstBuilder(Subtarget->isPPC64() ? 441 PPC::BL8_NOP_TLS : PPC::BL_TLS) 442 .addExpr(TlsRef) 443 .addExpr(SymVar)); 444 } 445 446 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 447 /// the current output stream. 448 /// 449 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 450 MCInst TmpInst; 451 bool isPPC64 = Subtarget->isPPC64(); 452 bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin(); 453 const Module *M = MF->getFunction()->getParent(); 454 PICLevel::Level PL = M->getPICLevel(); 455 456 // Lower multi-instruction pseudo operations. 457 switch (MI->getOpcode()) { 458 default: break; 459 case TargetOpcode::DBG_VALUE: 460 llvm_unreachable("Should be handled target independently"); 461 case TargetOpcode::STACKMAP: 462 return LowerSTACKMAP(OutStreamer, SM, *MI); 463 case TargetOpcode::PATCHPOINT: 464 return LowerPATCHPOINT(OutStreamer, SM, *MI); 465 466 case PPC::MoveGOTtoLR: { 467 // Transform %LR = MoveGOTtoLR 468 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 469 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding 470 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction: 471 // blrl 472 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local 473 MCSymbol *GOTSymbol = 474 OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 475 const MCExpr *OffsExpr = 476 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, 477 MCSymbolRefExpr::VK_PPC_LOCAL, 478 OutContext), 479 MCConstantExpr::Create(4, OutContext), 480 OutContext); 481 482 // Emit the 'bl'. 483 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); 484 return; 485 } 486 case PPC::MovePCtoLR: 487 case PPC::MovePCtoLR8: { 488 // Transform %LR = MovePCtoLR 489 // Into this, where the label is the PIC base: 490 // bl L1$pb 491 // L1$pb: 492 MCSymbol *PICBase = MF->getPICBaseSymbol(); 493 494 // Emit the 'bl'. 495 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 496 // FIXME: We would like an efficient form for this, so we don't have to do 497 // a lot of extra uniquing. 498 .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 499 500 // Emit the label. 501 OutStreamer.EmitLabel(PICBase); 502 return; 503 } 504 case PPC::UpdateGBR: { 505 // Transform %Rd = UpdateGBR(%Rt, %Ri) 506 // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri) 507 // add %Rd, %Rt, %Ri 508 // Get the offset from the GOT Base Register to the GOT 509 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 510 MCSymbol *PICOffset = 511 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); 512 TmpInst.setOpcode(PPC::LWZ); 513 const MCExpr *Exp = 514 MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); 515 const MCExpr *PB = 516 MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), 517 MCSymbolRefExpr::VK_None, 518 OutContext); 519 const MCOperand TR = TmpInst.getOperand(1); 520 const MCOperand PICR = TmpInst.getOperand(0); 521 522 // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri) 523 TmpInst.getOperand(1) = 524 MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext)); 525 TmpInst.getOperand(0) = TR; 526 TmpInst.getOperand(2) = PICR; 527 EmitToStreamer(OutStreamer, TmpInst); 528 529 TmpInst.setOpcode(PPC::ADD4); 530 TmpInst.getOperand(0) = PICR; 531 TmpInst.getOperand(1) = TR; 532 TmpInst.getOperand(2) = PICR; 533 EmitToStreamer(OutStreamer, TmpInst); 534 return; 535 } 536 case PPC::LWZtoc: { 537 // Transform %R3 = LWZtoc <ga:@min1>, %R2 538 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 539 540 // Change the opcode to LWZ, and the global address operand to be a 541 // reference to the GOT entry we will synthesize later. 542 TmpInst.setOpcode(PPC::LWZ); 543 const MachineOperand &MO = MI->getOperand(1); 544 545 // Map symbol -> label of TOC entry 546 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); 547 MCSymbol *MOSymbol = nullptr; 548 if (MO.isGlobal()) 549 MOSymbol = getSymbol(MO.getGlobal()); 550 else if (MO.isCPI()) 551 MOSymbol = GetCPISymbol(MO.getIndex()); 552 else if (MO.isJTI()) 553 MOSymbol = GetJTISymbol(MO.getIndex()); 554 else if (MO.isBlockAddress()) 555 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 556 557 if (PL == PICLevel::Small) { 558 const MCExpr *Exp = 559 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT, 560 OutContext); 561 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 562 } else { 563 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 564 565 const MCExpr *Exp = 566 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, 567 OutContext); 568 const MCExpr *PB = 569 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), 570 OutContext); 571 Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); 572 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 573 } 574 EmitToStreamer(OutStreamer, TmpInst); 575 return; 576 } 577 case PPC::LDtocJTI: 578 case PPC::LDtocCPT: 579 case PPC::LDtocBA: 580 case PPC::LDtoc: { 581 // Transform %X3 = LDtoc <ga:@min1>, %X2 582 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 583 584 // Change the opcode to LD, and the global address operand to be a 585 // reference to the TOC entry we will synthesize later. 586 TmpInst.setOpcode(PPC::LD); 587 const MachineOperand &MO = MI->getOperand(1); 588 589 // Map symbol -> label of TOC entry 590 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); 591 MCSymbol *MOSymbol = nullptr; 592 if (MO.isGlobal()) 593 MOSymbol = getSymbol(MO.getGlobal()); 594 else if (MO.isCPI()) 595 MOSymbol = GetCPISymbol(MO.getIndex()); 596 else if (MO.isJTI()) 597 MOSymbol = GetJTISymbol(MO.getIndex()); 598 else if (MO.isBlockAddress()) 599 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 600 601 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 602 603 const MCExpr *Exp = 604 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, 605 OutContext); 606 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 607 EmitToStreamer(OutStreamer, TmpInst); 608 return; 609 } 610 611 case PPC::ADDIStocHA: { 612 // Transform %Xd = ADDIStocHA %X2, <ga:@sym> 613 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 614 615 // Change the opcode to ADDIS8. If the global address is external, has 616 // common linkage, is a non-local function address, or is a jump table 617 // address, then generate a TOC entry and reference that. Otherwise 618 // reference the symbol directly. 619 TmpInst.setOpcode(PPC::ADDIS8); 620 const MachineOperand &MO = MI->getOperand(2); 621 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 622 MO.isBlockAddress()) && 623 "Invalid operand for ADDIStocHA!"); 624 MCSymbol *MOSymbol = nullptr; 625 bool IsExternal = false; 626 bool IsNonLocalFunction = false; 627 bool IsCommon = false; 628 bool IsAvailExt = false; 629 630 if (MO.isGlobal()) { 631 const GlobalValue *GV = MO.getGlobal(); 632 MOSymbol = getSymbol(GV); 633 IsExternal = GV->isDeclaration(); 634 IsCommon = GV->hasCommonLinkage(); 635 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 636 (GV->isDeclaration() || GV->isWeakForLinker()); 637 IsAvailExt = GV->hasAvailableExternallyLinkage(); 638 } else if (MO.isCPI()) 639 MOSymbol = GetCPISymbol(MO.getIndex()); 640 else if (MO.isJTI()) 641 MOSymbol = GetJTISymbol(MO.getIndex()); 642 else if (MO.isBlockAddress()) 643 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 644 645 if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt || 646 MO.isJTI() || MO.isBlockAddress() || 647 TM.getCodeModel() == CodeModel::Large) 648 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 649 650 const MCExpr *Exp = 651 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, 652 OutContext); 653 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 654 EmitToStreamer(OutStreamer, TmpInst); 655 return; 656 } 657 case PPC::LDtocL: { 658 // Transform %Xd = LDtocL <ga:@sym>, %Xs 659 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 660 661 // Change the opcode to LD. If the global address is external, has 662 // common linkage, or is a jump table address, then reference the 663 // associated TOC entry. Otherwise reference the symbol directly. 664 TmpInst.setOpcode(PPC::LD); 665 const MachineOperand &MO = MI->getOperand(1); 666 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 667 MO.isBlockAddress()) && 668 "Invalid operand for LDtocL!"); 669 MCSymbol *MOSymbol = nullptr; 670 671 if (MO.isJTI()) 672 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 673 else if (MO.isBlockAddress()) { 674 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 675 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 676 } 677 else if (MO.isCPI()) { 678 MOSymbol = GetCPISymbol(MO.getIndex()); 679 if (TM.getCodeModel() == CodeModel::Large) 680 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 681 } 682 else if (MO.isGlobal()) { 683 const GlobalValue *GValue = MO.getGlobal(); 684 MOSymbol = getSymbol(GValue); 685 if (GValue->getType()->getElementType()->isFunctionTy() || 686 GValue->isDeclaration() || GValue->hasCommonLinkage() || 687 GValue->hasAvailableExternallyLinkage() || 688 TM.getCodeModel() == CodeModel::Large) 689 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 690 } 691 692 const MCExpr *Exp = 693 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 694 OutContext); 695 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 696 EmitToStreamer(OutStreamer, TmpInst); 697 return; 698 } 699 case PPC::ADDItocL: { 700 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 701 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 702 703 // Change the opcode to ADDI8. If the global address is external, then 704 // generate a TOC entry and reference that. Otherwise reference the 705 // symbol directly. 706 TmpInst.setOpcode(PPC::ADDI8); 707 const MachineOperand &MO = MI->getOperand(2); 708 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 709 MCSymbol *MOSymbol = nullptr; 710 bool IsExternal = false; 711 bool IsNonLocalFunction = false; 712 713 if (MO.isGlobal()) { 714 const GlobalValue *GV = MO.getGlobal(); 715 MOSymbol = getSymbol(GV); 716 IsExternal = GV->isDeclaration(); 717 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 718 (GV->isDeclaration() || GV->isWeakForLinker()); 719 } else if (MO.isCPI()) 720 MOSymbol = GetCPISymbol(MO.getIndex()); 721 722 if (IsNonLocalFunction || IsExternal || 723 TM.getCodeModel() == CodeModel::Large) 724 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 725 726 const MCExpr *Exp = 727 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 728 OutContext); 729 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 730 EmitToStreamer(OutStreamer, TmpInst); 731 return; 732 } 733 case PPC::ADDISgotTprelHA: { 734 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 735 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 736 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 737 const MachineOperand &MO = MI->getOperand(2); 738 const GlobalValue *GValue = MO.getGlobal(); 739 MCSymbol *MOSymbol = getSymbol(GValue); 740 const MCExpr *SymGotTprel = 741 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 742 OutContext); 743 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 744 .addReg(MI->getOperand(0).getReg()) 745 .addReg(MI->getOperand(1).getReg()) 746 .addExpr(SymGotTprel)); 747 return; 748 } 749 case PPC::LDgotTprelL: 750 case PPC::LDgotTprelL32: { 751 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 752 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 753 754 // Change the opcode to LD. 755 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); 756 const MachineOperand &MO = MI->getOperand(1); 757 const GlobalValue *GValue = MO.getGlobal(); 758 MCSymbol *MOSymbol = getSymbol(GValue); 759 const MCExpr *Exp = 760 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, 761 OutContext); 762 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 763 EmitToStreamer(OutStreamer, TmpInst); 764 return; 765 } 766 767 case PPC::PPC32PICGOT: { 768 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 769 MCSymbol *GOTRef = OutContext.CreateTempSymbol(); 770 MCSymbol *NextInstr = OutContext.CreateTempSymbol(); 771 772 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 773 // FIXME: We would like an efficient form for this, so we don't have to do 774 // a lot of extra uniquing. 775 .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext))); 776 const MCExpr *OffsExpr = 777 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext), 778 MCSymbolRefExpr::Create(GOTRef, OutContext), 779 OutContext); 780 OutStreamer.EmitLabel(GOTRef); 781 OutStreamer.EmitValue(OffsExpr, 4); 782 OutStreamer.EmitLabel(NextInstr); 783 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR) 784 .addReg(MI->getOperand(0).getReg())); 785 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LWZ) 786 .addReg(MI->getOperand(1).getReg()) 787 .addImm(0) 788 .addReg(MI->getOperand(0).getReg())); 789 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADD4) 790 .addReg(MI->getOperand(0).getReg()) 791 .addReg(MI->getOperand(1).getReg()) 792 .addReg(MI->getOperand(0).getReg())); 793 return; 794 } 795 case PPC::PPC32GOT: { 796 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 797 const MCExpr *SymGotTlsL = 798 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, 799 OutContext); 800 const MCExpr *SymGotTlsHA = 801 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, 802 OutContext); 803 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI) 804 .addReg(MI->getOperand(0).getReg()) 805 .addExpr(SymGotTlsL)); 806 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 807 .addReg(MI->getOperand(0).getReg()) 808 .addReg(MI->getOperand(0).getReg()) 809 .addExpr(SymGotTlsHA)); 810 return; 811 } 812 case PPC::ADDIStlsgdHA: { 813 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 814 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 815 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 816 const MachineOperand &MO = MI->getOperand(2); 817 const GlobalValue *GValue = MO.getGlobal(); 818 MCSymbol *MOSymbol = getSymbol(GValue); 819 const MCExpr *SymGotTlsGD = 820 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 821 OutContext); 822 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 823 .addReg(MI->getOperand(0).getReg()) 824 .addReg(MI->getOperand(1).getReg()) 825 .addExpr(SymGotTlsGD)); 826 return; 827 } 828 case PPC::ADDItlsgdL: 829 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 830 // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l 831 case PPC::ADDItlsgdL32: { 832 // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym> 833 // Into: %Rd = ADDI %Rs, sym@got@tlsgd 834 const MachineOperand &MO = MI->getOperand(2); 835 const GlobalValue *GValue = MO.getGlobal(); 836 MCSymbol *MOSymbol = getSymbol(GValue); 837 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::Create( 838 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO 839 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, 840 OutContext); 841 EmitToStreamer(OutStreamer, 842 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 843 .addReg(MI->getOperand(0).getReg()) 844 .addReg(MI->getOperand(1).getReg()) 845 .addExpr(SymGotTlsGD)); 846 return; 847 } 848 case PPC::GETtlsADDR: 849 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 850 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) 851 case PPC::GETtlsADDR32: { 852 // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym> 853 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT 854 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD); 855 return; 856 } 857 case PPC::ADDIStlsldHA: { 858 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 859 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 860 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 861 const MachineOperand &MO = MI->getOperand(2); 862 const GlobalValue *GValue = MO.getGlobal(); 863 MCSymbol *MOSymbol = getSymbol(GValue); 864 const MCExpr *SymGotTlsLD = 865 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 866 OutContext); 867 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 868 .addReg(MI->getOperand(0).getReg()) 869 .addReg(MI->getOperand(1).getReg()) 870 .addExpr(SymGotTlsLD)); 871 return; 872 } 873 case PPC::ADDItlsldL: 874 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 875 // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l 876 case PPC::ADDItlsldL32: { 877 // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym> 878 // Into: %Rd = ADDI %Rs, sym@got@tlsld 879 const MachineOperand &MO = MI->getOperand(2); 880 const GlobalValue *GValue = MO.getGlobal(); 881 MCSymbol *MOSymbol = getSymbol(GValue); 882 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::Create( 883 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO 884 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, 885 OutContext); 886 EmitToStreamer(OutStreamer, 887 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 888 .addReg(MI->getOperand(0).getReg()) 889 .addReg(MI->getOperand(1).getReg()) 890 .addExpr(SymGotTlsLD)); 891 return; 892 } 893 case PPC::GETtlsldADDR: 894 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 895 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) 896 case PPC::GETtlsldADDR32: { 897 // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym> 898 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT 899 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD); 900 return; 901 } 902 case PPC::ADDISdtprelHA: 903 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 904 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 905 case PPC::ADDISdtprelHA32: { 906 // Transform: %Rd = ADDISdtprelHA32 %R3, <ga:@sym> 907 // Into: %Rd = ADDIS %R3, sym@dtprel@ha 908 const MachineOperand &MO = MI->getOperand(2); 909 const GlobalValue *GValue = MO.getGlobal(); 910 MCSymbol *MOSymbol = getSymbol(GValue); 911 const MCExpr *SymDtprel = 912 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 913 OutContext); 914 EmitToStreamer( 915 OutStreamer, 916 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) 917 .addReg(MI->getOperand(0).getReg()) 918 .addReg(Subtarget->isPPC64() ? PPC::X3 : PPC::R3) 919 .addExpr(SymDtprel)); 920 return; 921 } 922 case PPC::ADDIdtprelL: 923 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 924 // Into: %Xd = ADDI8 %Xs, sym@dtprel@l 925 case PPC::ADDIdtprelL32: { 926 // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym> 927 // Into: %Rd = ADDI %Rs, sym@dtprel@l 928 const MachineOperand &MO = MI->getOperand(2); 929 const GlobalValue *GValue = MO.getGlobal(); 930 MCSymbol *MOSymbol = getSymbol(GValue); 931 const MCExpr *SymDtprel = 932 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 933 OutContext); 934 EmitToStreamer(OutStreamer, 935 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 936 .addReg(MI->getOperand(0).getReg()) 937 .addReg(MI->getOperand(1).getReg()) 938 .addExpr(SymDtprel)); 939 return; 940 } 941 case PPC::MFOCRF: 942 case PPC::MFOCRF8: 943 if (!Subtarget->hasMFOCRF()) { 944 // Transform: %R3 = MFOCRF %CR7 945 // Into: %R3 = MFCR ;; cr7 946 unsigned NewOpcode = 947 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 948 OutStreamer.AddComment(PPCInstPrinter:: 949 getRegisterName(MI->getOperand(1).getReg())); 950 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 951 .addReg(MI->getOperand(0).getReg())); 952 return; 953 } 954 break; 955 case PPC::MTOCRF: 956 case PPC::MTOCRF8: 957 if (!Subtarget->hasMFOCRF()) { 958 // Transform: %CR7 = MTOCRF %R3 959 // Into: MTCRF mask, %R3 ;; cr7 960 unsigned NewOpcode = 961 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 962 unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 963 ->getEncodingValue(MI->getOperand(0).getReg()); 964 OutStreamer.AddComment(PPCInstPrinter:: 965 getRegisterName(MI->getOperand(0).getReg())); 966 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 967 .addImm(Mask) 968 .addReg(MI->getOperand(1).getReg())); 969 return; 970 } 971 break; 972 case PPC::LD: 973 case PPC::STD: 974 case PPC::LWA_32: 975 case PPC::LWA: { 976 // Verify alignment is legal, so we don't create relocations 977 // that can't be supported. 978 // FIXME: This test is currently disabled for Darwin. The test 979 // suite shows a handful of test cases that fail this check for 980 // Darwin. Those need to be investigated before this sanity test 981 // can be enabled for those subtargets. 982 if (!Subtarget->isDarwin()) { 983 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 984 const MachineOperand &MO = MI->getOperand(OpNum); 985 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 986 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 987 } 988 // Now process the instruction normally. 989 break; 990 } 991 } 992 993 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 994 EmitToStreamer(OutStreamer, TmpInst); 995 } 996 997 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { 998 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) { 999 PPCTargetStreamer *TS = 1000 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 1001 1002 if (TS) 1003 TS->emitAbiVersion(2); 1004 } 1005 1006 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() || 1007 TM.getRelocationModel() != Reloc::PIC_) 1008 return AsmPrinter::EmitStartOfAsmFile(M); 1009 1010 if (M.getPICLevel() == PICLevel::Small) 1011 return AsmPrinter::EmitStartOfAsmFile(M); 1012 1013 OutStreamer.SwitchSection(OutContext.getELFSection( 1014 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC)); 1015 1016 MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC")); 1017 MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); 1018 1019 OutStreamer.EmitLabel(CurrentPos); 1020 1021 // The GOT pointer points to the middle of the GOT, in order to reference the 1022 // entire 64kB range. 0x8000 is the midpoint. 1023 const MCExpr *tocExpr = 1024 MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext), 1025 MCConstantExpr::Create(0x8000, OutContext), 1026 OutContext); 1027 1028 OutStreamer.EmitAssignment(TOCSym, tocExpr); 1029 1030 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 1031 } 1032 1033 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 1034 // linux/ppc32 - Normal entry label. 1035 if (!Subtarget->isPPC64() && 1036 (TM.getRelocationModel() != Reloc::PIC_ || 1037 MF->getFunction()->getParent()->getPICLevel() == PICLevel::Small)) 1038 return AsmPrinter::EmitFunctionEntryLabel(); 1039 1040 if (!Subtarget->isPPC64()) { 1041 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1042 if (PPCFI->usesPICBase()) { 1043 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); 1044 MCSymbol *PICBase = MF->getPICBaseSymbol(); 1045 OutStreamer.EmitLabel(RelocSymbol); 1046 1047 const MCExpr *OffsExpr = 1048 MCBinaryExpr::CreateSub( 1049 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), 1050 OutContext), 1051 MCSymbolRefExpr::Create(PICBase, OutContext), 1052 OutContext); 1053 OutStreamer.EmitValue(OffsExpr, 4); 1054 OutStreamer.EmitLabel(CurrentFnSym); 1055 return; 1056 } else 1057 return AsmPrinter::EmitFunctionEntryLabel(); 1058 } 1059 1060 // ELFv2 ABI - Normal entry label. 1061 if (Subtarget->isELFv2ABI()) 1062 return AsmPrinter::EmitFunctionEntryLabel(); 1063 1064 // Emit an official procedure descriptor. 1065 MCSectionSubPair Current = OutStreamer.getCurrentSection(); 1066 const MCSectionELF *Section = OutStreamer.getContext().getELFSection( 1067 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1068 OutStreamer.SwitchSection(Section); 1069 OutStreamer.EmitLabel(CurrentFnSym); 1070 OutStreamer.EmitValueToAlignment(8); 1071 MCSymbol *Symbol1 = 1072 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 1073 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 1074 // entry point. 1075 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 1076 8 /*size*/); 1077 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 1078 // Generates a R_PPC64_TOC relocation for TOC base insertion. 1079 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 1080 MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 1081 8/*size*/); 1082 // Emit a null environment pointer. 1083 OutStreamer.EmitIntValue(0, 8 /* size */); 1084 OutStreamer.SwitchSection(Current.first, Current.second); 1085 1086 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 1087 ".L." + Twine(CurrentFnSym->getName())); 1088 OutStreamer.EmitLabel(RealFnSym); 1089 CurrentFnSymForSize = RealFnSym; 1090 } 1091 1092 1093 bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 1094 const DataLayout *TD = TM.getDataLayout(); 1095 1096 bool isPPC64 = TD->getPointerSizeInBits() == 64; 1097 1098 PPCTargetStreamer &TS = 1099 static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); 1100 1101 if (!TOC.empty()) { 1102 const MCSectionELF *Section; 1103 1104 if (isPPC64) 1105 Section = OutStreamer.getContext().getELFSection( 1106 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1107 else 1108 Section = OutStreamer.getContext().getELFSection( 1109 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1110 OutStreamer.SwitchSection(Section); 1111 1112 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 1113 E = TOC.end(); I != E; ++I) { 1114 OutStreamer.EmitLabel(I->second); 1115 MCSymbol *S = I->first; 1116 if (isPPC64) 1117 TS.emitTCEntry(*S); 1118 else 1119 OutStreamer.EmitSymbolValue(S, 4); 1120 } 1121 } 1122 1123 MachineModuleInfoELF &MMIELF = 1124 MMI->getObjFileInfo<MachineModuleInfoELF>(); 1125 1126 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 1127 if (!Stubs.empty()) { 1128 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1129 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1130 // L_foo$stub: 1131 OutStreamer.EmitLabel(Stubs[i].first); 1132 // .long _foo 1133 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 1134 OutContext), 1135 isPPC64 ? 8 : 4/*size*/); 1136 } 1137 1138 Stubs.clear(); 1139 OutStreamer.AddBlankLine(); 1140 } 1141 1142 return AsmPrinter::doFinalization(M); 1143 } 1144 1145 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 1146 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { 1147 // In the ELFv2 ABI, in functions that use the TOC register, we need to 1148 // provide two entry points. The ABI guarantees that when calling the 1149 // local entry point, r2 is set up by the caller to contain the TOC base 1150 // for this function, and when calling the global entry point, r12 is set 1151 // up by the caller to hold the address of the global entry point. We 1152 // thus emit a prefix sequence along the following lines: 1153 // 1154 // func: 1155 // # global entry point 1156 // addis r2,r12,(.TOC.-func)@ha 1157 // addi r2,r2,(.TOC.-func)@l 1158 // .localentry func, .-func 1159 // # local entry point, followed by function body 1160 // 1161 // This ensures we have r2 set up correctly while executing the function 1162 // body, no matter which entry point is called. 1163 if (Subtarget->isELFv2ABI() 1164 // Only do all that if the function uses r2 in the first place. 1165 && !MF->getRegInfo().use_empty(PPC::X2)) { 1166 1167 MCSymbol *GlobalEntryLabel = OutContext.CreateTempSymbol(); 1168 OutStreamer.EmitLabel(GlobalEntryLabel); 1169 const MCSymbolRefExpr *GlobalEntryLabelExp = 1170 MCSymbolRefExpr::Create(GlobalEntryLabel, OutContext); 1171 1172 MCSymbol *TOCSymbol = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 1173 const MCExpr *TOCDeltaExpr = 1174 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(TOCSymbol, OutContext), 1175 GlobalEntryLabelExp, OutContext); 1176 1177 const MCExpr *TOCDeltaHi = 1178 PPCMCExpr::CreateHa(TOCDeltaExpr, false, OutContext); 1179 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 1180 .addReg(PPC::X2) 1181 .addReg(PPC::X12) 1182 .addExpr(TOCDeltaHi)); 1183 1184 const MCExpr *TOCDeltaLo = 1185 PPCMCExpr::CreateLo(TOCDeltaExpr, false, OutContext); 1186 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI) 1187 .addReg(PPC::X2) 1188 .addReg(PPC::X2) 1189 .addExpr(TOCDeltaLo)); 1190 1191 MCSymbol *LocalEntryLabel = OutContext.CreateTempSymbol(); 1192 OutStreamer.EmitLabel(LocalEntryLabel); 1193 const MCSymbolRefExpr *LocalEntryLabelExp = 1194 MCSymbolRefExpr::Create(LocalEntryLabel, OutContext); 1195 const MCExpr *LocalOffsetExp = 1196 MCBinaryExpr::CreateSub(LocalEntryLabelExp, 1197 GlobalEntryLabelExp, OutContext); 1198 1199 PPCTargetStreamer *TS = 1200 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 1201 1202 if (TS) 1203 TS->emitLocalEntry(CurrentFnSym, LocalOffsetExp); 1204 } 1205 } 1206 1207 /// EmitFunctionBodyEnd - Print the traceback table before the .size 1208 /// directive. 1209 /// 1210 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 1211 // Only the 64-bit target requires a traceback table. For now, 1212 // we only emit the word of zeroes that GDB requires to find 1213 // the end of the function, and zeroes for the eight-byte 1214 // mandatory fields. 1215 // FIXME: We should fill in the eight-byte mandatory fields as described in 1216 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 1217 // currently make use of these fields). 1218 if (Subtarget->isPPC64()) { 1219 OutStreamer.EmitIntValue(0, 4/*size*/); 1220 OutStreamer.EmitIntValue(0, 8/*size*/); 1221 } 1222 } 1223 1224 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 1225 static const char *const CPUDirectives[] = { 1226 "", 1227 "ppc", 1228 "ppc440", 1229 "ppc601", 1230 "ppc602", 1231 "ppc603", 1232 "ppc7400", 1233 "ppc750", 1234 "ppc970", 1235 "ppcA2", 1236 "ppce500mc", 1237 "ppce5500", 1238 "power3", 1239 "power4", 1240 "power5", 1241 "power5x", 1242 "power6", 1243 "power6x", 1244 "power7", 1245 "ppc64", 1246 "ppc64le" 1247 }; 1248 1249 // Get the numerically largest directive. 1250 // FIXME: How should we merge darwin directives? 1251 unsigned Directive = PPC::DIR_NONE; 1252 for (const Function &F : M) { 1253 const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F); 1254 unsigned FDir = STI.getDarwinDirective(); 1255 Directive = Directive > FDir ? FDir : STI.getDarwinDirective(); 1256 if (STI.hasMFOCRF() && Directive < PPC::DIR_970) 1257 Directive = PPC::DIR_970; 1258 if (STI.hasAltivec() && Directive < PPC::DIR_7400) 1259 Directive = PPC::DIR_7400; 1260 if (STI.isPPC64() && Directive < PPC::DIR_64) 1261 Directive = PPC::DIR_64; 1262 } 1263 1264 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 1265 1266 assert(Directive < array_lengthof(CPUDirectives) && 1267 "CPUDirectives[] might not be up-to-date!"); 1268 PPCTargetStreamer &TStreamer = 1269 *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 1270 TStreamer.emitMachine(CPUDirectives[Directive]); 1271 1272 // Prime text sections so they are adjacent. This reduces the likelihood a 1273 // large data or debug section causes a branch to exceed 16M limit. 1274 const TargetLoweringObjectFileMachO &TLOFMacho = 1275 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1276 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 1277 if (TM.getRelocationModel() == Reloc::PIC_) { 1278 OutStreamer.SwitchSection( 1279 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 1280 MachO::S_SYMBOL_STUBS | 1281 MachO::S_ATTR_PURE_INSTRUCTIONS, 1282 32, SectionKind::getText())); 1283 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 1284 OutStreamer.SwitchSection( 1285 OutContext.getMachOSection("__TEXT","__symbol_stub1", 1286 MachO::S_SYMBOL_STUBS | 1287 MachO::S_ATTR_PURE_INSTRUCTIONS, 1288 16, SectionKind::getText())); 1289 } 1290 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 1291 } 1292 1293 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 1294 // Remove $stub suffix, add $lazy_ptr. 1295 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 1296 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 1297 } 1298 1299 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 1300 // Add $tmp suffix to $stub, yielding $stub$tmp. 1301 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 1302 } 1303 1304 void PPCDarwinAsmPrinter:: 1305 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 1306 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1307 1308 // Construct a local MCSubtargetInfo and shadow EmitToStreamer here. 1309 // This is because the MachineFunction won't exist (but have not yet been 1310 // freed) and since we're at the global level we can use the default 1311 // constructed subtarget. 1312 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( 1313 TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString())); 1314 auto EmitToStreamer = [&STI] (MCStreamer &S, const MCInst &Inst) { 1315 S.EmitInstruction(Inst, *STI); 1316 }; 1317 1318 const TargetLoweringObjectFileMachO &TLOFMacho = 1319 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1320 1321 // .lazy_symbol_pointer 1322 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 1323 1324 // Output stubs for dynamically-linked functions 1325 if (TM.getRelocationModel() == Reloc::PIC_) { 1326 const MCSection *StubSection = 1327 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 1328 MachO::S_SYMBOL_STUBS | 1329 MachO::S_ATTR_PURE_INSTRUCTIONS, 1330 32, SectionKind::getText()); 1331 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1332 OutStreamer.SwitchSection(StubSection); 1333 EmitAlignment(4); 1334 1335 MCSymbol *Stub = Stubs[i].first; 1336 MCSymbol *RawSym = Stubs[i].second.getPointer(); 1337 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 1338 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 1339 1340 OutStreamer.EmitLabel(Stub); 1341 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1342 1343 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 1344 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 1345 const MCExpr *Sub = 1346 MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); 1347 1348 // mflr r0 1349 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 1350 // bcl 20, 31, AnonSymbol 1351 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 1352 OutStreamer.EmitLabel(AnonSymbol); 1353 // mflr r11 1354 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 1355 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 1356 const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, true, OutContext); 1357 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 1358 .addReg(PPC::R11) 1359 .addReg(PPC::R11) 1360 .addExpr(SubHa16)); 1361 // mtlr r0 1362 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 1363 1364 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 1365 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 1366 const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, true, OutContext); 1367 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 1368 .addReg(PPC::R12) 1369 .addExpr(SubLo16).addExpr(SubLo16) 1370 .addReg(PPC::R11)); 1371 // mtctr r12 1372 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 1373 // bctr 1374 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 1375 1376 OutStreamer.SwitchSection(LSPSection); 1377 OutStreamer.EmitLabel(LazyPtr); 1378 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1379 1380 MCSymbol *DyldStubBindingHelper = 1381 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1382 if (isPPC64) { 1383 // .quad dyld_stub_binding_helper 1384 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1385 } else { 1386 // .long dyld_stub_binding_helper 1387 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1388 } 1389 } 1390 OutStreamer.AddBlankLine(); 1391 return; 1392 } 1393 1394 const MCSection *StubSection = 1395 OutContext.getMachOSection("__TEXT","__symbol_stub1", 1396 MachO::S_SYMBOL_STUBS | 1397 MachO::S_ATTR_PURE_INSTRUCTIONS, 1398 16, SectionKind::getText()); 1399 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1400 MCSymbol *Stub = Stubs[i].first; 1401 MCSymbol *RawSym = Stubs[i].second.getPointer(); 1402 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 1403 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 1404 1405 OutStreamer.SwitchSection(StubSection); 1406 EmitAlignment(4); 1407 OutStreamer.EmitLabel(Stub); 1408 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1409 1410 // lis r11, ha16(LazyPtr) 1411 const MCExpr *LazyPtrHa16 = 1412 PPCMCExpr::CreateHa(LazyPtrExpr, true, OutContext); 1413 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS) 1414 .addReg(PPC::R11) 1415 .addExpr(LazyPtrHa16)); 1416 1417 // ldu r12, lo16(LazyPtr)(r11) 1418 // lwzu r12, lo16(LazyPtr)(r11) 1419 const MCExpr *LazyPtrLo16 = 1420 PPCMCExpr::CreateLo(LazyPtrExpr, true, OutContext); 1421 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 1422 .addReg(PPC::R12) 1423 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 1424 .addReg(PPC::R11)); 1425 1426 // mtctr r12 1427 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 1428 // bctr 1429 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 1430 1431 OutStreamer.SwitchSection(LSPSection); 1432 OutStreamer.EmitLabel(LazyPtr); 1433 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1434 1435 MCSymbol *DyldStubBindingHelper = 1436 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1437 if (isPPC64) { 1438 // .quad dyld_stub_binding_helper 1439 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1440 } else { 1441 // .long dyld_stub_binding_helper 1442 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1443 } 1444 } 1445 1446 OutStreamer.AddBlankLine(); 1447 } 1448 1449 1450 bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 1451 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1452 1453 // Darwin/PPC always uses mach-o. 1454 const TargetLoweringObjectFileMachO &TLOFMacho = 1455 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1456 MachineModuleInfoMachO &MMIMacho = 1457 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1458 1459 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 1460 if (!Stubs.empty()) 1461 EmitFunctionStubs(Stubs); 1462 1463 if (MAI->doesSupportExceptionHandling() && MMI) { 1464 // Add the (possibly multiple) personalities to the set of global values. 1465 // Only referenced functions get into the Personalities list. 1466 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 1467 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 1468 E = Personalities.end(); I != E; ++I) { 1469 if (*I) { 1470 MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 1471 MachineModuleInfoImpl::StubValueTy &StubSym = 1472 MMIMacho.getGVStubEntry(NLPSym); 1473 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true); 1474 } 1475 } 1476 } 1477 1478 // Output stubs for dynamically-linked functions. 1479 Stubs = MMIMacho.GetGVStubList(); 1480 1481 // Output macho stubs for external and common global variables. 1482 if (!Stubs.empty()) { 1483 // Switch with ".non_lazy_symbol_pointer" directive. 1484 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 1485 EmitAlignment(isPPC64 ? 3 : 2); 1486 1487 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1488 // L_foo$stub: 1489 OutStreamer.EmitLabel(Stubs[i].first); 1490 // .indirect_symbol _foo 1491 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1492 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1493 1494 if (MCSym.getInt()) 1495 // External to current translation unit. 1496 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 1497 else 1498 // Internal to current translation unit. 1499 // 1500 // When we place the LSDA into the TEXT section, the type info pointers 1501 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1502 // However, sometimes the types are local to the file. So we need to 1503 // fill in the value for the NLP in those cases. 1504 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1505 OutContext), 1506 isPPC64 ? 8 : 4/*size*/); 1507 } 1508 1509 Stubs.clear(); 1510 OutStreamer.AddBlankLine(); 1511 } 1512 1513 Stubs = MMIMacho.GetHiddenGVStubList(); 1514 if (!Stubs.empty()) { 1515 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1516 EmitAlignment(isPPC64 ? 3 : 2); 1517 1518 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1519 // L_foo$stub: 1520 OutStreamer.EmitLabel(Stubs[i].first); 1521 // .long _foo 1522 OutStreamer.EmitValue(MCSymbolRefExpr:: 1523 Create(Stubs[i].second.getPointer(), 1524 OutContext), 1525 isPPC64 ? 8 : 4/*size*/); 1526 } 1527 1528 Stubs.clear(); 1529 OutStreamer.AddBlankLine(); 1530 } 1531 1532 // Funny Darwin hack: This flag tells the linker that no global symbols 1533 // contain code that falls through to other global symbols (e.g. the obvious 1534 // implementation of multiple entry points). If this doesn't occur, the 1535 // linker can safely perform dead code stripping. Since LLVM never generates 1536 // code that does this, it is always safe to set. 1537 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1538 1539 return AsmPrinter::doFinalization(M); 1540 } 1541 1542 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1543 /// for a MachineFunction to the given output stream, in a format that the 1544 /// Darwin assembler can deal with. 1545 /// 1546 static AsmPrinter * 1547 createPPCAsmPrinterPass(TargetMachine &tm, 1548 std::unique_ptr<MCStreamer> &&Streamer) { 1549 if (Triple(tm.getTargetTriple()).isMacOSX()) 1550 return new PPCDarwinAsmPrinter(tm, std::move(Streamer)); 1551 return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); 1552 } 1553 1554 // Force static initialization. 1555 extern "C" void LLVMInitializePowerPCAsmPrinter() { 1556 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1557 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1558 TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass); 1559 } 1560