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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(MCInstBuilder(PPC::LI) 525 .addReg(MI->getOperand(0).getReg()) 526 .addExpr(SymGotTlsL)); 527 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(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 OutStreamer.EmitInstruction(MCInstBuilder(NewOpcode) 695 .addImm(Mask) 696 .addReg(MI->getOperand(1).getReg())); 697 return; 698 } 699 break; 700 case PPC::SYNC: 701 // In Book E sync is called msync, handle this special case here... 702 if (Subtarget.isBookE()) { 703 OutStreamer.EmitRawText(StringRef("\tmsync")); 704 return; 705 } 706 break; 707 case PPC::LD: 708 case PPC::STD: 709 case PPC::LWA_32: 710 case PPC::LWA: { 711 // Verify alignment is legal, so we don't create relocations 712 // that can't be supported. 713 // FIXME: This test is currently disabled for Darwin. The test 714 // suite shows a handful of test cases that fail this check for 715 // Darwin. Those need to be investigated before this sanity test 716 // can be enabled for those subtargets. 717 if (!Subtarget.isDarwin()) { 718 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 719 const MachineOperand &MO = MI->getOperand(OpNum); 720 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 721 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 722 } 723 // Now process the instruction normally. 724 break; 725 } 726 } 727 728 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 729 OutStreamer.EmitInstruction(TmpInst); 730 } 731 732 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 733 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 734 return AsmPrinter::EmitFunctionEntryLabel(); 735 736 // Emit an official procedure descriptor. 737 MCSectionSubPair Current = OutStreamer.getCurrentSection(); 738 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 739 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 740 SectionKind::getReadOnly()); 741 OutStreamer.SwitchSection(Section); 742 OutStreamer.EmitLabel(CurrentFnSym); 743 OutStreamer.EmitValueToAlignment(8); 744 MCSymbol *Symbol1 = 745 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 746 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 747 // entry point. 748 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 749 8 /*size*/); 750 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 751 // Generates a R_PPC64_TOC relocation for TOC base insertion. 752 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 753 MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 754 8/*size*/); 755 // Emit a null environment pointer. 756 OutStreamer.EmitIntValue(0, 8 /* size */); 757 OutStreamer.SwitchSection(Current.first, Current.second); 758 759 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 760 ".L." + Twine(CurrentFnSym->getName())); 761 OutStreamer.EmitLabel(RealFnSym); 762 CurrentFnSymForSize = RealFnSym; 763 } 764 765 766 bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 767 const DataLayout *TD = TM.getDataLayout(); 768 769 bool isPPC64 = TD->getPointerSizeInBits() == 64; 770 771 PPCTargetStreamer &TS = 772 static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); 773 774 if (isPPC64 && !TOC.empty()) { 775 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 776 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 777 SectionKind::getReadOnly()); 778 OutStreamer.SwitchSection(Section); 779 780 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 781 E = TOC.end(); I != E; ++I) { 782 OutStreamer.EmitLabel(I->second); 783 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 784 TS.emitTCEntry(*S); 785 } 786 } 787 788 MachineModuleInfoELF &MMIELF = 789 MMI->getObjFileInfo<MachineModuleInfoELF>(); 790 791 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 792 if (!Stubs.empty()) { 793 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 794 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 795 // L_foo$stub: 796 OutStreamer.EmitLabel(Stubs[i].first); 797 // .long _foo 798 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 799 OutContext), 800 isPPC64 ? 8 : 4/*size*/); 801 } 802 803 Stubs.clear(); 804 OutStreamer.AddBlankLine(); 805 } 806 807 return AsmPrinter::doFinalization(M); 808 } 809 810 /// EmitFunctionBodyEnd - Print the traceback table before the .size 811 /// directive. 812 /// 813 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 814 // Only the 64-bit target requires a traceback table. For now, 815 // we only emit the word of zeroes that GDB requires to find 816 // the end of the function, and zeroes for the eight-byte 817 // mandatory fields. 818 // FIXME: We should fill in the eight-byte mandatory fields as described in 819 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 820 // currently make use of these fields). 821 if (Subtarget.isPPC64()) { 822 OutStreamer.EmitIntValue(0, 4/*size*/); 823 OutStreamer.EmitIntValue(0, 8/*size*/); 824 } 825 } 826 827 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 828 static const char *const CPUDirectives[] = { 829 "", 830 "ppc", 831 "ppc440", 832 "ppc601", 833 "ppc602", 834 "ppc603", 835 "ppc7400", 836 "ppc750", 837 "ppc970", 838 "ppcA2", 839 "ppce500mc", 840 "ppce5500", 841 "power3", 842 "power4", 843 "power5", 844 "power5x", 845 "power6", 846 "power6x", 847 "power7", 848 "ppc64", 849 "ppc64le" 850 }; 851 852 unsigned Directive = Subtarget.getDarwinDirective(); 853 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 854 Directive = PPC::DIR_970; 855 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 856 Directive = PPC::DIR_7400; 857 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 858 Directive = PPC::DIR_64; 859 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 860 861 // FIXME: This is a total hack, finish mc'izing the PPC backend. 862 if (OutStreamer.hasRawTextSupport()) { 863 assert(Directive < array_lengthof(CPUDirectives) && 864 "CPUDirectives[] might not be up-to-date!"); 865 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 866 } 867 868 // Prime text sections so they are adjacent. This reduces the likelihood a 869 // large data or debug section causes a branch to exceed 16M limit. 870 const TargetLoweringObjectFileMachO &TLOFMacho = 871 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 872 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 873 if (TM.getRelocationModel() == Reloc::PIC_) { 874 OutStreamer.SwitchSection( 875 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 876 MCSectionMachO::S_SYMBOL_STUBS | 877 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 878 32, SectionKind::getText())); 879 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 880 OutStreamer.SwitchSection( 881 OutContext.getMachOSection("__TEXT","__symbol_stub1", 882 MCSectionMachO::S_SYMBOL_STUBS | 883 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 884 16, SectionKind::getText())); 885 } 886 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 887 } 888 889 static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 890 // Remove $stub suffix, add $lazy_ptr. 891 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 892 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 893 } 894 895 static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 896 // Add $tmp suffix to $stub, yielding $stub$tmp. 897 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 898 } 899 900 void PPCDarwinAsmPrinter:: 901 EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 902 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 903 bool isDarwin = Subtarget.isDarwin(); 904 905 const TargetLoweringObjectFileMachO &TLOFMacho = 906 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 907 908 // .lazy_symbol_pointer 909 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 910 911 // Output stubs for dynamically-linked functions 912 if (TM.getRelocationModel() == Reloc::PIC_) { 913 const MCSection *StubSection = 914 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 915 MCSectionMachO::S_SYMBOL_STUBS | 916 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 917 32, SectionKind::getText()); 918 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 919 OutStreamer.SwitchSection(StubSection); 920 EmitAlignment(4); 921 922 MCSymbol *Stub = Stubs[i].first; 923 MCSymbol *RawSym = Stubs[i].second.getPointer(); 924 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 925 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 926 927 OutStreamer.EmitLabel(Stub); 928 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 929 930 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 931 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 932 const MCExpr *Sub = 933 MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); 934 935 // mflr r0 936 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 937 // bcl 20, 31, AnonSymbol 938 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 939 OutStreamer.EmitLabel(AnonSymbol); 940 // mflr r11 941 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 942 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 943 const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext); 944 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) 945 .addReg(PPC::R11) 946 .addReg(PPC::R11) 947 .addExpr(SubHa16)); 948 // mtlr r0 949 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 950 951 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 952 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 953 const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext); 954 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 955 .addReg(PPC::R12) 956 .addExpr(SubLo16).addExpr(SubLo16) 957 .addReg(PPC::R11)); 958 // mtctr r12 959 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 960 // bctr 961 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 962 963 OutStreamer.SwitchSection(LSPSection); 964 OutStreamer.EmitLabel(LazyPtr); 965 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 966 967 MCSymbol *DyldStubBindingHelper = 968 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 969 if (isPPC64) { 970 // .quad dyld_stub_binding_helper 971 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 972 } else { 973 // .long dyld_stub_binding_helper 974 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 975 } 976 } 977 OutStreamer.AddBlankLine(); 978 return; 979 } 980 981 const MCSection *StubSection = 982 OutContext.getMachOSection("__TEXT","__symbol_stub1", 983 MCSectionMachO::S_SYMBOL_STUBS | 984 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 985 16, SectionKind::getText()); 986 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 987 MCSymbol *Stub = Stubs[i].first; 988 MCSymbol *RawSym = Stubs[i].second.getPointer(); 989 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 990 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 991 992 OutStreamer.SwitchSection(StubSection); 993 EmitAlignment(4); 994 OutStreamer.EmitLabel(Stub); 995 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 996 997 // lis r11, ha16(LazyPtr) 998 const MCExpr *LazyPtrHa16 = 999 PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext); 1000 OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS) 1001 .addReg(PPC::R11) 1002 .addExpr(LazyPtrHa16)); 1003 1004 // ldu r12, lo16(LazyPtr)(r11) 1005 // lwzu r12, lo16(LazyPtr)(r11) 1006 const MCExpr *LazyPtrLo16 = 1007 PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext); 1008 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 1009 .addReg(PPC::R12) 1010 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 1011 .addReg(PPC::R11)); 1012 1013 // mtctr r12 1014 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 1015 // bctr 1016 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCTR)); 1017 1018 OutStreamer.SwitchSection(LSPSection); 1019 OutStreamer.EmitLabel(LazyPtr); 1020 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1021 1022 MCSymbol *DyldStubBindingHelper = 1023 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1024 if (isPPC64) { 1025 // .quad dyld_stub_binding_helper 1026 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1027 } else { 1028 // .long dyld_stub_binding_helper 1029 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1030 } 1031 } 1032 1033 OutStreamer.AddBlankLine(); 1034 } 1035 1036 1037 bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 1038 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1039 1040 // Darwin/PPC always uses mach-o. 1041 const TargetLoweringObjectFileMachO &TLOFMacho = 1042 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1043 MachineModuleInfoMachO &MMIMacho = 1044 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1045 1046 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 1047 if (!Stubs.empty()) 1048 EmitFunctionStubs(Stubs); 1049 1050 if (MAI->doesSupportExceptionHandling() && MMI) { 1051 // Add the (possibly multiple) personalities to the set of global values. 1052 // Only referenced functions get into the Personalities list. 1053 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 1054 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 1055 E = Personalities.end(); I != E; ++I) { 1056 if (*I) { 1057 MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 1058 MachineModuleInfoImpl::StubValueTy &StubSym = 1059 MMIMacho.getGVStubEntry(NLPSym); 1060 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true); 1061 } 1062 } 1063 } 1064 1065 // Output stubs for dynamically-linked functions. 1066 Stubs = MMIMacho.GetGVStubList(); 1067 1068 // Output macho stubs for external and common global variables. 1069 if (!Stubs.empty()) { 1070 // Switch with ".non_lazy_symbol_pointer" directive. 1071 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 1072 EmitAlignment(isPPC64 ? 3 : 2); 1073 1074 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1075 // L_foo$stub: 1076 OutStreamer.EmitLabel(Stubs[i].first); 1077 // .indirect_symbol _foo 1078 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1079 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1080 1081 if (MCSym.getInt()) 1082 // External to current translation unit. 1083 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 1084 else 1085 // Internal to current translation unit. 1086 // 1087 // When we place the LSDA into the TEXT section, the type info pointers 1088 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1089 // However, sometimes the types are local to the file. So we need to 1090 // fill in the value for the NLP in those cases. 1091 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1092 OutContext), 1093 isPPC64 ? 8 : 4/*size*/); 1094 } 1095 1096 Stubs.clear(); 1097 OutStreamer.AddBlankLine(); 1098 } 1099 1100 Stubs = MMIMacho.GetHiddenGVStubList(); 1101 if (!Stubs.empty()) { 1102 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1103 EmitAlignment(isPPC64 ? 3 : 2); 1104 1105 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1106 // L_foo$stub: 1107 OutStreamer.EmitLabel(Stubs[i].first); 1108 // .long _foo 1109 OutStreamer.EmitValue(MCSymbolRefExpr:: 1110 Create(Stubs[i].second.getPointer(), 1111 OutContext), 1112 isPPC64 ? 8 : 4/*size*/); 1113 } 1114 1115 Stubs.clear(); 1116 OutStreamer.AddBlankLine(); 1117 } 1118 1119 // Funny Darwin hack: This flag tells the linker that no global symbols 1120 // contain code that falls through to other global symbols (e.g. the obvious 1121 // implementation of multiple entry points). If this doesn't occur, the 1122 // linker can safely perform dead code stripping. Since LLVM never generates 1123 // code that does this, it is always safe to set. 1124 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1125 1126 return AsmPrinter::doFinalization(M); 1127 } 1128 1129 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1130 /// for a MachineFunction to the given output stream, in a format that the 1131 /// Darwin assembler can deal with. 1132 /// 1133 static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 1134 MCStreamer &Streamer) { 1135 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 1136 1137 if (Subtarget->isDarwin()) 1138 return new PPCDarwinAsmPrinter(tm, Streamer); 1139 return new PPCLinuxAsmPrinter(tm, Streamer); 1140 } 1141 1142 // Force static initialization. 1143 extern "C" void LLVMInitializePowerPCAsmPrinter() { 1144 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1145 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1146 } 1147