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