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