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