PPCAsmPrinter.cpp revision 249423
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" 59using namespace llvm; 60 61namespace { 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. 139static 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 150void 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/// 248bool 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 286bool 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. 317MCSymbol *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/// 336void 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) 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 LD. If the global address is external, has 462 // common linkage, or is a jump table address, then reference the 463 // associated TOC entry. Otherwise reference the symbol directly. 464 TmpInst.setOpcode(PPC::LD); 465 const MachineOperand &MO = MI->getOperand(1); 466 assert((MO.isGlobal() || MO.isJTI() || MO.isCPI()) && 467 "Invalid operand for LDtocL!"); 468 MCSymbol *MOSymbol = 0; 469 470 if (MO.isJTI()) 471 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 472 else if (MO.isCPI()) 473 MOSymbol = GetCPISymbol(MO.getIndex()); 474 else if (MO.isGlobal()) { 475 const GlobalValue *GValue = MO.getGlobal(); 476 const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue); 477 const GlobalValue *RealGValue = GAlias ? 478 GAlias->resolveAliasedGlobal(false) : GValue; 479 MOSymbol = Mang->getSymbol(RealGValue); 480 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue); 481 482 if (!GVar || !GVar->hasInitializer() || RealGValue->hasCommonLinkage() || 483 RealGValue->hasAvailableExternallyLinkage()) 484 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 485 } 486 487 const MCExpr *Exp = 488 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 489 OutContext); 490 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 491 OutStreamer.EmitInstruction(TmpInst); 492 return; 493 } 494 case PPC::ADDItocL: { 495 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 496 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 497 498 // Change the opcode to ADDI8. If the global address is external, then 499 // generate a TOC entry and reference that. Otherwise reference the 500 // symbol directly. 501 TmpInst.setOpcode(PPC::ADDI8); 502 const MachineOperand &MO = MI->getOperand(2); 503 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 504 MCSymbol *MOSymbol = 0; 505 bool IsExternal = false; 506 bool IsFunction = false; 507 508 if (MO.isGlobal()) { 509 const GlobalValue *GValue = MO.getGlobal(); 510 const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue); 511 const GlobalValue *RealGValue = GAlias ? 512 GAlias->resolveAliasedGlobal(false) : GValue; 513 MOSymbol = Mang->getSymbol(RealGValue); 514 const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue); 515 IsExternal = GVar && !GVar->hasInitializer(); 516 IsFunction = !GVar; 517 } else if (MO.isCPI()) 518 MOSymbol = GetCPISymbol(MO.getIndex()); 519 520 if (IsFunction || IsExternal) 521 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 522 523 const MCExpr *Exp = 524 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC16_LO, 525 OutContext); 526 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 527 OutStreamer.EmitInstruction(TmpInst); 528 return; 529 } 530 case PPC::ADDISgotTprelHA: { 531 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 532 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 533 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 534 const MachineOperand &MO = MI->getOperand(2); 535 const GlobalValue *GValue = MO.getGlobal(); 536 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 537 const MCExpr *SymGotTprel = 538 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA, 539 OutContext); 540 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 541 .addReg(MI->getOperand(0).getReg()) 542 .addReg(PPC::X2) 543 .addExpr(SymGotTprel)); 544 return; 545 } 546 case PPC::LDgotTprelL: { 547 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 548 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 549 550 // Change the opcode to LD. 551 TmpInst.setOpcode(PPC::LD); 552 const MachineOperand &MO = MI->getOperand(1); 553 const GlobalValue *GValue = MO.getGlobal(); 554 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 555 const MCExpr *Exp = 556 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO, 557 OutContext); 558 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 559 OutStreamer.EmitInstruction(TmpInst); 560 return; 561 } 562 case PPC::ADDIStlsgdHA: { 563 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 564 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 565 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 566 const MachineOperand &MO = MI->getOperand(2); 567 const GlobalValue *GValue = MO.getGlobal(); 568 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 569 const MCExpr *SymGotTlsGD = 570 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA, 571 OutContext); 572 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 573 .addReg(MI->getOperand(0).getReg()) 574 .addReg(PPC::X2) 575 .addExpr(SymGotTlsGD)); 576 return; 577 } 578 case PPC::ADDItlsgdL: { 579 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 580 // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l 581 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 582 const MachineOperand &MO = MI->getOperand(2); 583 const GlobalValue *GValue = MO.getGlobal(); 584 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 585 const MCExpr *SymGotTlsGD = 586 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO, 587 OutContext); 588 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) 589 .addReg(MI->getOperand(0).getReg()) 590 .addReg(MI->getOperand(1).getReg()) 591 .addExpr(SymGotTlsGD)); 592 return; 593 } 594 case PPC::GETtlsADDR: { 595 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 596 // Into: BL8_NOP_TLSGD __tls_get_addr(sym@tlsgd) 597 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 598 599 StringRef Name = "__tls_get_addr"; 600 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 601 const MCSymbolRefExpr *TlsRef = 602 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 603 const MachineOperand &MO = MI->getOperand(2); 604 const GlobalValue *GValue = MO.getGlobal(); 605 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 606 const MCExpr *SymVar = 607 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD, 608 OutContext); 609 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSGD) 610 .addExpr(TlsRef) 611 .addExpr(SymVar)); 612 return; 613 } 614 case PPC::ADDIStlsldHA: { 615 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 616 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 617 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 618 const MachineOperand &MO = MI->getOperand(2); 619 const GlobalValue *GValue = MO.getGlobal(); 620 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 621 const MCExpr *SymGotTlsLD = 622 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA, 623 OutContext); 624 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 625 .addReg(MI->getOperand(0).getReg()) 626 .addReg(PPC::X2) 627 .addExpr(SymGotTlsLD)); 628 return; 629 } 630 case PPC::ADDItlsldL: { 631 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 632 // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l 633 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 634 const MachineOperand &MO = MI->getOperand(2); 635 const GlobalValue *GValue = MO.getGlobal(); 636 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 637 const MCExpr *SymGotTlsLD = 638 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO, 639 OutContext); 640 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) 641 .addReg(MI->getOperand(0).getReg()) 642 .addReg(MI->getOperand(1).getReg()) 643 .addExpr(SymGotTlsLD)); 644 return; 645 } 646 case PPC::GETtlsldADDR: { 647 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 648 // Into: BL8_NOP_TLSLD __tls_get_addr(sym@tlsld) 649 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 650 651 StringRef Name = "__tls_get_addr"; 652 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 653 const MCSymbolRefExpr *TlsRef = 654 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 655 const MachineOperand &MO = MI->getOperand(2); 656 const GlobalValue *GValue = MO.getGlobal(); 657 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 658 const MCExpr *SymVar = 659 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD, 660 OutContext); 661 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_TLSLD) 662 .addExpr(TlsRef) 663 .addExpr(SymVar)); 664 return; 665 } 666 case PPC::ADDISdtprelHA: { 667 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 668 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 669 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 670 const MachineOperand &MO = MI->getOperand(2); 671 const GlobalValue *GValue = MO.getGlobal(); 672 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 673 const MCExpr *SymDtprel = 674 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_HA, 675 OutContext); 676 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8) 677 .addReg(MI->getOperand(0).getReg()) 678 .addReg(PPC::X3) 679 .addExpr(SymDtprel)); 680 return; 681 } 682 case PPC::ADDIdtprelL: { 683 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 684 // Into: %Xd = ADDI8 %Xs, sym@dtprel@l 685 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); 686 const MachineOperand &MO = MI->getOperand(2); 687 const GlobalValue *GValue = MO.getGlobal(); 688 MCSymbol *MOSymbol = Mang->getSymbol(GValue); 689 const MCExpr *SymDtprel = 690 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL16_LO, 691 OutContext); 692 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8) 693 .addReg(MI->getOperand(0).getReg()) 694 .addReg(MI->getOperand(1).getReg()) 695 .addExpr(SymDtprel)); 696 return; 697 } 698 case PPC::MFCRpseud: 699 case PPC::MFCR8pseud: 700 // Transform: %R3 = MFCRpseud %CR7 701 // Into: %R3 = MFCR ;; cr7 702 OutStreamer.AddComment(PPCInstPrinter:: 703 getRegisterName(MI->getOperand(1).getReg())); 704 OutStreamer.EmitInstruction(MCInstBuilder(Subtarget.isPPC64() ? PPC::MFCR8 : PPC::MFCR) 705 .addReg(MI->getOperand(0).getReg())); 706 return; 707 case PPC::SYNC: 708 // In Book E sync is called msync, handle this special case here... 709 if (Subtarget.isBookE()) { 710 OutStreamer.EmitRawText(StringRef("\tmsync")); 711 return; 712 } 713 } 714 715 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin()); 716 OutStreamer.EmitInstruction(TmpInst); 717} 718 719void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 720 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 721 return AsmPrinter::EmitFunctionEntryLabel(); 722 723 // Emit an official procedure descriptor. 724 const MCSection *Current = OutStreamer.getCurrentSection(); 725 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", 726 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 727 SectionKind::getReadOnly()); 728 OutStreamer.SwitchSection(Section); 729 OutStreamer.EmitLabel(CurrentFnSym); 730 OutStreamer.EmitValueToAlignment(8); 731 MCSymbol *Symbol1 = 732 OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); 733 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 734 // entry point. 735 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 736 8 /*size*/); 737 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 738 // Generates a R_PPC64_TOC relocation for TOC base insertion. 739 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 740 MCSymbolRefExpr::VK_PPC_TOC, OutContext), 741 8/*size*/); 742 // Emit a null environment pointer. 743 OutStreamer.EmitIntValue(0, 8 /* size */); 744 OutStreamer.SwitchSection(Current); 745 746 MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( 747 ".L." + Twine(CurrentFnSym->getName())); 748 OutStreamer.EmitLabel(RealFnSym); 749 CurrentFnSymForSize = RealFnSym; 750} 751 752 753bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 754 const DataLayout *TD = TM.getDataLayout(); 755 756 bool isPPC64 = TD->getPointerSizeInBits() == 64; 757 758 if (isPPC64 && !TOC.empty()) { 759 const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc", 760 ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, 761 SectionKind::getReadOnly()); 762 OutStreamer.SwitchSection(Section); 763 764 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 765 E = TOC.end(); I != E; ++I) { 766 OutStreamer.EmitLabel(I->second); 767 MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName()); 768 OutStreamer.EmitTCEntry(*S); 769 } 770 } 771 772 MachineModuleInfoELF &MMIELF = 773 MMI->getObjFileInfo<MachineModuleInfoELF>(); 774 775 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 776 if (!Stubs.empty()) { 777 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 778 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 779 // L_foo$stub: 780 OutStreamer.EmitLabel(Stubs[i].first); 781 // .long _foo 782 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), 783 OutContext), 784 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 785 } 786 787 Stubs.clear(); 788 OutStreamer.AddBlankLine(); 789 } 790 791 return AsmPrinter::doFinalization(M); 792} 793 794/// EmitFunctionBodyEnd - Print the traceback table before the .size 795/// directive. 796/// 797void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 798 // Only the 64-bit target requires a traceback table. For now, 799 // we only emit the word of zeroes that GDB requires to find 800 // the end of the function, and zeroes for the eight-byte 801 // mandatory fields. 802 // FIXME: We should fill in the eight-byte mandatory fields as described in 803 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 804 // currently make use of these fields). 805 if (Subtarget.isPPC64()) { 806 OutStreamer.EmitIntValue(0, 4/*size*/); 807 OutStreamer.EmitIntValue(0, 8/*size*/); 808 } 809} 810 811void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 812 static const char *const CPUDirectives[] = { 813 "", 814 "ppc", 815 "ppc440", 816 "ppc601", 817 "ppc602", 818 "ppc603", 819 "ppc7400", 820 "ppc750", 821 "ppc970", 822 "ppcA2", 823 "ppce500mc", 824 "ppce5500", 825 "power3", 826 "power4", 827 "power5", 828 "power5x", 829 "power6", 830 "power6x", 831 "power7", 832 "ppc64" 833 }; 834 835 unsigned Directive = Subtarget.getDarwinDirective(); 836 if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) 837 Directive = PPC::DIR_970; 838 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 839 Directive = PPC::DIR_7400; 840 if (Subtarget.isPPC64() && Directive < PPC::DIR_64) 841 Directive = PPC::DIR_64; 842 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 843 844 // FIXME: This is a total hack, finish mc'izing the PPC backend. 845 if (OutStreamer.hasRawTextSupport()) { 846 assert(Directive < sizeof(CPUDirectives) / sizeof(*CPUDirectives) && 847 "CPUDirectives[] might not be up-to-date!"); 848 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 849 } 850 851 // Prime text sections so they are adjacent. This reduces the likelihood a 852 // large data or debug section causes a branch to exceed 16M limit. 853 const TargetLoweringObjectFileMachO &TLOFMacho = 854 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 855 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 856 if (TM.getRelocationModel() == Reloc::PIC_) { 857 OutStreamer.SwitchSection( 858 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 859 MCSectionMachO::S_SYMBOL_STUBS | 860 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 861 32, SectionKind::getText())); 862 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 863 OutStreamer.SwitchSection( 864 OutContext.getMachOSection("__TEXT","__symbol_stub1", 865 MCSectionMachO::S_SYMBOL_STUBS | 866 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 867 16, SectionKind::getText())); 868 } 869 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 870} 871 872static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 873 // Remove $stub suffix, add $lazy_ptr. 874 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 875 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 876} 877 878static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 879 // Add $tmp suffix to $stub, yielding $stub$tmp. 880 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 881} 882 883void PPCDarwinAsmPrinter:: 884EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 885 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 886 887 const TargetLoweringObjectFileMachO &TLOFMacho = 888 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 889 890 // .lazy_symbol_pointer 891 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 892 893 // Output stubs for dynamically-linked functions 894 if (TM.getRelocationModel() == Reloc::PIC_) { 895 const MCSection *StubSection = 896 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 897 MCSectionMachO::S_SYMBOL_STUBS | 898 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 899 32, SectionKind::getText()); 900 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 901 OutStreamer.SwitchSection(StubSection); 902 EmitAlignment(4); 903 904 MCSymbol *Stub = Stubs[i].first; 905 MCSymbol *RawSym = Stubs[i].second.getPointer(); 906 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 907 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 908 909 OutStreamer.EmitLabel(Stub); 910 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 911 912 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 913 914 // mflr r0 915 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 916 // bcl 20, 31, AnonSymbol 917 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 918 OutStreamer.EmitLabel(AnonSymbol); 919 // mflr r11 920 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 921 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 922 const MCExpr *Sub = 923 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(LazyPtr, OutContext), 924 Anon, OutContext); 925 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS) 926 .addReg(PPC::R11) 927 .addReg(PPC::R11) 928 .addExpr(Sub)); 929 // mtlr r0 930 OutStreamer.EmitInstruction(MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 931 932 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 933 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 934 OutStreamer.EmitInstruction(MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 935 .addReg(PPC::R12) 936 .addExpr(Sub).addExpr(Sub) 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 971 OutStreamer.SwitchSection(StubSection); 972 EmitAlignment(4); 973 OutStreamer.EmitLabel(Stub); 974 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 975 // lis r11, ha16(LazyPtr) 976 const MCExpr *LazyPtrHa16 = 977 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_HA16, 978 OutContext); 979 OutStreamer.EmitInstruction(MCInstBuilder(PPC::LIS) 980 .addReg(PPC::R11) 981 .addExpr(LazyPtrHa16)); 982 983 const MCExpr *LazyPtrLo16 = 984 MCSymbolRefExpr::Create(LazyPtr, MCSymbolRefExpr::VK_PPC_DARWIN_LO16, 985 OutContext); 986 // ldu r12, lo16(LazyPtr)(r11) 987 // lwzu r12, lo16(LazyPtr)(r11) 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 1017bool 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(Mang->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/// 1113static 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. 1123extern "C" void LLVMInitializePowerPCAsmPrinter() { 1124 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1125 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1126} 1127