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