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