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