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