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