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