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