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