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