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