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