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