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