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#include "PPC.h" 20#include "InstPrinter/PPCInstPrinter.h" 21#include "MCTargetDesc/PPCMCExpr.h" 22#include "MCTargetDesc/PPCPredicates.h" 23#include "PPCMachineFunctionInfo.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/CodeGen/AsmPrinter.h" 31#include "llvm/CodeGen/MachineConstantPool.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/MachineRegisterInfo.h" 37#include "llvm/CodeGen/StackMaps.h" 38#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 39#include "llvm/IR/Constants.h" 40#include "llvm/IR/DebugInfo.h" 41#include "llvm/IR/DerivedTypes.h" 42#include "llvm/IR/Mangler.h" 43#include "llvm/IR/Module.h" 44#include "llvm/MC/MCAsmInfo.h" 45#include "llvm/MC/MCContext.h" 46#include "llvm/MC/MCExpr.h" 47#include "llvm/MC/MCInst.h" 48#include "llvm/MC/MCInstBuilder.h" 49#include "llvm/MC/MCSectionELF.h" 50#include "llvm/MC/MCSectionMachO.h" 51#include "llvm/MC/MCStreamer.h" 52#include "llvm/MC/MCSymbol.h" 53#include "llvm/Support/CommandLine.h" 54#include "llvm/Support/Debug.h" 55#include "llvm/Support/ELF.h" 56#include "llvm/Support/ErrorHandling.h" 57#include "llvm/Support/MathExtras.h" 58#include "llvm/Support/TargetRegistry.h" 59#include "llvm/Support/raw_ostream.h" 60#include "llvm/Target/TargetInstrInfo.h" 61#include "llvm/Target/TargetOptions.h" 62#include "llvm/Target/TargetRegisterInfo.h" 63using namespace llvm; 64 65#define DEBUG_TYPE "asmprinter" 66 67namespace { 68 class PPCAsmPrinter : public AsmPrinter { 69 protected: 70 MapVector<MCSymbol*, MCSymbol*> TOC; 71 const PPCSubtarget *Subtarget; 72 StackMaps SM; 73 public: 74 explicit PPCAsmPrinter(TargetMachine &TM, 75 std::unique_ptr<MCStreamer> Streamer) 76 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {} 77 78 const char *getPassName() const override { 79 return "PowerPC Assembly Printer"; 80 } 81 82 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym); 83 84 void EmitInstruction(const MachineInstr *MI) override; 85 86 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 87 88 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 89 unsigned AsmVariant, const char *ExtraCode, 90 raw_ostream &O) override; 91 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 92 unsigned AsmVariant, const char *ExtraCode, 93 raw_ostream &O) override; 94 95 void EmitEndOfAsmFile(Module &M) override; 96 97 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM, 98 const MachineInstr &MI); 99 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, 100 const MachineInstr &MI); 101 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); 102 bool runOnMachineFunction(MachineFunction &MF) override { 103 Subtarget = &MF.getSubtarget<PPCSubtarget>(); 104 return AsmPrinter::runOnMachineFunction(MF); 105 } 106 }; 107 108 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 109 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 110 public: 111 explicit PPCLinuxAsmPrinter(TargetMachine &TM, 112 std::unique_ptr<MCStreamer> Streamer) 113 : PPCAsmPrinter(TM, std::move(Streamer)) {} 114 115 const char *getPassName() const override { 116 return "Linux PPC Assembly Printer"; 117 } 118 119 bool doFinalization(Module &M) override; 120 void EmitStartOfAsmFile(Module &M) override; 121 122 void EmitFunctionEntryLabel() override; 123 124 void EmitFunctionBodyStart() override; 125 void EmitFunctionBodyEnd() override; 126 }; 127 128 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 129 /// OS X 130 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 131 public: 132 explicit PPCDarwinAsmPrinter(TargetMachine &TM, 133 std::unique_ptr<MCStreamer> Streamer) 134 : PPCAsmPrinter(TM, std::move(Streamer)) {} 135 136 const char *getPassName() const override { 137 return "Darwin PPC Assembly Printer"; 138 } 139 140 bool doFinalization(Module &M) override; 141 void EmitStartOfAsmFile(Module &M) override; 142 143 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 144 }; 145} // end of anonymous namespace 146 147/// stripRegisterPrefix - This method strips the character prefix from a 148/// register name so that only the number is left. Used by for linux asm. 149static const char *stripRegisterPrefix(const char *RegName) { 150 switch (RegName[0]) { 151 case 'r': 152 case 'f': 153 case 'q': // for QPX 154 case 'v': 155 if (RegName[1] == 's') 156 return RegName + 2; 157 return RegName + 1; 158 case 'c': if (RegName[1] == 'r') return RegName + 2; 159 } 160 161 return RegName; 162} 163 164void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 165 raw_ostream &O) { 166 const DataLayout *DL = TM.getDataLayout(); 167 const MachineOperand &MO = MI->getOperand(OpNo); 168 169 switch (MO.getType()) { 170 case MachineOperand::MO_Register: { 171 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 172 // Linux assembler (Others?) does not take register mnemonics. 173 // FIXME - What about special registers used in mfspr/mtspr? 174 if (!Subtarget->isDarwin()) 175 RegName = stripRegisterPrefix(RegName); 176 O << RegName; 177 return; 178 } 179 case MachineOperand::MO_Immediate: 180 O << MO.getImm(); 181 return; 182 183 case MachineOperand::MO_MachineBasicBlock: 184 O << *MO.getMBB()->getSymbol(); 185 return; 186 case MachineOperand::MO_ConstantPoolIndex: 187 O << DL->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 188 << '_' << MO.getIndex(); 189 return; 190 case MachineOperand::MO_BlockAddress: 191 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 192 return; 193 case MachineOperand::MO_GlobalAddress: { 194 // Computing the address of a global symbol, not calling it. 195 const GlobalValue *GV = MO.getGlobal(); 196 MCSymbol *SymToPrint; 197 198 // External or weakly linked global variables need non-lazily-resolved stubs 199 if (TM.getRelocationModel() != Reloc::Static && 200 (GV->isDeclaration() || GV->isWeakForLinker())) { 201 if (!GV->hasHiddenVisibility()) { 202 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 203 MachineModuleInfoImpl::StubValueTy &StubSym = 204 MMI->getObjFileInfo<MachineModuleInfoMachO>() 205 .getGVStubEntry(SymToPrint); 206 if (!StubSym.getPointer()) 207 StubSym = MachineModuleInfoImpl:: 208 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 209 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 210 GV->hasAvailableExternallyLinkage()) { 211 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 212 213 MachineModuleInfoImpl::StubValueTy &StubSym = 214 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 215 getHiddenGVStubEntry(SymToPrint); 216 if (!StubSym.getPointer()) 217 StubSym = MachineModuleInfoImpl:: 218 StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); 219 } else { 220 SymToPrint = getSymbol(GV); 221 } 222 } else { 223 SymToPrint = getSymbol(GV); 224 } 225 226 O << *SymToPrint; 227 228 printOffset(MO.getOffset(), O); 229 return; 230 } 231 232 default: 233 O << "<unknown operand type: " << (unsigned)MO.getType() << ">"; 234 return; 235 } 236} 237 238/// PrintAsmOperand - Print out an operand for an inline asm expression. 239/// 240bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 241 unsigned AsmVariant, 242 const char *ExtraCode, raw_ostream &O) { 243 // Does this asm operand have a single letter operand modifier? 244 if (ExtraCode && ExtraCode[0]) { 245 if (ExtraCode[1] != 0) return true; // Unknown modifier. 246 247 switch (ExtraCode[0]) { 248 default: 249 // See if this is a generic print operand 250 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 251 case 'c': // Don't print "$" before a global var name or constant. 252 break; // PPC never has a prefix. 253 case 'L': // Write second word of DImode reference. 254 // Verify that this operand has two consecutive registers. 255 if (!MI->getOperand(OpNo).isReg() || 256 OpNo+1 == MI->getNumOperands() || 257 !MI->getOperand(OpNo+1).isReg()) 258 return true; 259 ++OpNo; // Return the high-part. 260 break; 261 case 'I': 262 // Write 'i' if an integer constant, otherwise nothing. Used to print 263 // addi vs add, etc. 264 if (MI->getOperand(OpNo).isImm()) 265 O << "i"; 266 return false; 267 } 268 } 269 270 printOperand(MI, OpNo, O); 271 return false; 272} 273 274// At the moment, all inline asm memory operands are a single register. 275// In any case, the output of this routine should always be just one 276// assembler operand. 277 278bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 279 unsigned AsmVariant, 280 const char *ExtraCode, 281 raw_ostream &O) { 282 if (ExtraCode && ExtraCode[0]) { 283 if (ExtraCode[1] != 0) return true; // Unknown modifier. 284 285 switch (ExtraCode[0]) { 286 default: return true; // Unknown modifier. 287 case 'y': // A memory reference for an X-form instruction 288 { 289 const char *RegName = "r0"; 290 if (!Subtarget->isDarwin()) 291 RegName = stripRegisterPrefix(RegName); 292 O << RegName << ", "; 293 printOperand(MI, OpNo, O); 294 return false; 295 } 296 case 'U': // Print 'u' for update form. 297 case 'X': // Print 'x' for indexed form. 298 { 299 // FIXME: Currently for PowerPC memory operands are always loaded 300 // into a register, so we never get an update or indexed form. 301 // This is bad even for offset forms, since even if we know we 302 // have a value in -16(r1), we will generate a load into r<n> 303 // and then load from 0(r<n>). Until that issue is fixed, 304 // tolerate 'U' and 'X' but don't output anything. 305 assert(MI->getOperand(OpNo).isReg()); 306 return false; 307 } 308 } 309 } 310 311 assert(MI->getOperand(OpNo).isReg()); 312 O << "0("; 313 printOperand(MI, OpNo, O); 314 O << ")"; 315 return false; 316} 317 318 319/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 320/// exists for it. If not, create one. Then return a symbol that references 321/// the TOC entry. 322MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { 323 MCSymbol *&TOCEntry = TOC[Sym]; 324 if (!TOCEntry) 325 TOCEntry = createTempSymbol("C"); 326 return TOCEntry; 327} 328 329void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) { 330 SM.serializeToStackMapSection(); 331} 332 333void PPCAsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM, 334 const MachineInstr &MI) { 335 unsigned NumNOPBytes = MI.getOperand(1).getImm(); 336 337 SM.recordStackMap(MI); 338 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 339 340 // Scan ahead to trim the shadow. 341 const MachineBasicBlock &MBB = *MI.getParent(); 342 MachineBasicBlock::const_iterator MII(MI); 343 ++MII; 344 while (NumNOPBytes > 0) { 345 if (MII == MBB.end() || MII->isCall() || 346 MII->getOpcode() == PPC::DBG_VALUE || 347 MII->getOpcode() == TargetOpcode::PATCHPOINT || 348 MII->getOpcode() == TargetOpcode::STACKMAP) 349 break; 350 ++MII; 351 NumNOPBytes -= 4; 352 } 353 354 // Emit nops. 355 for (unsigned i = 0; i < NumNOPBytes; i += 4) 356 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP)); 357} 358 359// Lower a patchpoint of the form: 360// [<def>], <id>, <numBytes>, <target>, <numArgs> 361void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, 362 const MachineInstr &MI) { 363 SM.recordPatchPoint(MI); 364 PatchPointOpers Opers(&MI); 365 366 int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm(); 367 unsigned EncodedBytes = 0; 368 if (CallTarget) { 369 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && 370 "High 16 bits of call target should be zero."); 371 unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg(); 372 EncodedBytes = 6*4; 373 // Materialize the jump address: 374 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI8) 375 .addReg(ScratchReg) 376 .addImm((CallTarget >> 32) & 0xFFFF)); 377 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::RLDIC) 378 .addReg(ScratchReg) 379 .addReg(ScratchReg) 380 .addImm(32).addImm(16)); 381 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORIS8) 382 .addReg(ScratchReg) 383 .addReg(ScratchReg) 384 .addImm((CallTarget >> 16) & 0xFFFF)); 385 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ORI8) 386 .addReg(ScratchReg) 387 .addReg(ScratchReg) 388 .addImm(CallTarget & 0xFFFF)); 389 390 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR8).addReg(ScratchReg)); 391 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTRL8)); 392 } 393 394 // Emit padding. 395 unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm(); 396 assert(NumBytes >= EncodedBytes && 397 "Patchpoint can't request size less than the length of a call."); 398 assert((NumBytes - EncodedBytes) % 4 == 0 && 399 "Invalid number of NOP bytes requested!"); 400 for (unsigned i = EncodedBytes; i < NumBytes; i += 4) 401 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP)); 402} 403 404/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a 405/// call to __tls_get_addr to the current output stream. 406void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, 407 MCSymbolRefExpr::VariantKind VK) { 408 StringRef Name = "__tls_get_addr"; 409 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name); 410 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 411 412 assert(MI->getOperand(0).isReg() && 413 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || 414 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && 415 "GETtls[ld]ADDR[32] must define GPR3"); 416 assert(MI->getOperand(1).isReg() && 417 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || 418 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && 419 "GETtls[ld]ADDR[32] must read GPR3"); 420 421 if (!Subtarget->isPPC64() && !Subtarget->isDarwin() && 422 TM.getRelocationModel() == Reloc::PIC_) 423 Kind = MCSymbolRefExpr::VK_PLT; 424 const MCSymbolRefExpr *TlsRef = 425 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); 426 const MachineOperand &MO = MI->getOperand(2); 427 const GlobalValue *GValue = MO.getGlobal(); 428 MCSymbol *MOSymbol = getSymbol(GValue); 429 const MCExpr *SymVar = MCSymbolRefExpr::Create(MOSymbol, VK, OutContext); 430 EmitToStreamer(OutStreamer, 431 MCInstBuilder(Subtarget->isPPC64() ? 432 PPC::BL8_NOP_TLS : PPC::BL_TLS) 433 .addExpr(TlsRef) 434 .addExpr(SymVar)); 435} 436 437/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 438/// the current output stream. 439/// 440void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 441 MCInst TmpInst; 442 bool isPPC64 = Subtarget->isPPC64(); 443 bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin(); 444 const Module *M = MF->getFunction()->getParent(); 445 PICLevel::Level PL = M->getPICLevel(); 446 447 // Lower multi-instruction pseudo operations. 448 switch (MI->getOpcode()) { 449 default: break; 450 case TargetOpcode::DBG_VALUE: 451 llvm_unreachable("Should be handled target independently"); 452 case TargetOpcode::STACKMAP: 453 return LowerSTACKMAP(OutStreamer, SM, *MI); 454 case TargetOpcode::PATCHPOINT: 455 return LowerPATCHPOINT(OutStreamer, SM, *MI); 456 457 case PPC::MoveGOTtoLR: { 458 // Transform %LR = MoveGOTtoLR 459 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 460 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding 461 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction: 462 // blrl 463 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local 464 MCSymbol *GOTSymbol = 465 OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 466 const MCExpr *OffsExpr = 467 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, 468 MCSymbolRefExpr::VK_PPC_LOCAL, 469 OutContext), 470 MCConstantExpr::Create(4, OutContext), 471 OutContext); 472 473 // Emit the 'bl'. 474 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); 475 return; 476 } 477 case PPC::MovePCtoLR: 478 case PPC::MovePCtoLR8: { 479 // Transform %LR = MovePCtoLR 480 // Into this, where the label is the PIC base: 481 // bl L1$pb 482 // L1$pb: 483 MCSymbol *PICBase = MF->getPICBaseSymbol(); 484 485 // Emit the 'bl'. 486 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 487 // FIXME: We would like an efficient form for this, so we don't have to do 488 // a lot of extra uniquing. 489 .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); 490 491 // Emit the label. 492 OutStreamer.EmitLabel(PICBase); 493 return; 494 } 495 case PPC::UpdateGBR: { 496 // Transform %Rd = UpdateGBR(%Rt, %Ri) 497 // Into: lwz %Rt, .L0$poff - .L0$pb(%Ri) 498 // add %Rd, %Rt, %Ri 499 // Get the offset from the GOT Base Register to the GOT 500 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 501 MCSymbol *PICOffset = 502 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(); 503 TmpInst.setOpcode(PPC::LWZ); 504 const MCExpr *Exp = 505 MCSymbolRefExpr::Create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); 506 const MCExpr *PB = 507 MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), 508 MCSymbolRefExpr::VK_None, 509 OutContext); 510 const MCOperand TR = TmpInst.getOperand(1); 511 const MCOperand PICR = TmpInst.getOperand(0); 512 513 // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri) 514 TmpInst.getOperand(1) = 515 MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext)); 516 TmpInst.getOperand(0) = TR; 517 TmpInst.getOperand(2) = PICR; 518 EmitToStreamer(OutStreamer, TmpInst); 519 520 TmpInst.setOpcode(PPC::ADD4); 521 TmpInst.getOperand(0) = PICR; 522 TmpInst.getOperand(1) = TR; 523 TmpInst.getOperand(2) = PICR; 524 EmitToStreamer(OutStreamer, TmpInst); 525 return; 526 } 527 case PPC::LWZtoc: { 528 // Transform %R3 = LWZtoc <ga:@min1>, %R2 529 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 530 531 // Change the opcode to LWZ, and the global address operand to be a 532 // reference to the GOT entry we will synthesize later. 533 TmpInst.setOpcode(PPC::LWZ); 534 const MachineOperand &MO = MI->getOperand(1); 535 536 // Map symbol -> label of TOC entry 537 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); 538 MCSymbol *MOSymbol = nullptr; 539 if (MO.isGlobal()) 540 MOSymbol = getSymbol(MO.getGlobal()); 541 else if (MO.isCPI()) 542 MOSymbol = GetCPISymbol(MO.getIndex()); 543 else if (MO.isJTI()) 544 MOSymbol = GetJTISymbol(MO.getIndex()); 545 else if (MO.isBlockAddress()) 546 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 547 548 if (PL == PICLevel::Small) { 549 const MCExpr *Exp = 550 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT, 551 OutContext); 552 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 553 } else { 554 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 555 556 const MCExpr *Exp = 557 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, 558 OutContext); 559 const MCExpr *PB = 560 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), 561 OutContext); 562 Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); 563 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 564 } 565 EmitToStreamer(OutStreamer, TmpInst); 566 return; 567 } 568 case PPC::LDtocJTI: 569 case PPC::LDtocCPT: 570 case PPC::LDtocBA: 571 case PPC::LDtoc: { 572 // Transform %X3 = LDtoc <ga:@min1>, %X2 573 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 574 575 // Change the opcode to LD, and the global address operand to be a 576 // reference to the TOC entry we will synthesize later. 577 TmpInst.setOpcode(PPC::LD); 578 const MachineOperand &MO = MI->getOperand(1); 579 580 // Map symbol -> label of TOC entry 581 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()); 582 MCSymbol *MOSymbol = nullptr; 583 if (MO.isGlobal()) 584 MOSymbol = getSymbol(MO.getGlobal()); 585 else if (MO.isCPI()) 586 MOSymbol = GetCPISymbol(MO.getIndex()); 587 else if (MO.isJTI()) 588 MOSymbol = GetJTISymbol(MO.getIndex()); 589 else if (MO.isBlockAddress()) 590 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 591 592 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); 593 594 const MCExpr *Exp = 595 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, 596 OutContext); 597 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 598 EmitToStreamer(OutStreamer, TmpInst); 599 return; 600 } 601 602 case PPC::ADDIStocHA: { 603 // Transform %Xd = ADDIStocHA %X2, <ga:@sym> 604 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 605 606 // Change the opcode to ADDIS8. If the global address is external, has 607 // common linkage, is a non-local function address, or is a jump table 608 // address, then generate a TOC entry and reference that. Otherwise 609 // reference the symbol directly. 610 TmpInst.setOpcode(PPC::ADDIS8); 611 const MachineOperand &MO = MI->getOperand(2); 612 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 613 MO.isBlockAddress()) && 614 "Invalid operand for ADDIStocHA!"); 615 MCSymbol *MOSymbol = nullptr; 616 bool IsExternal = false; 617 bool IsNonLocalFunction = false; 618 bool IsCommon = false; 619 bool IsAvailExt = false; 620 621 if (MO.isGlobal()) { 622 const GlobalValue *GV = MO.getGlobal(); 623 MOSymbol = getSymbol(GV); 624 IsExternal = GV->isDeclaration(); 625 IsCommon = GV->hasCommonLinkage(); 626 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 627 (GV->isDeclaration() || GV->isWeakForLinker()); 628 IsAvailExt = GV->hasAvailableExternallyLinkage(); 629 } else if (MO.isCPI()) 630 MOSymbol = GetCPISymbol(MO.getIndex()); 631 else if (MO.isJTI()) 632 MOSymbol = GetJTISymbol(MO.getIndex()); 633 else if (MO.isBlockAddress()) 634 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 635 636 if (IsExternal || IsNonLocalFunction || IsCommon || IsAvailExt || 637 MO.isJTI() || MO.isBlockAddress() || 638 TM.getCodeModel() == CodeModel::Large) 639 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 640 641 const MCExpr *Exp = 642 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, 643 OutContext); 644 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 645 EmitToStreamer(OutStreamer, TmpInst); 646 return; 647 } 648 case PPC::LDtocL: { 649 // Transform %Xd = LDtocL <ga:@sym>, %Xs 650 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 651 652 // Change the opcode to LD. If the global address is external, has 653 // common linkage, or is a jump table address, then reference the 654 // associated TOC entry. Otherwise reference the symbol directly. 655 TmpInst.setOpcode(PPC::LD); 656 const MachineOperand &MO = MI->getOperand(1); 657 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 658 MO.isBlockAddress()) && 659 "Invalid operand for LDtocL!"); 660 MCSymbol *MOSymbol = nullptr; 661 662 if (MO.isJTI()) 663 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex())); 664 else if (MO.isBlockAddress()) { 665 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress()); 666 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 667 } 668 else if (MO.isCPI()) { 669 MOSymbol = GetCPISymbol(MO.getIndex()); 670 if (TM.getCodeModel() == CodeModel::Large) 671 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 672 } 673 else if (MO.isGlobal()) { 674 const GlobalValue *GValue = MO.getGlobal(); 675 MOSymbol = getSymbol(GValue); 676 if (GValue->getType()->getElementType()->isFunctionTy() || 677 GValue->isDeclaration() || GValue->hasCommonLinkage() || 678 GValue->hasAvailableExternallyLinkage() || 679 TM.getCodeModel() == CodeModel::Large) 680 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 681 } 682 683 const MCExpr *Exp = 684 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 685 OutContext); 686 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 687 EmitToStreamer(OutStreamer, TmpInst); 688 return; 689 } 690 case PPC::ADDItocL: { 691 // Transform %Xd = ADDItocL %Xs, <ga:@sym> 692 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 693 694 // Change the opcode to ADDI8. If the global address is external, then 695 // generate a TOC entry and reference that. Otherwise reference the 696 // symbol directly. 697 TmpInst.setOpcode(PPC::ADDI8); 698 const MachineOperand &MO = MI->getOperand(2); 699 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL"); 700 MCSymbol *MOSymbol = nullptr; 701 bool IsExternal = false; 702 bool IsNonLocalFunction = false; 703 704 if (MO.isGlobal()) { 705 const GlobalValue *GV = MO.getGlobal(); 706 MOSymbol = getSymbol(GV); 707 IsExternal = GV->isDeclaration(); 708 IsNonLocalFunction = GV->getType()->getElementType()->isFunctionTy() && 709 (GV->isDeclaration() || GV->isWeakForLinker()); 710 } else if (MO.isCPI()) 711 MOSymbol = GetCPISymbol(MO.getIndex()); 712 713 if (IsNonLocalFunction || IsExternal || 714 TM.getCodeModel() == CodeModel::Large) 715 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol); 716 717 const MCExpr *Exp = 718 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, 719 OutContext); 720 TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); 721 EmitToStreamer(OutStreamer, TmpInst); 722 return; 723 } 724 case PPC::ADDISgotTprelHA: { 725 // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> 726 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 727 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 728 const MachineOperand &MO = MI->getOperand(2); 729 const GlobalValue *GValue = MO.getGlobal(); 730 MCSymbol *MOSymbol = getSymbol(GValue); 731 const MCExpr *SymGotTprel = 732 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 733 OutContext); 734 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 735 .addReg(MI->getOperand(0).getReg()) 736 .addReg(MI->getOperand(1).getReg()) 737 .addExpr(SymGotTprel)); 738 return; 739 } 740 case PPC::LDgotTprelL: 741 case PPC::LDgotTprelL32: { 742 // Transform %Xd = LDgotTprelL <ga:@sym>, %Xs 743 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 744 745 // Change the opcode to LD. 746 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ); 747 const MachineOperand &MO = MI->getOperand(1); 748 const GlobalValue *GValue = MO.getGlobal(); 749 MCSymbol *MOSymbol = getSymbol(GValue); 750 const MCExpr *Exp = 751 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, 752 OutContext); 753 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 754 EmitToStreamer(OutStreamer, TmpInst); 755 return; 756 } 757 758 case PPC::PPC32PICGOT: { 759 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 760 MCSymbol *GOTRef = OutContext.CreateTempSymbol(); 761 MCSymbol *NextInstr = OutContext.CreateTempSymbol(); 762 763 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) 764 // FIXME: We would like an efficient form for this, so we don't have to do 765 // a lot of extra uniquing. 766 .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext))); 767 const MCExpr *OffsExpr = 768 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext), 769 MCSymbolRefExpr::Create(GOTRef, OutContext), 770 OutContext); 771 OutStreamer.EmitLabel(GOTRef); 772 OutStreamer.EmitValue(OffsExpr, 4); 773 OutStreamer.EmitLabel(NextInstr); 774 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR) 775 .addReg(MI->getOperand(0).getReg())); 776 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LWZ) 777 .addReg(MI->getOperand(1).getReg()) 778 .addImm(0) 779 .addReg(MI->getOperand(0).getReg())); 780 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADD4) 781 .addReg(MI->getOperand(0).getReg()) 782 .addReg(MI->getOperand(1).getReg()) 783 .addReg(MI->getOperand(0).getReg())); 784 return; 785 } 786 case PPC::PPC32GOT: { 787 MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 788 const MCExpr *SymGotTlsL = 789 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, 790 OutContext); 791 const MCExpr *SymGotTlsHA = 792 MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, 793 OutContext); 794 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI) 795 .addReg(MI->getOperand(0).getReg()) 796 .addExpr(SymGotTlsL)); 797 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 798 .addReg(MI->getOperand(0).getReg()) 799 .addReg(MI->getOperand(0).getReg()) 800 .addExpr(SymGotTlsHA)); 801 return; 802 } 803 case PPC::ADDIStlsgdHA: { 804 // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> 805 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha 806 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 807 const MachineOperand &MO = MI->getOperand(2); 808 const GlobalValue *GValue = MO.getGlobal(); 809 MCSymbol *MOSymbol = getSymbol(GValue); 810 const MCExpr *SymGotTlsGD = 811 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 812 OutContext); 813 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 814 .addReg(MI->getOperand(0).getReg()) 815 .addReg(MI->getOperand(1).getReg()) 816 .addExpr(SymGotTlsGD)); 817 return; 818 } 819 case PPC::ADDItlsgdL: 820 // Transform: %Xd = ADDItlsgdL %Xs, <ga:@sym> 821 // Into: %Xd = ADDI8 %Xs, sym@got@tlsgd@l 822 case PPC::ADDItlsgdL32: { 823 // Transform: %Rd = ADDItlsgdL32 %Rs, <ga:@sym> 824 // Into: %Rd = ADDI %Rs, sym@got@tlsgd 825 const MachineOperand &MO = MI->getOperand(2); 826 const GlobalValue *GValue = MO.getGlobal(); 827 MCSymbol *MOSymbol = getSymbol(GValue); 828 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::Create( 829 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO 830 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, 831 OutContext); 832 EmitToStreamer(OutStreamer, 833 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 834 .addReg(MI->getOperand(0).getReg()) 835 .addReg(MI->getOperand(1).getReg()) 836 .addExpr(SymGotTlsGD)); 837 return; 838 } 839 case PPC::GETtlsADDR: 840 // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> 841 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) 842 case PPC::GETtlsADDR32: { 843 // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym> 844 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT 845 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD); 846 return; 847 } 848 case PPC::ADDIStlsldHA: { 849 // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> 850 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha 851 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); 852 const MachineOperand &MO = MI->getOperand(2); 853 const GlobalValue *GValue = MO.getGlobal(); 854 MCSymbol *MOSymbol = getSymbol(GValue); 855 const MCExpr *SymGotTlsLD = 856 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 857 OutContext); 858 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) 859 .addReg(MI->getOperand(0).getReg()) 860 .addReg(MI->getOperand(1).getReg()) 861 .addExpr(SymGotTlsLD)); 862 return; 863 } 864 case PPC::ADDItlsldL: 865 // Transform: %Xd = ADDItlsldL %Xs, <ga:@sym> 866 // Into: %Xd = ADDI8 %Xs, sym@got@tlsld@l 867 case PPC::ADDItlsldL32: { 868 // Transform: %Rd = ADDItlsldL32 %Rs, <ga:@sym> 869 // Into: %Rd = ADDI %Rs, sym@got@tlsld 870 const MachineOperand &MO = MI->getOperand(2); 871 const GlobalValue *GValue = MO.getGlobal(); 872 MCSymbol *MOSymbol = getSymbol(GValue); 873 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::Create( 874 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO 875 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, 876 OutContext); 877 EmitToStreamer(OutStreamer, 878 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 879 .addReg(MI->getOperand(0).getReg()) 880 .addReg(MI->getOperand(1).getReg()) 881 .addExpr(SymGotTlsLD)); 882 return; 883 } 884 case PPC::GETtlsldADDR: 885 // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> 886 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) 887 case PPC::GETtlsldADDR32: { 888 // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym> 889 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT 890 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD); 891 return; 892 } 893 case PPC::ADDISdtprelHA: 894 // Transform: %Xd = ADDISdtprelHA %X3, <ga:@sym> 895 // Into: %Xd = ADDIS8 %X3, sym@dtprel@ha 896 case PPC::ADDISdtprelHA32: { 897 // Transform: %Rd = ADDISdtprelHA32 %R3, <ga:@sym> 898 // Into: %Rd = ADDIS %R3, sym@dtprel@ha 899 const MachineOperand &MO = MI->getOperand(2); 900 const GlobalValue *GValue = MO.getGlobal(); 901 MCSymbol *MOSymbol = getSymbol(GValue); 902 const MCExpr *SymDtprel = 903 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 904 OutContext); 905 EmitToStreamer( 906 OutStreamer, 907 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) 908 .addReg(MI->getOperand(0).getReg()) 909 .addReg(Subtarget->isPPC64() ? PPC::X3 : PPC::R3) 910 .addExpr(SymDtprel)); 911 return; 912 } 913 case PPC::ADDIdtprelL: 914 // Transform: %Xd = ADDIdtprelL %Xs, <ga:@sym> 915 // Into: %Xd = ADDI8 %Xs, sym@dtprel@l 916 case PPC::ADDIdtprelL32: { 917 // Transform: %Rd = ADDIdtprelL32 %Rs, <ga:@sym> 918 // Into: %Rd = ADDI %Rs, sym@dtprel@l 919 const MachineOperand &MO = MI->getOperand(2); 920 const GlobalValue *GValue = MO.getGlobal(); 921 MCSymbol *MOSymbol = getSymbol(GValue); 922 const MCExpr *SymDtprel = 923 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 924 OutContext); 925 EmitToStreamer(OutStreamer, 926 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) 927 .addReg(MI->getOperand(0).getReg()) 928 .addReg(MI->getOperand(1).getReg()) 929 .addExpr(SymDtprel)); 930 return; 931 } 932 case PPC::MFOCRF: 933 case PPC::MFOCRF8: 934 if (!Subtarget->hasMFOCRF()) { 935 // Transform: %R3 = MFOCRF %CR7 936 // Into: %R3 = MFCR ;; cr7 937 unsigned NewOpcode = 938 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 939 OutStreamer.AddComment(PPCInstPrinter:: 940 getRegisterName(MI->getOperand(1).getReg())); 941 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 942 .addReg(MI->getOperand(0).getReg())); 943 return; 944 } 945 break; 946 case PPC::MTOCRF: 947 case PPC::MTOCRF8: 948 if (!Subtarget->hasMFOCRF()) { 949 // Transform: %CR7 = MTOCRF %R3 950 // Into: MTCRF mask, %R3 ;; cr7 951 unsigned NewOpcode = 952 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 953 unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 954 ->getEncodingValue(MI->getOperand(0).getReg()); 955 OutStreamer.AddComment(PPCInstPrinter:: 956 getRegisterName(MI->getOperand(0).getReg())); 957 EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) 958 .addImm(Mask) 959 .addReg(MI->getOperand(1).getReg())); 960 return; 961 } 962 break; 963 case PPC::LD: 964 case PPC::STD: 965 case PPC::LWA_32: 966 case PPC::LWA: { 967 // Verify alignment is legal, so we don't create relocations 968 // that can't be supported. 969 // FIXME: This test is currently disabled for Darwin. The test 970 // suite shows a handful of test cases that fail this check for 971 // Darwin. Those need to be investigated before this sanity test 972 // can be enabled for those subtargets. 973 if (!Subtarget->isDarwin()) { 974 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 975 const MachineOperand &MO = MI->getOperand(OpNum); 976 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) 977 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 978 } 979 // Now process the instruction normally. 980 break; 981 } 982 } 983 984 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); 985 EmitToStreamer(OutStreamer, TmpInst); 986} 987 988void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { 989 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) { 990 PPCTargetStreamer *TS = 991 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 992 993 if (TS) 994 TS->emitAbiVersion(2); 995 } 996 997 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() || 998 TM.getRelocationModel() != Reloc::PIC_) 999 return AsmPrinter::EmitStartOfAsmFile(M); 1000 1001 if (M.getPICLevel() == PICLevel::Small) 1002 return AsmPrinter::EmitStartOfAsmFile(M); 1003 1004 OutStreamer.SwitchSection(OutContext.getELFSection( 1005 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC)); 1006 1007 MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC")); 1008 MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); 1009 1010 OutStreamer.EmitLabel(CurrentPos); 1011 1012 // The GOT pointer points to the middle of the GOT, in order to reference the 1013 // entire 64kB range. 0x8000 is the midpoint. 1014 const MCExpr *tocExpr = 1015 MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(CurrentPos, OutContext), 1016 MCConstantExpr::Create(0x8000, OutContext), 1017 OutContext); 1018 1019 OutStreamer.EmitAssignment(TOCSym, tocExpr); 1020 1021 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 1022} 1023 1024void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 1025 // linux/ppc32 - Normal entry label. 1026 if (!Subtarget->isPPC64() && 1027 (TM.getRelocationModel() != Reloc::PIC_ || 1028 MF->getFunction()->getParent()->getPICLevel() == PICLevel::Small)) 1029 return AsmPrinter::EmitFunctionEntryLabel(); 1030 1031 if (!Subtarget->isPPC64()) { 1032 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1033 if (PPCFI->usesPICBase()) { 1034 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); 1035 MCSymbol *PICBase = MF->getPICBaseSymbol(); 1036 OutStreamer.EmitLabel(RelocSymbol); 1037 1038 const MCExpr *OffsExpr = 1039 MCBinaryExpr::CreateSub( 1040 MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), 1041 OutContext), 1042 MCSymbolRefExpr::Create(PICBase, OutContext), 1043 OutContext); 1044 OutStreamer.EmitValue(OffsExpr, 4); 1045 OutStreamer.EmitLabel(CurrentFnSym); 1046 return; 1047 } else 1048 return AsmPrinter::EmitFunctionEntryLabel(); 1049 } 1050 1051 // ELFv2 ABI - Normal entry label. 1052 if (Subtarget->isELFv2ABI()) 1053 return AsmPrinter::EmitFunctionEntryLabel(); 1054 1055 // Emit an official procedure descriptor. 1056 MCSectionSubPair Current = OutStreamer.getCurrentSection(); 1057 const MCSectionELF *Section = OutStreamer.getContext().getELFSection( 1058 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1059 OutStreamer.SwitchSection(Section); 1060 OutStreamer.EmitLabel(CurrentFnSym); 1061 OutStreamer.EmitValueToAlignment(8); 1062 MCSymbol *Symbol1 = CurrentFnSymForSize; 1063 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 1064 // entry point. 1065 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), 1066 8 /*size*/); 1067 MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 1068 // Generates a R_PPC64_TOC relocation for TOC base insertion. 1069 OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, 1070 MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 1071 8/*size*/); 1072 // Emit a null environment pointer. 1073 OutStreamer.EmitIntValue(0, 8 /* size */); 1074 OutStreamer.SwitchSection(Current.first, Current.second); 1075} 1076 1077 1078bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 1079 const DataLayout *TD = TM.getDataLayout(); 1080 1081 bool isPPC64 = TD->getPointerSizeInBits() == 64; 1082 1083 PPCTargetStreamer &TS = 1084 static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); 1085 1086 if (!TOC.empty()) { 1087 const MCSectionELF *Section; 1088 1089 if (isPPC64) 1090 Section = OutStreamer.getContext().getELFSection( 1091 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1092 else 1093 Section = OutStreamer.getContext().getELFSection( 1094 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1095 OutStreamer.SwitchSection(Section); 1096 1097 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 1098 E = TOC.end(); I != E; ++I) { 1099 OutStreamer.EmitLabel(I->second); 1100 MCSymbol *S = I->first; 1101 if (isPPC64) 1102 TS.emitTCEntry(*S); 1103 else 1104 OutStreamer.EmitSymbolValue(S, 4); 1105 } 1106 } 1107 1108 return AsmPrinter::doFinalization(M); 1109} 1110 1111/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 1112void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { 1113 // In the ELFv2 ABI, in functions that use the TOC register, we need to 1114 // provide two entry points. The ABI guarantees that when calling the 1115 // local entry point, r2 is set up by the caller to contain the TOC base 1116 // for this function, and when calling the global entry point, r12 is set 1117 // up by the caller to hold the address of the global entry point. We 1118 // thus emit a prefix sequence along the following lines: 1119 // 1120 // func: 1121 // # global entry point 1122 // addis r2,r12,(.TOC.-func)@ha 1123 // addi r2,r2,(.TOC.-func)@l 1124 // .localentry func, .-func 1125 // # local entry point, followed by function body 1126 // 1127 // This ensures we have r2 set up correctly while executing the function 1128 // body, no matter which entry point is called. 1129 if (Subtarget->isELFv2ABI() 1130 // Only do all that if the function uses r2 in the first place. 1131 && !MF->getRegInfo().use_empty(PPC::X2)) { 1132 1133 MCSymbol *GlobalEntryLabel = OutContext.CreateTempSymbol(); 1134 OutStreamer.EmitLabel(GlobalEntryLabel); 1135 const MCSymbolRefExpr *GlobalEntryLabelExp = 1136 MCSymbolRefExpr::Create(GlobalEntryLabel, OutContext); 1137 1138 MCSymbol *TOCSymbol = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); 1139 const MCExpr *TOCDeltaExpr = 1140 MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(TOCSymbol, OutContext), 1141 GlobalEntryLabelExp, OutContext); 1142 1143 const MCExpr *TOCDeltaHi = 1144 PPCMCExpr::CreateHa(TOCDeltaExpr, false, OutContext); 1145 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 1146 .addReg(PPC::X2) 1147 .addReg(PPC::X12) 1148 .addExpr(TOCDeltaHi)); 1149 1150 const MCExpr *TOCDeltaLo = 1151 PPCMCExpr::CreateLo(TOCDeltaExpr, false, OutContext); 1152 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI) 1153 .addReg(PPC::X2) 1154 .addReg(PPC::X2) 1155 .addExpr(TOCDeltaLo)); 1156 1157 MCSymbol *LocalEntryLabel = OutContext.CreateTempSymbol(); 1158 OutStreamer.EmitLabel(LocalEntryLabel); 1159 const MCSymbolRefExpr *LocalEntryLabelExp = 1160 MCSymbolRefExpr::Create(LocalEntryLabel, OutContext); 1161 const MCExpr *LocalOffsetExp = 1162 MCBinaryExpr::CreateSub(LocalEntryLabelExp, 1163 GlobalEntryLabelExp, OutContext); 1164 1165 PPCTargetStreamer *TS = 1166 static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 1167 1168 if (TS) 1169 TS->emitLocalEntry(CurrentFnSym, LocalOffsetExp); 1170 } 1171} 1172 1173/// EmitFunctionBodyEnd - Print the traceback table before the .size 1174/// directive. 1175/// 1176void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { 1177 // Only the 64-bit target requires a traceback table. For now, 1178 // we only emit the word of zeroes that GDB requires to find 1179 // the end of the function, and zeroes for the eight-byte 1180 // mandatory fields. 1181 // FIXME: We should fill in the eight-byte mandatory fields as described in 1182 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 1183 // currently make use of these fields). 1184 if (Subtarget->isPPC64()) { 1185 OutStreamer.EmitIntValue(0, 4/*size*/); 1186 OutStreamer.EmitIntValue(0, 8/*size*/); 1187 } 1188} 1189 1190void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 1191 static const char *const CPUDirectives[] = { 1192 "", 1193 "ppc", 1194 "ppc440", 1195 "ppc601", 1196 "ppc602", 1197 "ppc603", 1198 "ppc7400", 1199 "ppc750", 1200 "ppc970", 1201 "ppcA2", 1202 "ppce500mc", 1203 "ppce5500", 1204 "power3", 1205 "power4", 1206 "power5", 1207 "power5x", 1208 "power6", 1209 "power6x", 1210 "power7", 1211 "ppc64", 1212 "ppc64le" 1213 }; 1214 1215 // Get the numerically largest directive. 1216 // FIXME: How should we merge darwin directives? 1217 unsigned Directive = PPC::DIR_NONE; 1218 for (const Function &F : M) { 1219 const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F); 1220 unsigned FDir = STI.getDarwinDirective(); 1221 Directive = Directive > FDir ? FDir : STI.getDarwinDirective(); 1222 if (STI.hasMFOCRF() && Directive < PPC::DIR_970) 1223 Directive = PPC::DIR_970; 1224 if (STI.hasAltivec() && Directive < PPC::DIR_7400) 1225 Directive = PPC::DIR_7400; 1226 if (STI.isPPC64() && Directive < PPC::DIR_64) 1227 Directive = PPC::DIR_64; 1228 } 1229 1230 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 1231 1232 assert(Directive < array_lengthof(CPUDirectives) && 1233 "CPUDirectives[] might not be up-to-date!"); 1234 PPCTargetStreamer &TStreamer = 1235 *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); 1236 TStreamer.emitMachine(CPUDirectives[Directive]); 1237 1238 // Prime text sections so they are adjacent. This reduces the likelihood a 1239 // large data or debug section causes a branch to exceed 16M limit. 1240 const TargetLoweringObjectFileMachO &TLOFMacho = 1241 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1242 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 1243 if (TM.getRelocationModel() == Reloc::PIC_) { 1244 OutStreamer.SwitchSection( 1245 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 1246 MachO::S_SYMBOL_STUBS | 1247 MachO::S_ATTR_PURE_INSTRUCTIONS, 1248 32, SectionKind::getText())); 1249 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 1250 OutStreamer.SwitchSection( 1251 OutContext.getMachOSection("__TEXT","__symbol_stub1", 1252 MachO::S_SYMBOL_STUBS | 1253 MachO::S_ATTR_PURE_INSTRUCTIONS, 1254 16, SectionKind::getText())); 1255 } 1256 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 1257} 1258 1259static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 1260 // Remove $stub suffix, add $lazy_ptr. 1261 StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); 1262 return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); 1263} 1264 1265static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 1266 // Add $tmp suffix to $stub, yielding $stub$tmp. 1267 return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); 1268} 1269 1270void PPCDarwinAsmPrinter:: 1271EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 1272 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1273 1274 // Construct a local MCSubtargetInfo and shadow EmitToStreamer here. 1275 // This is because the MachineFunction won't exist (but have not yet been 1276 // freed) and since we're at the global level we can use the default 1277 // constructed subtarget. 1278 std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( 1279 TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString())); 1280 auto EmitToStreamer = [&STI] (MCStreamer &S, const MCInst &Inst) { 1281 S.EmitInstruction(Inst, *STI); 1282 }; 1283 1284 const TargetLoweringObjectFileMachO &TLOFMacho = 1285 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1286 1287 // .lazy_symbol_pointer 1288 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 1289 1290 // Output stubs for dynamically-linked functions 1291 if (TM.getRelocationModel() == Reloc::PIC_) { 1292 const MCSection *StubSection = 1293 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 1294 MachO::S_SYMBOL_STUBS | 1295 MachO::S_ATTR_PURE_INSTRUCTIONS, 1296 32, SectionKind::getText()); 1297 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1298 OutStreamer.SwitchSection(StubSection); 1299 EmitAlignment(4); 1300 1301 MCSymbol *Stub = Stubs[i].first; 1302 MCSymbol *RawSym = Stubs[i].second.getPointer(); 1303 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 1304 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 1305 1306 OutStreamer.EmitLabel(Stub); 1307 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1308 1309 const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); 1310 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 1311 const MCExpr *Sub = 1312 MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); 1313 1314 // mflr r0 1315 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); 1316 // bcl 20, 31, AnonSymbol 1317 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); 1318 OutStreamer.EmitLabel(AnonSymbol); 1319 // mflr r11 1320 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); 1321 // addis r11, r11, ha16(LazyPtr - AnonSymbol) 1322 const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, true, OutContext); 1323 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) 1324 .addReg(PPC::R11) 1325 .addReg(PPC::R11) 1326 .addExpr(SubHa16)); 1327 // mtlr r0 1328 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); 1329 1330 // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) 1331 // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) 1332 const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, true, OutContext); 1333 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 1334 .addReg(PPC::R12) 1335 .addExpr(SubLo16).addExpr(SubLo16) 1336 .addReg(PPC::R11)); 1337 // mtctr r12 1338 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 1339 // bctr 1340 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 1341 1342 OutStreamer.SwitchSection(LSPSection); 1343 OutStreamer.EmitLabel(LazyPtr); 1344 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1345 1346 MCSymbol *DyldStubBindingHelper = 1347 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1348 if (isPPC64) { 1349 // .quad dyld_stub_binding_helper 1350 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1351 } else { 1352 // .long dyld_stub_binding_helper 1353 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1354 } 1355 } 1356 OutStreamer.AddBlankLine(); 1357 return; 1358 } 1359 1360 const MCSection *StubSection = 1361 OutContext.getMachOSection("__TEXT","__symbol_stub1", 1362 MachO::S_SYMBOL_STUBS | 1363 MachO::S_ATTR_PURE_INSTRUCTIONS, 1364 16, SectionKind::getText()); 1365 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1366 MCSymbol *Stub = Stubs[i].first; 1367 MCSymbol *RawSym = Stubs[i].second.getPointer(); 1368 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 1369 const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); 1370 1371 OutStreamer.SwitchSection(StubSection); 1372 EmitAlignment(4); 1373 OutStreamer.EmitLabel(Stub); 1374 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1375 1376 // lis r11, ha16(LazyPtr) 1377 const MCExpr *LazyPtrHa16 = 1378 PPCMCExpr::CreateHa(LazyPtrExpr, true, OutContext); 1379 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS) 1380 .addReg(PPC::R11) 1381 .addExpr(LazyPtrHa16)); 1382 1383 // ldu r12, lo16(LazyPtr)(r11) 1384 // lwzu r12, lo16(LazyPtr)(r11) 1385 const MCExpr *LazyPtrLo16 = 1386 PPCMCExpr::CreateLo(LazyPtrExpr, true, OutContext); 1387 EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) 1388 .addReg(PPC::R12) 1389 .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) 1390 .addReg(PPC::R11)); 1391 1392 // mtctr r12 1393 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); 1394 // bctr 1395 EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); 1396 1397 OutStreamer.SwitchSection(LSPSection); 1398 OutStreamer.EmitLabel(LazyPtr); 1399 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 1400 1401 MCSymbol *DyldStubBindingHelper = 1402 OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); 1403 if (isPPC64) { 1404 // .quad dyld_stub_binding_helper 1405 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); 1406 } else { 1407 // .long dyld_stub_binding_helper 1408 OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); 1409 } 1410 } 1411 1412 OutStreamer.AddBlankLine(); 1413} 1414 1415 1416bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 1417 bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; 1418 1419 // Darwin/PPC always uses mach-o. 1420 const TargetLoweringObjectFileMachO &TLOFMacho = 1421 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 1422 MachineModuleInfoMachO &MMIMacho = 1423 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 1424 1425 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 1426 if (!Stubs.empty()) 1427 EmitFunctionStubs(Stubs); 1428 1429 if (MAI->doesSupportExceptionHandling() && MMI) { 1430 // Add the (possibly multiple) personalities to the set of global values. 1431 // Only referenced functions get into the Personalities list. 1432 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 1433 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 1434 E = Personalities.end(); I != E; ++I) { 1435 if (*I) { 1436 MCSymbol *NLPSym = getSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 1437 MachineModuleInfoImpl::StubValueTy &StubSym = 1438 MMIMacho.getGVStubEntry(NLPSym); 1439 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(*I), true); 1440 } 1441 } 1442 } 1443 1444 // Output stubs for dynamically-linked functions. 1445 Stubs = MMIMacho.GetGVStubList(); 1446 1447 // Output macho stubs for external and common global variables. 1448 if (!Stubs.empty()) { 1449 // Switch with ".non_lazy_symbol_pointer" directive. 1450 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 1451 EmitAlignment(isPPC64 ? 3 : 2); 1452 1453 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1454 // L_foo$stub: 1455 OutStreamer.EmitLabel(Stubs[i].first); 1456 // .indirect_symbol _foo 1457 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 1458 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 1459 1460 if (MCSym.getInt()) 1461 // External to current translation unit. 1462 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); 1463 else 1464 // Internal to current translation unit. 1465 // 1466 // When we place the LSDA into the TEXT section, the type info pointers 1467 // need to be indirect and pc-rel. We accomplish this by using NLPs. 1468 // However, sometimes the types are local to the file. So we need to 1469 // fill in the value for the NLP in those cases. 1470 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 1471 OutContext), 1472 isPPC64 ? 8 : 4/*size*/); 1473 } 1474 1475 Stubs.clear(); 1476 OutStreamer.AddBlankLine(); 1477 } 1478 1479 Stubs = MMIMacho.GetHiddenGVStubList(); 1480 if (!Stubs.empty()) { 1481 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 1482 EmitAlignment(isPPC64 ? 3 : 2); 1483 1484 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1485 // L_foo$stub: 1486 OutStreamer.EmitLabel(Stubs[i].first); 1487 // .long _foo 1488 OutStreamer.EmitValue(MCSymbolRefExpr:: 1489 Create(Stubs[i].second.getPointer(), 1490 OutContext), 1491 isPPC64 ? 8 : 4/*size*/); 1492 } 1493 1494 Stubs.clear(); 1495 OutStreamer.AddBlankLine(); 1496 } 1497 1498 // Funny Darwin hack: This flag tells the linker that no global symbols 1499 // contain code that falls through to other global symbols (e.g. the obvious 1500 // implementation of multiple entry points). If this doesn't occur, the 1501 // linker can safely perform dead code stripping. Since LLVM never generates 1502 // code that does this, it is always safe to set. 1503 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 1504 1505 return AsmPrinter::doFinalization(M); 1506} 1507 1508/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 1509/// for a MachineFunction to the given output stream, in a format that the 1510/// Darwin assembler can deal with. 1511/// 1512static AsmPrinter * 1513createPPCAsmPrinterPass(TargetMachine &tm, 1514 std::unique_ptr<MCStreamer> &&Streamer) { 1515 if (Triple(tm.getTargetTriple()).isMacOSX()) 1516 return new PPCDarwinAsmPrinter(tm, std::move(Streamer)); 1517 return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); 1518} 1519 1520// Force static initialization. 1521extern "C" void LLVMInitializePowerPCAsmPrinter() { 1522 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1523 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1524 TargetRegistry::RegisterAsmPrinter(ThePPC64LETarget, createPPCAsmPrinterPass); 1525} 1526