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 *GV = MO.getGlobal(); 384 MOSymbol = getSymbol(GV); 385 IsExternal = GV->isDeclaration(); 386 IsCommon = GV->hasCommonLinkage(); 387 IsFunction = GV->getType()->getElementType()->isFunctionTy(); 388 IsAvailExt = GV->hasAvailableExternallyLinkage(); 389 } else if (MO.isCPI()) 390 MOSymbol = GetCPISymbol(MO.getIndex()); 391 else if (MO.isJTI()) 392 MOSymbol = GetJTISymbol(MO.getIndex()); 393 394 if (IsExternal || IsFunction || IsCommon || IsAvailExt || MO.isJTI() || 395 TM.getCodeModel() == CodeModel::Large) 396 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 397 398 const MCExpr *Exp = 399 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, 400 OutContext); 401 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 402 EmitToStreamer(OutStreamer, TmpInst); 403 return; 404 } 405 case PPC::LDtocL: { 406 // Transform %Xd = LDtocL <ga:@sym>, %Xs 407 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 408 409 // Change the opcode to LD. If the global address is external, has 410 // common linkage, or is a jump table address, then reference the 411 // associated TOC entry. Otherwise reference the symbol directly. 412 TmpInst.setOpcode(PPC::LD); 413 const MachineOperand &MO = MI->getOperand(1); 414 assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) && 415 "Invalid operand for LDtocL!"); 416 MCSymbol *MOSymbol = nullptr; 417 418 if (MO.isJTI()) 419 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 420 else if (MO.isCPI()) { 421 MOSymbol = GetCPISymbol(MO.getIndex()); 422 if (TM.getCodeModel() == CodeModel::Large) 423 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 424 } 425 else if (MO.isGlobal()) { 426 const GlobalValue *GValue = MO.getGlobal(); 427 MOSymbol = getSymbol(GValue); 428 if (GValue->getType()->getElementType()->isFunctionTy() || 429 GValue->isDeclaration() || GValue->hasCommonLinkage() || 430 GValue->hasAvailableExternallyLinkage() || 431 TM.getCodeModel() == CodeModel::Large) 432 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 433 } 434 435 const MCExpr *Exp = 436 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 437 OutContext); 438 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 439 EmitToStreamer(OutStreamer, TmpInst); 440 return; 441 } 442 case PPC::ADDItocL: { 443 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 444 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 445 446 // Change the opcode to ADDI8. If the global address is external, then 447 // generate a TOC entry and reference that. Otherwise reference the 448 // symbol directly. 449 TmpInst.setOpcode(PPC::ADDI8); 450 const MachineOperand &MO = MI->getOperand(2); 451 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 452 MCSymbol *MOSymbol = nullptr; 453 bool IsExternal = false; 454 bool IsFunction = false; 455 456 if (MO.isGlobal()) { 457 const GlobalValue *GV = MO.getGlobal(); 458 MOSymbol = getSymbol(GV); 459 IsExternal = GV->isDeclaration(); 460 IsFunction = GV->getType()->getElementType()->isFunctionTy(); 461 } else if (MO.isCPI()) 462 MOSymbol = GetCPISymbol(MO.getIndex()); 463 464 if (IsFunction || IsExternal || TM.getCodeModel() == CodeModel::Large) 465 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 466 467 const MCExpr *Exp = 468 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 469 OutContext); 470 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 471 EmitToStreamer(OutStreamer, TmpInst); 472 return; 473 } 474 case PPC::ADDISgotTprelHA: { 475 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 476 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 477 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 478 const MachineOperand &MO = MI->getOperand(2); 479 const GlobalValue *GValue = MO.getGlobal(); 480 MCSymbol *MOSymbol = getSymbol(GValue); 481 const MCExpr *SymGotTprel = 482 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 483 OutContext); 484 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 485 .addReg(MI->getOperand(0).getReg()) 486 .addReg(PPC::X2) 487 .addExpr(SymGotTprel)); 488 return; 489 } 490 case PPC::LDgotTprelL: 491 case PPC::LDgotTprelL32: { 492 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 493 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 494 495 // Change the opcode to LD. 496 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); 497 const MachineOperand &MO = MI->getOperand(1); 498 const GlobalValue *GValue = MO.getGlobal(); 499 MCSymbol *MOSymbol = getSymbol(GValue); 500 const MCExpr *Exp = 501 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, 502 OutContext); 503 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 504 EmitToStreamer(OutStreamer, TmpInst); 505 return; 506 } 507 508 case PPC::PPC32GOT: { 509 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 510 const MCExpr *SymGotTlsL = 511 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, 512 OutContext); 513 const MCExpr *SymGotTlsHA = 514 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, 515 OutContext); 516 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI) 517 .addReg(MI->getOperand(0).getReg()) 518 .addExpr(SymGotTlsL)); 519 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 520 .addReg(MI->getOperand(0).getReg()) 521 .addReg(MI->getOperand(0).getReg()) 522 .addExpr(SymGotTlsHA)); 523 return; 524 } 525 case PPC::ADDIStlsgdHA: { 526 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 527 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 528 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 529 const MachineOperand &MO = MI->getOperand(2); 530 const GlobalValue *GValue = MO.getGlobal(); 531 MCSymbol *MOSymbol = getSymbol(GValue); 532 const MCExpr *SymGotTlsGD = 533 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 534 OutContext); 535 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 536 .addReg(MI->getOperand(0).getReg()) 537 .addReg(PPC::X2) 538 .addExpr(SymGotTlsGD)); 539 return; 540 } 541 case PPC::ADDItlsgdL: { 542 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 543 // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l 544 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 545 const MachineOperand &MO = MI->getOperand(2); 546 const GlobalValue *GValue = MO.getGlobal(); 547 MCSymbol *MOSymbol = getSymbol(GValue); 548 const MCExpr *SymGotTlsGD = 549 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO, 550 OutContext); 551 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI8) 552 .addReg(MI->getOperand(0).getReg()) 553 .addReg(MI->getOperand(1).getReg()) 554 .addExpr(SymGotTlsGD)); 555 return; 556 } 557 case PPC::GETtlsADDR: { 558 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 559 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd) 560 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 561 562 StringRef Name = "__tls_get_addr"; 563 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 564 const MCSymbolRefExpr *TlsRef = 565 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 566 const MachineOperand &MO = MI->getOperand(2); 567 const GlobalValue *GValue = MO.getGlobal(); 568 MCSymbol *MOSymbol = getSymbol(GValue); 569 const MCExpr *SymVar = 570 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, 571 OutContext); 572 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL8_NOP_TLS) 573 .addExpr(TlsRef) 574 .addExpr(SymVar)); 575 return; 576 } 577 case PPC::ADDIStlsldHA: { 578 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 579 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 580 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 581 const MachineOperand &MO = MI->getOperand(2); 582 const GlobalValue *GValue = MO.getGlobal(); 583 MCSymbol *MOSymbol = getSymbol(GValue); 584 const MCExpr *SymGotTlsLD = 585 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 586 OutContext); 587 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 588 .addReg(MI->getOperand(0).getReg()) 589 .addReg(PPC::X2) 590 .addExpr(SymGotTlsLD)); 591 return; 592 } 593 case PPC::ADDItlsldL: { 594 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 595 // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l 596 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 597 const MachineOperand &MO = MI->getOperand(2); 598 const GlobalValue *GValue = MO.getGlobal(); 599 MCSymbol *MOSymbol = getSymbol(GValue); 600 const MCExpr *SymGotTlsLD = 601 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO, 602 OutContext); 603 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI8) 604 .addReg(MI->getOperand(0).getReg()) 605 .addReg(MI->getOperand(1).getReg()) 606 .addExpr(SymGotTlsLD)); 607 return; 608 } 609 case PPC::GETtlsldADDR: { 610 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 611 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld) 612 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 613 614 StringRef Name = "__tls_get_addr"; 615 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 616 const MCSymbolRefExpr *TlsRef = 617 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 618 const MachineOperand &MO = MI->getOperand(2); 619 const GlobalValue *GValue = MO.getGlobal(); 620 MCSymbol *MOSymbol = getSymbol(GValue); 621 const MCExpr *SymVar = 622 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, 623 OutContext); 624 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL8_NOP_TLS) 625 .addExpr(TlsRef) 626 .addExpr(SymVar)); 627 return; 628 } 629 case PPC::ADDISdtprelHA: { 630 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 631 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 632 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 633 const MachineOperand &MO = MI->getOperand(2); 634 const GlobalValue *GValue = MO.getGlobal(); 635 MCSymbol *MOSymbol = getSymbol(GValue); 636 const MCExpr *SymDtprel = 637 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 638 OutContext); 639 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 640 .addReg(MI->getOperand(0).getReg()) 641 .addReg(PPC::X3) 642 .addExpr(SymDtprel)); 643 return; 644 } 645 case PPC::ADDIdtprelL: { 646 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 647 // Into: %Xd = ADDI8 %Xs, sym@dtprel@l 648 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 649 const MachineOperand &MO = MI->getOperand(2); 650 const GlobalValue *GValue = MO.getGlobal(); 651 MCSymbol *MOSymbol = getSymbol(GValue); 652 const MCExpr *SymDtprel = 653 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 654 OutContext); 655 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI8) 656 .addReg(MI->getOperand(0).getReg()) 657 .addReg(MI->getOperand(1).getReg()) 658 .addExpr(SymDtprel)); 659 return; 660 } 661 case PPC::MFOCRF: 662 case PPC::MFOCRF8: 663 if (!Subtarget.hasMFOCRF()) { 664 // Transform: %R3 = MFOCRF %CR7 665 // Into: %R3 = MFCR ;; cr7 666 unsigned NewOpcode = 667 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 668 OutStreamer.AddComment(PPCInstPrinter:: 669 getRegisterName(MI->getOperand(1).getReg())); 670 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 671 .addReg(MI->getOperand(0).getReg())); 672 return; 673 } 674 break; 675 case PPC::MTOCRF: 676 case PPC::MTOCRF8: 677 if (!Subtarget.hasMFOCRF()) { 678 // Transform: %CR7 = MTOCRF %R3 679 // Into: MTCRF mask, %R3 ;; cr7 680 unsigned NewOpcode = 681 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 682 unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 683 ->getEncodingValue(MI->getOperand(0).getReg()); 684 OutStreamer.AddComment(PPCInstPrinter:: 685 getRegisterName(MI->getOperand(0).getReg())); 686 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 687 .addImm(Mask) 688 .addReg(MI->getOperand(1).getReg())); 689 return; 690 } 691 break; 692 case PPC::LD: 693 case PPC::STD: 694 case PPC::LWA_32: 695 case PPC::LWA: { 696 // Verify alignment is legal, so we don't create relocations 697 // that can't be supported. 698 // FIXME: This test is currently disabled for Darwin. The test 699 // suite shows a handful of test cases that fail this check for 700 // Darwin. Those need to be investigated before this sanity test 701 // can be enabled for those subtargets. 702 if (!Subtarget.isDarwin()) { 703 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 704 const MachineOperand &MO = MI->getOperand(OpNum); 705 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 706 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 707 } 708 // Now process the instruction normally. 709 break; 710 } 711 } 712 713 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 714 EmitToStreamer(OutStreamer, TmpInst); 715 } 716 717 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 718 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 719 return AsmPrinter::EmitFunctionEntryLabel(); 720 721 // Emit an official procedure descriptor. 722 MCSectionSubPair Current = OutStreamer.getCurrentSection(); 723 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 724 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 725 SectionKind::getReadOnly()); 726 OutStreamer.SwitchSection(Section); 727 OutStreamer.EmitLabel(CurrentFnSym); 728 OutStreamer.EmitValueToAlignment(8); 729 MCSymbol *Symbol1 = 730 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 731 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 732 // entry point. 733 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 734 8 /*size*/); 735 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 736 // Generates a R_PPC64_TOC relocation for TOC base insertion. 737 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 738 MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 739 8/*size*/); 740 // Emit a null environment pointer. 741 OutStreamer.EmitIntValue(0, 8 /* size */); 742 OutStreamer.SwitchSection(Current.first, Current.second); 743 744 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 745 ".L." + Twine(CurrentFnSym->getName())); 746 OutStreamer.EmitLabel(RealFnSym); 747 CurrentFnSymForSize = RealFnSym; 748 } 749 750 751 bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 752 const DataLayout *TD = TM.getDataLayout(); 753 754 bool isPPC64 = TD->getPointerSizeInBits() == 64; 755 756 PPCTargetStreamer &TS = 757 static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); 758 759 if (isPPC64 && !TOC.empty()) { 760 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 761 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 762 SectionKind::getReadOnly()); 763 OutStreamer.SwitchSection(Section); 764 765 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 766 E = TOC.end(); I != E; ++I) { 767 OutStreamer.EmitLabel(I->second); 768 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 769 TS.emitTCEntry(*S); 770 } 771 } 772 773 MachineModuleInfoELF &MMIELF = 774 MMI->getObjFileInfo<MachineModuleInfoELF>(); 775 776 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 777 if (!Stubs.empty()) { 778 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 779 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 780 // L_foo$stub: 781 OutStreamer.EmitLabel(Stubs[i].first); 782 // .long _foo 783 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 784 OutContext), 785 isPPC64 ? 8 : 4/*size*/); 786 } 787 788 Stubs.clear(); 789 OutStreamer.AddBlankLine(); 790 } 791 792 return AsmPrinter::doFinalization(M); 793 } 794 795 /// EmitFunctionBodyEnd - Print the traceback table before the .size 796 /// directive. 797 /// 798 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 799 // Only the 64-bit target requires a traceback table. For now, 800 // we only emit the word of zeroes that GDB requires to find 801 // the end of the function, and zeroes for the eight-byte 802 // mandatory fields. 803 // FIXME: We should fill in the eight-byte mandatory fields as described in 804 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 805 // currently make use of these fields). 806 if (Subtarget.isPPC64()) { 807 OutStreamer.EmitIntValue(0, 4/*size*/); 808 OutStreamer.EmitIntValue(0, 8/*size*/); 809 } 810 } 811 812 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 813 static const char *const CPUDirectives[] = { 814 "", 815 "ppc", 816 "ppc440", 817 "ppc601", 818 "ppc602", 819 "ppc603", 820 "ppc7400", 821 "ppc750", 822 "ppc970", 823 "ppcA2", 824 "ppce500mc", 825 "ppce5500", 826 "power3", 827 "power4", 828 "power5", 829 "power5x", 830 "power6", 831 "power6x", 832 "power7", 833 "ppc64", 834 "ppc64le" 835 }; 836 837 unsigned Directive = Subtarget.getDarwinDirective(); 838 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 839 Directive = PPC::DIR_970; 840 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 841 Directive = PPC::DIR_7400; 842 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 843 Directive = PPC::DIR_64; 844 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 845 846 assert(Directive < array_lengthof(CPUDirectives) && 847 "CPUDirectives[] might not be up-to-date!"); 848 PPCTargetStreamer &TStreamer = 849 *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 850 TStreamer.emitMachine(CPUDirectives[Directive]); 851 852 // Prime text sections so they are adjacent. This reduces the likelihood a 853 // large data or debug section causes a branch to exceed 16M limit. 854 const TargetLoweringObjectFileMachO &TLOFMacho = 855 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 856 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 857 if (TM.getRelocationModel() == Reloc::PIC_) { 858 OutStreamer.SwitchSection( 859 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 860 MachO::S_SYMBOL_STUBS | 861 MachO::S_ATTR_PURE_INSTRUCTIONS, 862 32, SectionKind::getText())); 863 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 864 OutStreamer.SwitchSection( 865 OutContext.getMachOSection("__TEXT","__symbol_stub1", 866 MachO::S_SYMBOL_STUBS | 867 MachO::S_ATTR_PURE_INSTRUCTIONS, 868 16, SectionKind::getText())); 869 } 870 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 871 } 872 873 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 874 // Remove $stub suffix, add $lazy_ptr. 875 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 876 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 877 } 878 879 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 880 // Add $tmp suffix to $stub, yielding $stub$tmp. 881 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 882 } 883 884 void PPCDarwinAsmPrinter:: 885 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 886 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 887 bool isDarwin = Subtarget.isDarwin(); 888 889 const TargetLoweringObjectFileMachO &TLOFMacho = 890 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 891 892 // .lazy_symbol_pointer 893 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 894 895 // Output stubs for dynamically-linked functions 896 if (TM.getRelocationModel() == Reloc::PIC_) { 897 const MCSection *StubSection = 898 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 899 MachO::S_SYMBOL_STUBS | 900 MachO::S_ATTR_PURE_INSTRUCTIONS, 901 32, SectionKind::getText()); 902 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 903 OutStreamer.SwitchSection(StubSection); 904 EmitAlignment(4); 905 906 MCSymbol *Stub = Stubs[i].first; 907 MCSymbol *RawSym = Stubs[i].second.getPointer(); 908 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 909 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 910 911 OutStreamer.EmitLabel(Stub); 912 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 913 914 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 915 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 916 const MCExpr *Sub = 917 MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); 918 919 // mflr r0 920 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 921 // bcl 20, 31, AnonSymbol 922 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 923 OutStreamer.EmitLabel(AnonSymbol); 924 // mflr r11 925 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 926 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 927 const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext); 928 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 929 .addReg(PPC::R11) 930 .addReg(PPC::R11) 931 .addExpr(SubHa16)); 932 // mtlr r0 933 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 934 935 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 936 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 937 const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext); 938 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 939 .addReg(PPC::R12) 940 .addExpr(SubLo16).addExpr(SubLo16) 941 .addReg(PPC::R11)); 942 // mtctr r12 943 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 944 // bctr 945 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 946 947 OutStreamer.SwitchSection(LSPSection); 948 OutStreamer.EmitLabel(LazyPtr); 949 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 950 951 MCSymbol *DyldStubBindingHelper = 952 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 953 if (isPPC64) { 954 // .quad dyld_stub_binding_helper 955 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 956 } else { 957 // .long dyld_stub_binding_helper 958 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 959 } 960 } 961 OutStreamer.AddBlankLine(); 962 return; 963 } 964 965 const MCSection *StubSection = 966 OutContext.getMachOSection("__TEXT","__symbol_stub1", 967 MachO::S_SYMBOL_STUBS | 968 MachO::S_ATTR_PURE_INSTRUCTIONS, 969 16, SectionKind::getText()); 970 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 971 MCSymbol *Stub = Stubs[i].first; 972 MCSymbol *RawSym = Stubs[i].second.getPointer(); 973 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 974 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 975 976 OutStreamer.SwitchSection(StubSection); 977 EmitAlignment(4); 978 OutStreamer.EmitLabel(Stub); 979 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 980 981 // lis r11, ha16(LazyPtr) 982 const MCExpr *LazyPtrHa16 = 983 PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext); 984 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS) 985 .addReg(PPC::R11) 986 .addExpr(LazyPtrHa16)); 987 988 // ldu r12, lo16(LazyPtr)(r11) 989 // lwzu r12, lo16(LazyPtr)(r11) 990 const MCExpr *LazyPtrLo16 = 991 PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext); 992 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 993 .addReg(PPC::R12) 994 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 995 .addReg(PPC::R11)); 996 997 // mtctr r12 998 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 999 // bctr 1000 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 1001 1002 OutStreamer.SwitchSection(LSPSection); 1003 OutStreamer.EmitLabel(LazyPtr); 1004 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1005 1006 MCSymbol *DyldStubBindingHelper = 1007 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1008 if (isPPC64) { 1009 // .quad dyld_stub_binding_helper 1010 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1011 } else { 1012 // .long dyld_stub_binding_helper 1013 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1014 } 1015 } 1016 1017 OutStreamer.AddBlankLine(); 1018 } 1019 1020 1021 bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 1022 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1023 1024 // Darwin/PPC always uses mach-o. 1025 const TargetLoweringObjectFileMachO &TLOFMacho = 1026 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1027 MachineModuleInfoMachO &MMIMacho = 1028 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1029 1030 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 1031 if (!Stubs.empty()) 1032 EmitFunctionStubs(Stubs); 1033 1034 if (MAI->doesSupportExceptionHandling() && MMI) { 1035 // Add the (possibly multiple) personalities to the set of global values. 1036 // Only referenced functions get into the Personalities list. 1037 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 1038 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 1039 E = Personalities.end(); I != E; ++I) { 1040 if (*I) { 1041 MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 1042 MachineModuleInfoImpl::StubValueTy &StubSym = 1043 MMIMacho.getGVStubEntry(NLPSym); 1044 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true); 1045 } 1046 } 1047 } 1048 1049 // Output stubs for dynamically-linked functions. 1050 Stubs = MMIMacho.GetGVStubList(); 1051 1052 // Output macho stubs for external and common global variables. 1053 if (!Stubs.empty()) { 1054 // Switch with ".non_lazy_symbol_pointer" directive. 1055 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 1056 EmitAlignment(isPPC64 ? 3 : 2); 1057 1058 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1059 // L_foo$stub: 1060 OutStreamer.EmitLabel(Stubs[i].first); 1061 // .indirect_symbol _foo 1062 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1063 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1064 1065 if (MCSym.getInt()) 1066 // External to current translation unit. 1067 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 1068 else 1069 // Internal to current translation unit. 1070 // 1071 // When we place the LSDA into the TEXT section, the type info pointers 1072 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1073 // However, sometimes the types are local to the file. So we need to 1074 // fill in the value for the NLP in those cases. 1075 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1076 OutContext), 1077 isPPC64 ? 8 : 4/*size*/); 1078 } 1079 1080 Stubs.clear(); 1081 OutStreamer.AddBlankLine(); 1082 } 1083 1084 Stubs = MMIMacho.GetHiddenGVStubList(); 1085 if (!Stubs.empty()) { 1086 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1087 EmitAlignment(isPPC64 ? 3 : 2); 1088 1089 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1090 // L_foo$stub: 1091 OutStreamer.EmitLabel(Stubs[i].first); 1092 // .long _foo 1093 OutStreamer.EmitValue(MCSymbolRefExpr:: 1094 Create(Stubs[i].second.getPointer(), 1095 OutContext), 1096 isPPC64 ? 8 : 4/*size*/); 1097 } 1098 1099 Stubs.clear(); 1100 OutStreamer.AddBlankLine(); 1101 } 1102 1103 // Funny Darwin hack: This flag tells the linker that no global symbols 1104 // contain code that falls through to other global symbols (e.g. the obvious 1105 // implementation of multiple entry points). If this doesn't occur, the 1106 // linker can safely perform dead code stripping. Since LLVM never generates 1107 // code that does this, it is always safe to set. 1108 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1109 1110 return AsmPrinter::doFinalization(M); 1111 } 1112 1113 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1114 /// for a MachineFunction to the given output stream, in a format that the 1115 /// Darwin assembler can deal with. 1116 /// 1117 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 1118 MCStreamer &Streamer) { 1119 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 1120 1121 if (Subtarget->isDarwin()) 1122 return new PPCDarwinAsmPrinter(tm, Streamer); 1123 return new PPCLinuxAsmPrinter(tm, Streamer); 1124 } 1125 1126 // Force static initialization. 1127 extern "C" void LLVMInitializePowerPCAsmPrinter() { 1128 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1129 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1130 TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass); 1131 } 1132