1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains a printer that converts from our internal representation 10 // of machine-dependent LLVM code to PowerPC assembly language. This printer is 11 // the output mechanism used by `llc'. 12 // 13 // Documentation at http://developer.apple.com/documentation/DeveloperTools/ 14 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "MCTargetDesc/PPCInstPrinter.h" 19 #include "MCTargetDesc/PPCMCExpr.h" 20 #include "MCTargetDesc/PPCMCTargetDesc.h" 21 #include "MCTargetDesc/PPCPredicates.h" 22 #include "PPC.h" 23 #include "PPCInstrInfo.h" 24 #include "PPCMachineFunctionInfo.h" 25 #include "PPCSubtarget.h" 26 #include "PPCTargetMachine.h" 27 #include "PPCTargetStreamer.h" 28 #include "TargetInfo/PowerPCTargetInfo.h" 29 #include "llvm/ADT/MapVector.h" 30 #include "llvm/ADT/SmallPtrSet.h" 31 #include "llvm/ADT/StringRef.h" 32 #include "llvm/ADT/Triple.h" 33 #include "llvm/ADT/Twine.h" 34 #include "llvm/BinaryFormat/ELF.h" 35 #include "llvm/CodeGen/AsmPrinter.h" 36 #include "llvm/CodeGen/MachineBasicBlock.h" 37 #include "llvm/CodeGen/MachineFunction.h" 38 #include "llvm/CodeGen/MachineInstr.h" 39 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 40 #include "llvm/CodeGen/MachineOperand.h" 41 #include "llvm/CodeGen/MachineRegisterInfo.h" 42 #include "llvm/CodeGen/StackMaps.h" 43 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 44 #include "llvm/IR/DataLayout.h" 45 #include "llvm/IR/GlobalValue.h" 46 #include "llvm/IR/GlobalVariable.h" 47 #include "llvm/IR/Module.h" 48 #include "llvm/MC/MCAsmInfo.h" 49 #include "llvm/MC/MCContext.h" 50 #include "llvm/MC/MCDirectives.h" 51 #include "llvm/MC/MCExpr.h" 52 #include "llvm/MC/MCInst.h" 53 #include "llvm/MC/MCInstBuilder.h" 54 #include "llvm/MC/MCSectionELF.h" 55 #include "llvm/MC/MCSectionXCOFF.h" 56 #include "llvm/MC/MCStreamer.h" 57 #include "llvm/MC/MCSymbol.h" 58 #include "llvm/MC/MCSymbolELF.h" 59 #include "llvm/MC/MCSymbolXCOFF.h" 60 #include "llvm/MC/SectionKind.h" 61 #include "llvm/Support/Casting.h" 62 #include "llvm/Support/CodeGen.h" 63 #include "llvm/Support/Debug.h" 64 #include "llvm/Support/ErrorHandling.h" 65 #include "llvm/Support/Process.h" 66 #include "llvm/Support/TargetRegistry.h" 67 #include "llvm/Support/raw_ostream.h" 68 #include "llvm/Target/TargetMachine.h" 69 #include "llvm/Transforms/Utils/ModuleUtils.h" 70 #include <algorithm> 71 #include <cassert> 72 #include <cstdint> 73 #include <memory> 74 #include <new> 75 76 using namespace llvm; 77 using namespace llvm::XCOFF; 78 79 #define DEBUG_TYPE "asmprinter" 80 81 // Specialize DenseMapInfo to allow 82 // std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap. 83 // This specialization is needed here because that type is used as keys in the 84 // map representing TOC entries. 85 namespace llvm { 86 template <> 87 struct DenseMapInfo<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> { 88 using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>; 89 90 static inline TOCKey getEmptyKey() { 91 return {nullptr, MCSymbolRefExpr::VariantKind::VK_None}; 92 } 93 static inline TOCKey getTombstoneKey() { 94 return {nullptr, MCSymbolRefExpr::VariantKind::VK_Invalid}; 95 } 96 static unsigned getHashValue(const TOCKey &PairVal) { 97 return detail::combineHashValue( 98 DenseMapInfo<const MCSymbol *>::getHashValue(PairVal.first), 99 DenseMapInfo<int>::getHashValue(PairVal.second)); 100 } 101 static bool isEqual(const TOCKey &A, const TOCKey &B) { return A == B; } 102 }; 103 } // end namespace llvm 104 105 namespace { 106 107 class PPCAsmPrinter : public AsmPrinter { 108 protected: 109 // For TLS on AIX, we need to be able to identify TOC entries of specific 110 // VariantKind so we can add the right relocations when we generate the 111 // entries. So each entry is represented by a pair of MCSymbol and 112 // VariantKind. For example, we need to be able to identify the following 113 // entry as a TLSGD entry so we can add the @m relocation: 114 // .tc .i[TC],i[TL]@m 115 // By default, VK_None is used for the VariantKind. 116 MapVector<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>, 117 MCSymbol *> 118 TOC; 119 const PPCSubtarget *Subtarget = nullptr; 120 StackMaps SM; 121 122 public: 123 explicit PPCAsmPrinter(TargetMachine &TM, 124 std::unique_ptr<MCStreamer> Streamer) 125 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {} 126 127 StringRef getPassName() const override { return "PowerPC Assembly Printer"; } 128 129 MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym, 130 MCSymbolRefExpr::VariantKind Kind = 131 MCSymbolRefExpr::VariantKind::VK_None); 132 133 bool doInitialization(Module &M) override { 134 if (!TOC.empty()) 135 TOC.clear(); 136 return AsmPrinter::doInitialization(M); 137 } 138 139 void emitInstruction(const MachineInstr *MI) override; 140 141 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand, 142 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only. 143 /// The \p MI would be INLINEASM ONLY. 144 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O); 145 146 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override; 147 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 148 const char *ExtraCode, raw_ostream &O) override; 149 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 150 const char *ExtraCode, raw_ostream &O) override; 151 152 void emitEndOfAsmFile(Module &M) override; 153 154 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI); 155 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI); 156 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); 157 bool runOnMachineFunction(MachineFunction &MF) override { 158 Subtarget = &MF.getSubtarget<PPCSubtarget>(); 159 bool Changed = AsmPrinter::runOnMachineFunction(MF); 160 emitXRayTable(); 161 return Changed; 162 } 163 }; 164 165 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 166 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 167 public: 168 explicit PPCLinuxAsmPrinter(TargetMachine &TM, 169 std::unique_ptr<MCStreamer> Streamer) 170 : PPCAsmPrinter(TM, std::move(Streamer)) {} 171 172 StringRef getPassName() const override { 173 return "Linux PPC Assembly Printer"; 174 } 175 176 void emitStartOfAsmFile(Module &M) override; 177 void emitEndOfAsmFile(Module &) override; 178 179 void emitFunctionEntryLabel() override; 180 181 void emitFunctionBodyStart() override; 182 void emitFunctionBodyEnd() override; 183 void emitInstruction(const MachineInstr *MI) override; 184 }; 185 186 class PPCAIXAsmPrinter : public PPCAsmPrinter { 187 private: 188 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern 189 /// linkage for them in AIX. 190 SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols; 191 192 /// A format indicator and unique trailing identifier to form part of the 193 /// sinit/sterm function names. 194 std::string FormatIndicatorAndUniqueModId; 195 196 // Record a list of GlobalAlias associated with a GlobalObject. 197 // This is used for AIX's extra-label-at-definition aliasing strategy. 198 DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>> 199 GOAliasMap; 200 201 void emitTracebackTable(); 202 203 SmallVector<const GlobalVariable *, 8> TOCDataGlobalVars; 204 205 void emitGlobalVariableHelper(const GlobalVariable *); 206 207 public: 208 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) 209 : PPCAsmPrinter(TM, std::move(Streamer)) { 210 if (MAI->isLittleEndian()) 211 report_fatal_error( 212 "cannot create AIX PPC Assembly Printer for a little-endian target"); 213 } 214 215 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; } 216 217 bool doInitialization(Module &M) override; 218 219 void emitXXStructorList(const DataLayout &DL, const Constant *List, 220 bool IsCtor) override; 221 222 void SetupMachineFunction(MachineFunction &MF) override; 223 224 void emitGlobalVariable(const GlobalVariable *GV) override; 225 226 void emitFunctionDescriptor() override; 227 228 void emitFunctionEntryLabel() override; 229 230 void emitFunctionBodyEnd() override; 231 232 void emitEndOfAsmFile(Module &) override; 233 234 void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override; 235 236 void emitInstruction(const MachineInstr *MI) override; 237 238 bool doFinalization(Module &M) override; 239 240 void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override; 241 }; 242 243 } // end anonymous namespace 244 245 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO, 246 raw_ostream &O) { 247 // Computing the address of a global symbol, not calling it. 248 const GlobalValue *GV = MO.getGlobal(); 249 getSymbol(GV)->print(O, MAI); 250 printOffset(MO.getOffset(), O); 251 } 252 253 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, 254 raw_ostream &O) { 255 const DataLayout &DL = getDataLayout(); 256 const MachineOperand &MO = MI->getOperand(OpNo); 257 258 switch (MO.getType()) { 259 case MachineOperand::MO_Register: { 260 // The MI is INLINEASM ONLY and UseVSXReg is always false. 261 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); 262 263 // Linux assembler (Others?) does not take register mnemonics. 264 // FIXME - What about special registers used in mfspr/mtspr? 265 O << PPCRegisterInfo::stripRegisterPrefix(RegName); 266 return; 267 } 268 case MachineOperand::MO_Immediate: 269 O << MO.getImm(); 270 return; 271 272 case MachineOperand::MO_MachineBasicBlock: 273 MO.getMBB()->getSymbol()->print(O, MAI); 274 return; 275 case MachineOperand::MO_ConstantPoolIndex: 276 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' 277 << MO.getIndex(); 278 return; 279 case MachineOperand::MO_BlockAddress: 280 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI); 281 return; 282 case MachineOperand::MO_GlobalAddress: { 283 PrintSymbolOperand(MO, O); 284 return; 285 } 286 287 default: 288 O << "<unknown operand type: " << (unsigned)MO.getType() << ">"; 289 return; 290 } 291 } 292 293 /// PrintAsmOperand - Print out an operand for an inline asm expression. 294 /// 295 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 296 const char *ExtraCode, raw_ostream &O) { 297 // Does this asm operand have a single letter operand modifier? 298 if (ExtraCode && ExtraCode[0]) { 299 if (ExtraCode[1] != 0) return true; // Unknown modifier. 300 301 switch (ExtraCode[0]) { 302 default: 303 // See if this is a generic print operand 304 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O); 305 case 'L': // Write second word of DImode reference. 306 // Verify that this operand has two consecutive registers. 307 if (!MI->getOperand(OpNo).isReg() || 308 OpNo+1 == MI->getNumOperands() || 309 !MI->getOperand(OpNo+1).isReg()) 310 return true; 311 ++OpNo; // Return the high-part. 312 break; 313 case 'I': 314 // Write 'i' if an integer constant, otherwise nothing. Used to print 315 // addi vs add, etc. 316 if (MI->getOperand(OpNo).isImm()) 317 O << "i"; 318 return false; 319 case 'x': 320 if(!MI->getOperand(OpNo).isReg()) 321 return true; 322 // This operand uses VSX numbering. 323 // If the operand is a VMX register, convert it to a VSX register. 324 Register Reg = MI->getOperand(OpNo).getReg(); 325 if (PPCInstrInfo::isVRRegister(Reg)) 326 Reg = PPC::VSX32 + (Reg - PPC::V0); 327 else if (PPCInstrInfo::isVFRegister(Reg)) 328 Reg = PPC::VSX32 + (Reg - PPC::VF0); 329 const char *RegName; 330 RegName = PPCInstPrinter::getRegisterName(Reg); 331 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); 332 O << RegName; 333 return false; 334 } 335 } 336 337 printOperand(MI, OpNo, O); 338 return false; 339 } 340 341 // At the moment, all inline asm memory operands are a single register. 342 // In any case, the output of this routine should always be just one 343 // assembler operand. 344 345 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 346 const char *ExtraCode, 347 raw_ostream &O) { 348 if (ExtraCode && ExtraCode[0]) { 349 if (ExtraCode[1] != 0) return true; // Unknown modifier. 350 351 switch (ExtraCode[0]) { 352 default: return true; // Unknown modifier. 353 case 'L': // A memory reference to the upper word of a double word op. 354 O << getDataLayout().getPointerSize() << "("; 355 printOperand(MI, OpNo, O); 356 O << ")"; 357 return false; 358 case 'y': // A memory reference for an X-form instruction 359 O << "0, "; 360 printOperand(MI, OpNo, O); 361 return false; 362 case 'U': // Print 'u' for update form. 363 case 'X': // Print 'x' for indexed form. 364 // FIXME: Currently for PowerPC memory operands are always loaded 365 // into a register, so we never get an update or indexed form. 366 // This is bad even for offset forms, since even if we know we 367 // have a value in -16(r1), we will generate a load into r<n> 368 // and then load from 0(r<n>). Until that issue is fixed, 369 // tolerate 'U' and 'X' but don't output anything. 370 assert(MI->getOperand(OpNo).isReg()); 371 return false; 372 } 373 } 374 375 assert(MI->getOperand(OpNo).isReg()); 376 O << "0("; 377 printOperand(MI, OpNo, O); 378 O << ")"; 379 return false; 380 } 381 382 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 383 /// exists for it. If not, create one. Then return a symbol that references 384 /// the TOC entry. 385 MCSymbol * 386 PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym, 387 MCSymbolRefExpr::VariantKind Kind) { 388 MCSymbol *&TOCEntry = TOC[{Sym, Kind}]; 389 if (!TOCEntry) 390 TOCEntry = createTempSymbol("C"); 391 return TOCEntry; 392 } 393 394 void PPCAsmPrinter::emitEndOfAsmFile(Module &M) { 395 emitStackMaps(SM); 396 } 397 398 void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) { 399 unsigned NumNOPBytes = MI.getOperand(1).getImm(); 400 401 auto &Ctx = OutStreamer->getContext(); 402 MCSymbol *MILabel = Ctx.createTempSymbol(); 403 OutStreamer->emitLabel(MILabel); 404 405 SM.recordStackMap(*MILabel, MI); 406 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 407 408 // Scan ahead to trim the shadow. 409 const MachineBasicBlock &MBB = *MI.getParent(); 410 MachineBasicBlock::const_iterator MII(MI); 411 ++MII; 412 while (NumNOPBytes > 0) { 413 if (MII == MBB.end() || MII->isCall() || 414 MII->getOpcode() == PPC::DBG_VALUE || 415 MII->getOpcode() == TargetOpcode::PATCHPOINT || 416 MII->getOpcode() == TargetOpcode::STACKMAP) 417 break; 418 ++MII; 419 NumNOPBytes -= 4; 420 } 421 422 // Emit nops. 423 for (unsigned i = 0; i < NumNOPBytes; i += 4) 424 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 425 } 426 427 // Lower a patchpoint of the form: 428 // [<def>], <id>, <numBytes>, <target>, <numArgs> 429 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) { 430 auto &Ctx = OutStreamer->getContext(); 431 MCSymbol *MILabel = Ctx.createTempSymbol(); 432 OutStreamer->emitLabel(MILabel); 433 434 SM.recordPatchPoint(*MILabel, MI); 435 PatchPointOpers Opers(&MI); 436 437 unsigned EncodedBytes = 0; 438 const MachineOperand &CalleeMO = Opers.getCallTarget(); 439 440 if (CalleeMO.isImm()) { 441 int64_t CallTarget = CalleeMO.getImm(); 442 if (CallTarget) { 443 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && 444 "High 16 bits of call target should be zero."); 445 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg(); 446 EncodedBytes = 0; 447 // Materialize the jump address: 448 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8) 449 .addReg(ScratchReg) 450 .addImm((CallTarget >> 32) & 0xFFFF)); 451 ++EncodedBytes; 452 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC) 453 .addReg(ScratchReg) 454 .addReg(ScratchReg) 455 .addImm(32).addImm(16)); 456 ++EncodedBytes; 457 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8) 458 .addReg(ScratchReg) 459 .addReg(ScratchReg) 460 .addImm((CallTarget >> 16) & 0xFFFF)); 461 ++EncodedBytes; 462 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8) 463 .addReg(ScratchReg) 464 .addReg(ScratchReg) 465 .addImm(CallTarget & 0xFFFF)); 466 467 // Save the current TOC pointer before the remote call. 468 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset(); 469 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD) 470 .addReg(PPC::X2) 471 .addImm(TOCSaveOffset) 472 .addReg(PPC::X1)); 473 ++EncodedBytes; 474 475 // If we're on ELFv1, then we need to load the actual function pointer 476 // from the function descriptor. 477 if (!Subtarget->isELFv2ABI()) { 478 // Load the new TOC pointer and the function address, but not r11 479 // (needing this is rare, and loading it here would prevent passing it 480 // via a 'nest' parameter. 481 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 482 .addReg(PPC::X2) 483 .addImm(8) 484 .addReg(ScratchReg)); 485 ++EncodedBytes; 486 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 487 .addReg(ScratchReg) 488 .addImm(0) 489 .addReg(ScratchReg)); 490 ++EncodedBytes; 491 } 492 493 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8) 494 .addReg(ScratchReg)); 495 ++EncodedBytes; 496 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8)); 497 ++EncodedBytes; 498 499 // Restore the TOC pointer after the call. 500 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 501 .addReg(PPC::X2) 502 .addImm(TOCSaveOffset) 503 .addReg(PPC::X1)); 504 ++EncodedBytes; 505 } 506 } else if (CalleeMO.isGlobal()) { 507 const GlobalValue *GValue = CalleeMO.getGlobal(); 508 MCSymbol *MOSymbol = getSymbol(GValue); 509 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext); 510 511 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP) 512 .addExpr(SymVar)); 513 EncodedBytes += 2; 514 } 515 516 // Each instruction is 4 bytes. 517 EncodedBytes *= 4; 518 519 // Emit padding. 520 unsigned NumBytes = Opers.getNumPatchBytes(); 521 assert(NumBytes >= EncodedBytes && 522 "Patchpoint can't request size less than the length of a call."); 523 assert((NumBytes - EncodedBytes) % 4 == 0 && 524 "Invalid number of NOP bytes requested!"); 525 for (unsigned i = EncodedBytes; i < NumBytes; i += 4) 526 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 527 } 528 529 /// This helper function creates the TlsGetAddr MCSymbol for AIX. We will 530 /// create the csect and use the qual-name symbol instead of creating just the 531 /// external symbol. 532 static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx) { 533 return Ctx 534 .getXCOFFSection(".__tls_get_addr", SectionKind::getText(), 535 XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER)) 536 ->getQualNameSymbol(); 537 } 538 539 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a 540 /// call to __tls_get_addr to the current output stream. 541 void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, 542 MCSymbolRefExpr::VariantKind VK) { 543 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; 544 unsigned Opcode = PPC::BL8_NOP_TLS; 545 546 assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI"); 547 if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG || 548 MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) { 549 Kind = MCSymbolRefExpr::VK_PPC_NOTOC; 550 Opcode = PPC::BL8_NOTOC_TLS; 551 } 552 const Module *M = MF->getFunction().getParent(); 553 554 assert(MI->getOperand(0).isReg() && 555 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || 556 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && 557 "GETtls[ld]ADDR[32] must define GPR3"); 558 assert(MI->getOperand(1).isReg() && 559 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || 560 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && 561 "GETtls[ld]ADDR[32] must read GPR3"); 562 563 if (Subtarget->isAIXABI()) { 564 // On AIX, the variable offset should already be in R4 and the region handle 565 // should already be in R3. 566 // For TLSGD, which currently is the only supported access model, we only 567 // need to generate an absolute branch to .__tls_get_addr. 568 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4; 569 (void)VarOffsetReg; 570 assert(MI->getOperand(2).isReg() && 571 MI->getOperand(2).getReg() == VarOffsetReg && 572 "GETtls[ld]ADDR[32] must read GPR4"); 573 MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext); 574 const MCExpr *TlsRef = MCSymbolRefExpr::create( 575 TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext); 576 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef)); 577 return; 578 } 579 580 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr"); 581 582 if (Subtarget->is32BitELFABI() && isPositionIndependent()) 583 Kind = MCSymbolRefExpr::VK_PLT; 584 585 const MCExpr *TlsRef = 586 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext); 587 588 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI. 589 if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() && 590 M->getPICLevel() == PICLevel::BigPIC) 591 TlsRef = MCBinaryExpr::createAdd( 592 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext); 593 const MachineOperand &MO = MI->getOperand(2); 594 const GlobalValue *GValue = MO.getGlobal(); 595 MCSymbol *MOSymbol = getSymbol(GValue); 596 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 597 EmitToStreamer(*OutStreamer, 598 MCInstBuilder(Subtarget->isPPC64() ? Opcode 599 : (unsigned)PPC::BL_TLS) 600 .addExpr(TlsRef) 601 .addExpr(SymVar)); 602 } 603 604 /// Map a machine operand for a TOC pseudo-machine instruction to its 605 /// corresponding MCSymbol. 606 static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO, 607 AsmPrinter &AP) { 608 switch (MO.getType()) { 609 case MachineOperand::MO_GlobalAddress: 610 return AP.getSymbol(MO.getGlobal()); 611 case MachineOperand::MO_ConstantPoolIndex: 612 return AP.GetCPISymbol(MO.getIndex()); 613 case MachineOperand::MO_JumpTableIndex: 614 return AP.GetJTISymbol(MO.getIndex()); 615 case MachineOperand::MO_BlockAddress: 616 return AP.GetBlockAddressSymbol(MO.getBlockAddress()); 617 default: 618 llvm_unreachable("Unexpected operand type to get symbol."); 619 } 620 } 621 622 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 623 /// the current output stream. 624 /// 625 void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { 626 MCInst TmpInst; 627 const bool IsPPC64 = Subtarget->isPPC64(); 628 const bool IsAIX = Subtarget->isAIXABI(); 629 const Module *M = MF->getFunction().getParent(); 630 PICLevel::Level PL = M->getPICLevel(); 631 632 #ifndef NDEBUG 633 // Validate that SPE and FPU are mutually exclusive in codegen 634 if (!MI->isInlineAsm()) { 635 for (const MachineOperand &MO: MI->operands()) { 636 if (MO.isReg()) { 637 Register Reg = MO.getReg(); 638 if (Subtarget->hasSPE()) { 639 if (PPC::F4RCRegClass.contains(Reg) || 640 PPC::F8RCRegClass.contains(Reg) || 641 PPC::VFRCRegClass.contains(Reg) || 642 PPC::VRRCRegClass.contains(Reg) || 643 PPC::VSFRCRegClass.contains(Reg) || 644 PPC::VSSRCRegClass.contains(Reg) 645 ) 646 llvm_unreachable("SPE targets cannot have FPRegs!"); 647 } else { 648 if (PPC::SPERCRegClass.contains(Reg)) 649 llvm_unreachable("SPE register found in FPU-targeted code!"); 650 } 651 } 652 } 653 } 654 #endif 655 656 auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr, 657 ptrdiff_t OriginalOffset) { 658 // Apply an offset to the TOC-based expression such that the adjusted 659 // notional offset from the TOC base (to be encoded into the instruction's D 660 // or DS field) is the signed 16-bit truncation of the original notional 661 // offset from the TOC base. 662 // This is consistent with the treatment used both by XL C/C++ and 663 // by AIX ld -r. 664 ptrdiff_t Adjustment = 665 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset); 666 return MCBinaryExpr::createAdd( 667 Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext); 668 }; 669 670 auto getTOCEntryLoadingExprForXCOFF = 671 [IsPPC64, getTOCRelocAdjustedExprForXCOFF, 672 this](const MCSymbol *MOSymbol, const MCExpr *Expr, 673 MCSymbolRefExpr::VariantKind VK = 674 MCSymbolRefExpr::VariantKind::VK_None) -> const MCExpr * { 675 const unsigned EntryByteSize = IsPPC64 ? 8 : 4; 676 const auto TOCEntryIter = TOC.find({MOSymbol, VK}); 677 assert(TOCEntryIter != TOC.end() && 678 "Could not find the TOC entry for this symbol."); 679 const ptrdiff_t EntryDistanceFromTOCBase = 680 (TOCEntryIter - TOC.begin()) * EntryByteSize; 681 constexpr int16_t PositiveTOCRange = INT16_MAX; 682 683 if (EntryDistanceFromTOCBase > PositiveTOCRange) 684 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase); 685 686 return Expr; 687 }; 688 auto GetVKForMO = [&](const MachineOperand &MO) { 689 // For GD TLS access on AIX, we have two TOC entries for the symbol (one for 690 // the variable offset and the other for the region handle). They are 691 // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG. 692 if (MO.getTargetFlags() & PPCII::MO_TLSGDM_FLAG) 693 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM; 694 if (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG) 695 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD; 696 return MCSymbolRefExpr::VariantKind::VK_None; 697 }; 698 699 // Lower multi-instruction pseudo operations. 700 switch (MI->getOpcode()) { 701 default: break; 702 case TargetOpcode::DBG_VALUE: 703 llvm_unreachable("Should be handled target independently"); 704 case TargetOpcode::STACKMAP: 705 return LowerSTACKMAP(SM, *MI); 706 case TargetOpcode::PATCHPOINT: 707 return LowerPATCHPOINT(SM, *MI); 708 709 case PPC::MoveGOTtoLR: { 710 // Transform %lr = MoveGOTtoLR 711 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 712 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding 713 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction: 714 // blrl 715 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local 716 MCSymbol *GOTSymbol = 717 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 718 const MCExpr *OffsExpr = 719 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, 720 MCSymbolRefExpr::VK_PPC_LOCAL, 721 OutContext), 722 MCConstantExpr::create(4, OutContext), 723 OutContext); 724 725 // Emit the 'bl'. 726 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); 727 return; 728 } 729 case PPC::MovePCtoLR: 730 case PPC::MovePCtoLR8: { 731 // Transform %lr = MovePCtoLR 732 // Into this, where the label is the PIC base: 733 // bl L1$pb 734 // L1$pb: 735 MCSymbol *PICBase = MF->getPICBaseSymbol(); 736 737 // Emit the 'bl'. 738 EmitToStreamer(*OutStreamer, 739 MCInstBuilder(PPC::BL) 740 // FIXME: We would like an efficient form for this, so we 741 // don't have to do a lot of extra uniquing. 742 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext))); 743 744 // Emit the label. 745 OutStreamer->emitLabel(PICBase); 746 return; 747 } 748 case PPC::UpdateGBR: { 749 // Transform %rd = UpdateGBR(%rt, %ri) 750 // Into: lwz %rt, .L0$poff - .L0$pb(%ri) 751 // add %rd, %rt, %ri 752 // or into (if secure plt mode is on): 753 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha 754 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l 755 // Get the offset from the GOT Base Register to the GOT 756 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 757 if (Subtarget->isSecurePlt() && isPositionIndependent() ) { 758 unsigned PICR = TmpInst.getOperand(0).getReg(); 759 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol( 760 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_" 761 : ".LTOC"); 762 const MCExpr *PB = 763 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext); 764 765 const MCExpr *DeltaExpr = MCBinaryExpr::createSub( 766 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext); 767 768 const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, OutContext); 769 EmitToStreamer( 770 *OutStreamer, 771 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi)); 772 773 const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, OutContext); 774 EmitToStreamer( 775 *OutStreamer, 776 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo)); 777 return; 778 } else { 779 MCSymbol *PICOffset = 780 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF); 781 TmpInst.setOpcode(PPC::LWZ); 782 const MCExpr *Exp = 783 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext); 784 const MCExpr *PB = 785 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), 786 MCSymbolRefExpr::VK_None, 787 OutContext); 788 const MCOperand TR = TmpInst.getOperand(1); 789 const MCOperand PICR = TmpInst.getOperand(0); 790 791 // Step 1: lwz %rt, .L$poff - .L$pb(%ri) 792 TmpInst.getOperand(1) = 793 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext)); 794 TmpInst.getOperand(0) = TR; 795 TmpInst.getOperand(2) = PICR; 796 EmitToStreamer(*OutStreamer, TmpInst); 797 798 TmpInst.setOpcode(PPC::ADD4); 799 TmpInst.getOperand(0) = PICR; 800 TmpInst.getOperand(1) = TR; 801 TmpInst.getOperand(2) = PICR; 802 EmitToStreamer(*OutStreamer, TmpInst); 803 return; 804 } 805 } 806 case PPC::LWZtoc: { 807 // Transform %rN = LWZtoc @op1, %r2 808 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 809 810 // Change the opcode to LWZ. 811 TmpInst.setOpcode(PPC::LWZ); 812 813 const MachineOperand &MO = MI->getOperand(1); 814 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 815 "Invalid operand for LWZtoc."); 816 817 // Map the operand to its corresponding MCSymbol. 818 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 819 820 // Create a reference to the GOT entry for the symbol. The GOT entry will be 821 // synthesized later. 822 if (PL == PICLevel::SmallPIC && !IsAIX) { 823 const MCExpr *Exp = 824 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT, 825 OutContext); 826 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 827 EmitToStreamer(*OutStreamer, TmpInst); 828 return; 829 } 830 831 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 832 833 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the 834 // storage allocated in the TOC which contains the address of 835 // 'MOSymbol'. Said TOC entry will be synthesized later. 836 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK); 837 const MCExpr *Exp = 838 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext); 839 840 // AIX uses the label directly as the lwz displacement operand for 841 // references into the toc section. The displacement value will be generated 842 // relative to the toc-base. 843 if (IsAIX) { 844 assert( 845 TM.getCodeModel() == CodeModel::Small && 846 "This pseudo should only be selected for 32-bit small code model."); 847 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK); 848 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 849 850 // Print MO for better readability 851 if (isVerbose()) 852 OutStreamer->GetCommentOS() << MO << '\n'; 853 EmitToStreamer(*OutStreamer, TmpInst); 854 return; 855 } 856 857 // Create an explicit subtract expression between the local symbol and 858 // '.LTOC' to manifest the toc-relative offset. 859 const MCExpr *PB = MCSymbolRefExpr::create( 860 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext); 861 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext); 862 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 863 EmitToStreamer(*OutStreamer, TmpInst); 864 return; 865 } 866 case PPC::ADDItoc: { 867 assert(IsAIX && TM.getCodeModel() == CodeModel::Small && 868 "Operand only valid in AIX 32 bit mode"); 869 870 // Transform %rN = ADDItoc @op1, %r2. 871 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 872 873 // Change the opcode to load address. 874 TmpInst.setOpcode(PPC::LA); 875 876 const MachineOperand &MO = MI->getOperand(1); 877 assert(MO.isGlobal() && "Invalid operand for ADDItoc."); 878 879 // Map the operand to its corresponding MCSymbol. 880 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 881 882 const MCExpr *Exp = 883 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_None, OutContext); 884 885 TmpInst.getOperand(1) = TmpInst.getOperand(2); 886 TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 887 EmitToStreamer(*OutStreamer, TmpInst); 888 return; 889 } 890 case PPC::LDtocJTI: 891 case PPC::LDtocCPT: 892 case PPC::LDtocBA: 893 case PPC::LDtoc: { 894 // Transform %x3 = LDtoc @min1, %x2 895 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 896 897 // Change the opcode to LD. 898 TmpInst.setOpcode(PPC::LD); 899 900 const MachineOperand &MO = MI->getOperand(1); 901 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 902 "Invalid operand!"); 903 904 // Map the operand to its corresponding MCSymbol. 905 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 906 907 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 908 909 // Map the machine operand to its corresponding MCSymbol, then map the 910 // global address operand to be a reference to the TOC entry we will 911 // synthesize later. 912 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK); 913 914 MCSymbolRefExpr::VariantKind VKExpr = 915 IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC; 916 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, VKExpr, OutContext); 917 TmpInst.getOperand(1) = MCOperand::createExpr( 918 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp); 919 920 // Print MO for better readability 921 if (isVerbose() && IsAIX) 922 OutStreamer->GetCommentOS() << MO << '\n'; 923 EmitToStreamer(*OutStreamer, TmpInst); 924 return; 925 } 926 case PPC::ADDIStocHA: { 927 assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && 928 "This pseudo should only be selected for 32-bit large code model on" 929 " AIX."); 930 931 // Transform %rd = ADDIStocHA %rA, @sym(%r2) 932 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 933 934 // Change the opcode to ADDIS. 935 TmpInst.setOpcode(PPC::ADDIS); 936 937 const MachineOperand &MO = MI->getOperand(2); 938 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 939 "Invalid operand for ADDIStocHA."); 940 941 // Map the machine operand to its corresponding MCSymbol. 942 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 943 944 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 945 946 // Always use TOC on AIX. Map the global address operand to be a reference 947 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to 948 // reference the storage allocated in the TOC which contains the address of 949 // 'MOSymbol'. 950 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK); 951 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, 952 MCSymbolRefExpr::VK_PPC_U, 953 OutContext); 954 TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 955 EmitToStreamer(*OutStreamer, TmpInst); 956 return; 957 } 958 case PPC::LWZtocL: { 959 assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && 960 "This pseudo should only be selected for 32-bit large code model on" 961 " AIX."); 962 963 // Transform %rd = LWZtocL @sym, %rs. 964 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 965 966 // Change the opcode to lwz. 967 TmpInst.setOpcode(PPC::LWZ); 968 969 const MachineOperand &MO = MI->getOperand(1); 970 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 971 "Invalid operand for LWZtocL."); 972 973 // Map the machine operand to its corresponding MCSymbol. 974 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 975 976 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 977 978 // Always use TOC on AIX. Map the global address operand to be a reference 979 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to 980 // reference the storage allocated in the TOC which contains the address of 981 // 'MOSymbol'. 982 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK); 983 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, 984 MCSymbolRefExpr::VK_PPC_L, 985 OutContext); 986 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 987 EmitToStreamer(*OutStreamer, TmpInst); 988 return; 989 } 990 case PPC::ADDIStocHA8: { 991 // Transform %xd = ADDIStocHA8 %x2, @sym 992 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 993 994 // Change the opcode to ADDIS8. If the global address is the address of 995 // an external symbol, is a jump table address, is a block address, or is a 996 // constant pool index with large code model enabled, then generate a TOC 997 // entry and reference that. Otherwise, reference the symbol directly. 998 TmpInst.setOpcode(PPC::ADDIS8); 999 1000 const MachineOperand &MO = MI->getOperand(2); 1001 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && 1002 "Invalid operand for ADDIStocHA8!"); 1003 1004 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 1005 1006 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 1007 1008 const bool GlobalToc = 1009 MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal()); 1010 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() || 1011 (MO.isCPI() && TM.getCodeModel() == CodeModel::Large)) 1012 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK); 1013 1014 VK = IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA; 1015 1016 const MCExpr *Exp = 1017 MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 1018 1019 if (!MO.isJTI() && MO.getOffset()) 1020 Exp = MCBinaryExpr::createAdd(Exp, 1021 MCConstantExpr::create(MO.getOffset(), 1022 OutContext), 1023 OutContext); 1024 1025 TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 1026 EmitToStreamer(*OutStreamer, TmpInst); 1027 return; 1028 } 1029 case PPC::LDtocL: { 1030 // Transform %xd = LDtocL @sym, %xs 1031 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 1032 1033 // Change the opcode to LD. If the global address is the address of 1034 // an external symbol, is a jump table address, is a block address, or is 1035 // a constant pool index with large code model enabled, then generate a 1036 // TOC entry and reference that. Otherwise, reference the symbol directly. 1037 TmpInst.setOpcode(PPC::LD); 1038 1039 const MachineOperand &MO = MI->getOperand(1); 1040 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || 1041 MO.isBlockAddress()) && 1042 "Invalid operand for LDtocL!"); 1043 1044 LLVM_DEBUG(assert( 1045 (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && 1046 "LDtocL used on symbol that could be accessed directly is " 1047 "invalid. Must match ADDIStocHA8.")); 1048 1049 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); 1050 1051 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO); 1052 1053 if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large) 1054 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK); 1055 1056 VK = IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO; 1057 const MCExpr *Exp = 1058 MCSymbolRefExpr::create(MOSymbol, VK, OutContext); 1059 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 1060 EmitToStreamer(*OutStreamer, TmpInst); 1061 return; 1062 } 1063 case PPC::ADDItocL: { 1064 // Transform %xd = ADDItocL %xs, @sym 1065 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 1066 1067 // Change the opcode to ADDI8. If the global address is external, then 1068 // generate a TOC entry and reference that. Otherwise, reference the 1069 // symbol directly. 1070 TmpInst.setOpcode(PPC::ADDI8); 1071 1072 const MachineOperand &MO = MI->getOperand(2); 1073 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL."); 1074 1075 LLVM_DEBUG(assert( 1076 !(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) && 1077 "Interposable definitions must use indirect access.")); 1078 1079 const MCExpr *Exp = 1080 MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO, *this), 1081 MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext); 1082 TmpInst.getOperand(2) = MCOperand::createExpr(Exp); 1083 EmitToStreamer(*OutStreamer, TmpInst); 1084 return; 1085 } 1086 case PPC::ADDISgotTprelHA: { 1087 // Transform: %xd = ADDISgotTprelHA %x2, @sym 1088 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 1089 assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 1090 const MachineOperand &MO = MI->getOperand(2); 1091 const GlobalValue *GValue = MO.getGlobal(); 1092 MCSymbol *MOSymbol = getSymbol(GValue); 1093 const MCExpr *SymGotTprel = 1094 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, 1095 OutContext); 1096 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 1097 .addReg(MI->getOperand(0).getReg()) 1098 .addReg(MI->getOperand(1).getReg()) 1099 .addExpr(SymGotTprel)); 1100 return; 1101 } 1102 case PPC::LDgotTprelL: 1103 case PPC::LDgotTprelL32: { 1104 // Transform %xd = LDgotTprelL @sym, %xs 1105 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 1106 1107 // Change the opcode to LD. 1108 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ); 1109 const MachineOperand &MO = MI->getOperand(1); 1110 const GlobalValue *GValue = MO.getGlobal(); 1111 MCSymbol *MOSymbol = getSymbol(GValue); 1112 const MCExpr *Exp = MCSymbolRefExpr::create( 1113 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO 1114 : MCSymbolRefExpr::VK_PPC_GOT_TPREL, 1115 OutContext); 1116 TmpInst.getOperand(1) = MCOperand::createExpr(Exp); 1117 EmitToStreamer(*OutStreamer, TmpInst); 1118 return; 1119 } 1120 1121 case PPC::PPC32PICGOT: { 1122 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 1123 MCSymbol *GOTRef = OutContext.createTempSymbol(); 1124 MCSymbol *NextInstr = OutContext.createTempSymbol(); 1125 1126 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL) 1127 // FIXME: We would like an efficient form for this, so we don't have to do 1128 // a lot of extra uniquing. 1129 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext))); 1130 const MCExpr *OffsExpr = 1131 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext), 1132 MCSymbolRefExpr::create(GOTRef, OutContext), 1133 OutContext); 1134 OutStreamer->emitLabel(GOTRef); 1135 OutStreamer->emitValue(OffsExpr, 4); 1136 OutStreamer->emitLabel(NextInstr); 1137 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR) 1138 .addReg(MI->getOperand(0).getReg())); 1139 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ) 1140 .addReg(MI->getOperand(1).getReg()) 1141 .addImm(0) 1142 .addReg(MI->getOperand(0).getReg())); 1143 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4) 1144 .addReg(MI->getOperand(0).getReg()) 1145 .addReg(MI->getOperand(1).getReg()) 1146 .addReg(MI->getOperand(0).getReg())); 1147 return; 1148 } 1149 case PPC::PPC32GOT: { 1150 MCSymbol *GOTSymbol = 1151 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); 1152 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create( 1153 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext); 1154 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create( 1155 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext); 1156 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI) 1157 .addReg(MI->getOperand(0).getReg()) 1158 .addExpr(SymGotTlsL)); 1159 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) 1160 .addReg(MI->getOperand(0).getReg()) 1161 .addReg(MI->getOperand(0).getReg()) 1162 .addExpr(SymGotTlsHA)); 1163 return; 1164 } 1165 case PPC::ADDIStlsgdHA: { 1166 // Transform: %xd = ADDIStlsgdHA %x2, @sym 1167 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 1168 assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 1169 const MachineOperand &MO = MI->getOperand(2); 1170 const GlobalValue *GValue = MO.getGlobal(); 1171 MCSymbol *MOSymbol = getSymbol(GValue); 1172 const MCExpr *SymGotTlsGD = 1173 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, 1174 OutContext); 1175 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 1176 .addReg(MI->getOperand(0).getReg()) 1177 .addReg(MI->getOperand(1).getReg()) 1178 .addExpr(SymGotTlsGD)); 1179 return; 1180 } 1181 case PPC::ADDItlsgdL: 1182 // Transform: %xd = ADDItlsgdL %xs, @sym 1183 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l 1184 case PPC::ADDItlsgdL32: { 1185 // Transform: %rd = ADDItlsgdL32 %rs, @sym 1186 // Into: %rd = ADDI %rs, sym@got@tlsgd 1187 const MachineOperand &MO = MI->getOperand(2); 1188 const GlobalValue *GValue = MO.getGlobal(); 1189 MCSymbol *MOSymbol = getSymbol(GValue); 1190 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create( 1191 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO 1192 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, 1193 OutContext); 1194 EmitToStreamer(*OutStreamer, 1195 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1196 .addReg(MI->getOperand(0).getReg()) 1197 .addReg(MI->getOperand(1).getReg()) 1198 .addExpr(SymGotTlsGD)); 1199 return; 1200 } 1201 case PPC::GETtlsADDR: 1202 // Transform: %x3 = GETtlsADDR %x3, @sym 1203 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) 1204 case PPC::GETtlsADDRPCREL: 1205 case PPC::GETtlsADDR32AIX: 1206 case PPC::GETtlsADDR64AIX: 1207 // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64). 1208 // Into: BLA .__tls_get_addr() 1209 // Unlike on Linux, there is no symbol or relocation needed for this call. 1210 case PPC::GETtlsADDR32: { 1211 // Transform: %r3 = GETtlsADDR32 %r3, @sym 1212 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT 1213 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD); 1214 return; 1215 } 1216 case PPC::ADDIStlsldHA: { 1217 // Transform: %xd = ADDIStlsldHA %x2, @sym 1218 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha 1219 assert(IsPPC64 && "Not supported for 32-bit PowerPC"); 1220 const MachineOperand &MO = MI->getOperand(2); 1221 const GlobalValue *GValue = MO.getGlobal(); 1222 MCSymbol *MOSymbol = getSymbol(GValue); 1223 const MCExpr *SymGotTlsLD = 1224 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, 1225 OutContext); 1226 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) 1227 .addReg(MI->getOperand(0).getReg()) 1228 .addReg(MI->getOperand(1).getReg()) 1229 .addExpr(SymGotTlsLD)); 1230 return; 1231 } 1232 case PPC::ADDItlsldL: 1233 // Transform: %xd = ADDItlsldL %xs, @sym 1234 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l 1235 case PPC::ADDItlsldL32: { 1236 // Transform: %rd = ADDItlsldL32 %rs, @sym 1237 // Into: %rd = ADDI %rs, sym@got@tlsld 1238 const MachineOperand &MO = MI->getOperand(2); 1239 const GlobalValue *GValue = MO.getGlobal(); 1240 MCSymbol *MOSymbol = getSymbol(GValue); 1241 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create( 1242 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO 1243 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, 1244 OutContext); 1245 EmitToStreamer(*OutStreamer, 1246 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1247 .addReg(MI->getOperand(0).getReg()) 1248 .addReg(MI->getOperand(1).getReg()) 1249 .addExpr(SymGotTlsLD)); 1250 return; 1251 } 1252 case PPC::GETtlsldADDR: 1253 // Transform: %x3 = GETtlsldADDR %x3, @sym 1254 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) 1255 case PPC::GETtlsldADDRPCREL: 1256 case PPC::GETtlsldADDR32: { 1257 // Transform: %r3 = GETtlsldADDR32 %r3, @sym 1258 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT 1259 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD); 1260 return; 1261 } 1262 case PPC::ADDISdtprelHA: 1263 // Transform: %xd = ADDISdtprelHA %xs, @sym 1264 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha 1265 case PPC::ADDISdtprelHA32: { 1266 // Transform: %rd = ADDISdtprelHA32 %rs, @sym 1267 // Into: %rd = ADDIS %rs, sym@dtprel@ha 1268 const MachineOperand &MO = MI->getOperand(2); 1269 const GlobalValue *GValue = MO.getGlobal(); 1270 MCSymbol *MOSymbol = getSymbol(GValue); 1271 const MCExpr *SymDtprel = 1272 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, 1273 OutContext); 1274 EmitToStreamer( 1275 *OutStreamer, 1276 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS) 1277 .addReg(MI->getOperand(0).getReg()) 1278 .addReg(MI->getOperand(1).getReg()) 1279 .addExpr(SymDtprel)); 1280 return; 1281 } 1282 case PPC::PADDIdtprel: { 1283 // Transform: %rd = PADDIdtprel %rs, @sym 1284 // Into: %rd = PADDI8 %rs, sym@dtprel 1285 const MachineOperand &MO = MI->getOperand(2); 1286 const GlobalValue *GValue = MO.getGlobal(); 1287 MCSymbol *MOSymbol = getSymbol(GValue); 1288 const MCExpr *SymDtprel = MCSymbolRefExpr::create( 1289 MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext); 1290 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8) 1291 .addReg(MI->getOperand(0).getReg()) 1292 .addReg(MI->getOperand(1).getReg()) 1293 .addExpr(SymDtprel)); 1294 return; 1295 } 1296 1297 case PPC::ADDIdtprelL: 1298 // Transform: %xd = ADDIdtprelL %xs, @sym 1299 // Into: %xd = ADDI8 %xs, sym@dtprel@l 1300 case PPC::ADDIdtprelL32: { 1301 // Transform: %rd = ADDIdtprelL32 %rs, @sym 1302 // Into: %rd = ADDI %rs, sym@dtprel@l 1303 const MachineOperand &MO = MI->getOperand(2); 1304 const GlobalValue *GValue = MO.getGlobal(); 1305 MCSymbol *MOSymbol = getSymbol(GValue); 1306 const MCExpr *SymDtprel = 1307 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, 1308 OutContext); 1309 EmitToStreamer(*OutStreamer, 1310 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI) 1311 .addReg(MI->getOperand(0).getReg()) 1312 .addReg(MI->getOperand(1).getReg()) 1313 .addExpr(SymDtprel)); 1314 return; 1315 } 1316 case PPC::MFOCRF: 1317 case PPC::MFOCRF8: 1318 if (!Subtarget->hasMFOCRF()) { 1319 // Transform: %r3 = MFOCRF %cr7 1320 // Into: %r3 = MFCR ;; cr7 1321 unsigned NewOpcode = 1322 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; 1323 OutStreamer->AddComment(PPCInstPrinter:: 1324 getRegisterName(MI->getOperand(1).getReg())); 1325 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) 1326 .addReg(MI->getOperand(0).getReg())); 1327 return; 1328 } 1329 break; 1330 case PPC::MTOCRF: 1331 case PPC::MTOCRF8: 1332 if (!Subtarget->hasMFOCRF()) { 1333 // Transform: %cr7 = MTOCRF %r3 1334 // Into: MTCRF mask, %r3 ;; cr7 1335 unsigned NewOpcode = 1336 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; 1337 unsigned Mask = 0x80 >> OutContext.getRegisterInfo() 1338 ->getEncodingValue(MI->getOperand(0).getReg()); 1339 OutStreamer->AddComment(PPCInstPrinter:: 1340 getRegisterName(MI->getOperand(0).getReg())); 1341 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) 1342 .addImm(Mask) 1343 .addReg(MI->getOperand(1).getReg())); 1344 return; 1345 } 1346 break; 1347 case PPC::LD: 1348 case PPC::STD: 1349 case PPC::LWA_32: 1350 case PPC::LWA: { 1351 // Verify alignment is legal, so we don't create relocations 1352 // that can't be supported. 1353 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; 1354 const MachineOperand &MO = MI->getOperand(OpNum); 1355 if (MO.isGlobal()) { 1356 const DataLayout &DL = MO.getGlobal()->getParent()->getDataLayout(); 1357 if (MO.getGlobal()->getPointerAlignment(DL) < 4) 1358 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!"); 1359 } 1360 // Now process the instruction normally. 1361 break; 1362 } 1363 } 1364 1365 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 1366 EmitToStreamer(*OutStreamer, TmpInst); 1367 } 1368 1369 void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) { 1370 if (!Subtarget->isPPC64()) 1371 return PPCAsmPrinter::emitInstruction(MI); 1372 1373 switch (MI->getOpcode()) { 1374 default: 1375 return PPCAsmPrinter::emitInstruction(MI); 1376 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: { 1377 // .begin: 1378 // b .end # lis 0, FuncId[16..32] 1379 // nop # li 0, FuncId[0..15] 1380 // std 0, -8(1) 1381 // mflr 0 1382 // bl __xray_FunctionEntry 1383 // mtlr 0 1384 // .end: 1385 // 1386 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1387 // of instructions change. 1388 MCSymbol *BeginOfSled = OutContext.createTempSymbol(); 1389 MCSymbol *EndOfSled = OutContext.createTempSymbol(); 1390 OutStreamer->emitLabel(BeginOfSled); 1391 EmitToStreamer(*OutStreamer, 1392 MCInstBuilder(PPC::B).addExpr( 1393 MCSymbolRefExpr::create(EndOfSled, OutContext))); 1394 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 1395 EmitToStreamer( 1396 *OutStreamer, 1397 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1)); 1398 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0)); 1399 EmitToStreamer(*OutStreamer, 1400 MCInstBuilder(PPC::BL8_NOP) 1401 .addExpr(MCSymbolRefExpr::create( 1402 OutContext.getOrCreateSymbol("__xray_FunctionEntry"), 1403 OutContext))); 1404 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0)); 1405 OutStreamer->emitLabel(EndOfSled); 1406 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2); 1407 break; 1408 } 1409 case TargetOpcode::PATCHABLE_RET: { 1410 unsigned RetOpcode = MI->getOperand(0).getImm(); 1411 MCInst RetInst; 1412 RetInst.setOpcode(RetOpcode); 1413 for (const auto &MO : llvm::drop_begin(MI->operands())) { 1414 MCOperand MCOp; 1415 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this)) 1416 RetInst.addOperand(MCOp); 1417 } 1418 1419 bool IsConditional; 1420 if (RetOpcode == PPC::BCCLR) { 1421 IsConditional = true; 1422 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 || 1423 RetOpcode == PPC::TCRETURNai8) { 1424 break; 1425 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) { 1426 IsConditional = false; 1427 } else { 1428 EmitToStreamer(*OutStreamer, RetInst); 1429 break; 1430 } 1431 1432 MCSymbol *FallthroughLabel; 1433 if (IsConditional) { 1434 // Before: 1435 // bgtlr cr0 1436 // 1437 // After: 1438 // ble cr0, .end 1439 // .p2align 3 1440 // .begin: 1441 // blr # lis 0, FuncId[16..32] 1442 // nop # li 0, FuncId[0..15] 1443 // std 0, -8(1) 1444 // mflr 0 1445 // bl __xray_FunctionExit 1446 // mtlr 0 1447 // blr 1448 // .end: 1449 // 1450 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1451 // of instructions change. 1452 FallthroughLabel = OutContext.createTempSymbol(); 1453 EmitToStreamer( 1454 *OutStreamer, 1455 MCInstBuilder(PPC::BCC) 1456 .addImm(PPC::InvertPredicate( 1457 static_cast<PPC::Predicate>(MI->getOperand(1).getImm()))) 1458 .addReg(MI->getOperand(2).getReg()) 1459 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext))); 1460 RetInst = MCInst(); 1461 RetInst.setOpcode(PPC::BLR8); 1462 } 1463 // .p2align 3 1464 // .begin: 1465 // b(lr)? # lis 0, FuncId[16..32] 1466 // nop # li 0, FuncId[0..15] 1467 // std 0, -8(1) 1468 // mflr 0 1469 // bl __xray_FunctionExit 1470 // mtlr 0 1471 // b(lr)? 1472 // 1473 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1474 // of instructions change. 1475 OutStreamer->emitCodeAlignment(8); 1476 MCSymbol *BeginOfSled = OutContext.createTempSymbol(); 1477 OutStreamer->emitLabel(BeginOfSled); 1478 EmitToStreamer(*OutStreamer, RetInst); 1479 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP)); 1480 EmitToStreamer( 1481 *OutStreamer, 1482 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1)); 1483 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0)); 1484 EmitToStreamer(*OutStreamer, 1485 MCInstBuilder(PPC::BL8_NOP) 1486 .addExpr(MCSymbolRefExpr::create( 1487 OutContext.getOrCreateSymbol("__xray_FunctionExit"), 1488 OutContext))); 1489 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0)); 1490 EmitToStreamer(*OutStreamer, RetInst); 1491 if (IsConditional) 1492 OutStreamer->emitLabel(FallthroughLabel); 1493 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2); 1494 break; 1495 } 1496 case TargetOpcode::PATCHABLE_FUNCTION_EXIT: 1497 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted"); 1498 case TargetOpcode::PATCHABLE_TAIL_CALL: 1499 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a 1500 // normal function exit from a tail exit. 1501 llvm_unreachable("Tail call is handled in the normal case. See comments " 1502 "around this assert."); 1503 } 1504 } 1505 1506 void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) { 1507 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) { 1508 PPCTargetStreamer *TS = 1509 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1510 1511 if (TS) 1512 TS->emitAbiVersion(2); 1513 } 1514 1515 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() || 1516 !isPositionIndependent()) 1517 return AsmPrinter::emitStartOfAsmFile(M); 1518 1519 if (M.getPICLevel() == PICLevel::SmallPIC) 1520 return AsmPrinter::emitStartOfAsmFile(M); 1521 1522 OutStreamer->SwitchSection(OutContext.getELFSection( 1523 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC)); 1524 1525 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC")); 1526 MCSymbol *CurrentPos = OutContext.createTempSymbol(); 1527 1528 OutStreamer->emitLabel(CurrentPos); 1529 1530 // The GOT pointer points to the middle of the GOT, in order to reference the 1531 // entire 64kB range. 0x8000 is the midpoint. 1532 const MCExpr *tocExpr = 1533 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext), 1534 MCConstantExpr::create(0x8000, OutContext), 1535 OutContext); 1536 1537 OutStreamer->emitAssignment(TOCSym, tocExpr); 1538 1539 OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); 1540 } 1541 1542 void PPCLinuxAsmPrinter::emitFunctionEntryLabel() { 1543 // linux/ppc32 - Normal entry label. 1544 if (!Subtarget->isPPC64() && 1545 (!isPositionIndependent() || 1546 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC)) 1547 return AsmPrinter::emitFunctionEntryLabel(); 1548 1549 if (!Subtarget->isPPC64()) { 1550 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1551 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) { 1552 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(*MF); 1553 MCSymbol *PICBase = MF->getPICBaseSymbol(); 1554 OutStreamer->emitLabel(RelocSymbol); 1555 1556 const MCExpr *OffsExpr = 1557 MCBinaryExpr::createSub( 1558 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")), 1559 OutContext), 1560 MCSymbolRefExpr::create(PICBase, OutContext), 1561 OutContext); 1562 OutStreamer->emitValue(OffsExpr, 4); 1563 OutStreamer->emitLabel(CurrentFnSym); 1564 return; 1565 } else 1566 return AsmPrinter::emitFunctionEntryLabel(); 1567 } 1568 1569 // ELFv2 ABI - Normal entry label. 1570 if (Subtarget->isELFv2ABI()) { 1571 // In the Large code model, we allow arbitrary displacements between 1572 // the text section and its associated TOC section. We place the 1573 // full 8-byte offset to the TOC in memory immediately preceding 1574 // the function global entry point. 1575 if (TM.getCodeModel() == CodeModel::Large 1576 && !MF->getRegInfo().use_empty(PPC::X2)) { 1577 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1578 1579 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1580 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol(*MF); 1581 const MCExpr *TOCDeltaExpr = 1582 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext), 1583 MCSymbolRefExpr::create(GlobalEPSymbol, 1584 OutContext), 1585 OutContext); 1586 1587 OutStreamer->emitLabel(PPCFI->getTOCOffsetSymbol(*MF)); 1588 OutStreamer->emitValue(TOCDeltaExpr, 8); 1589 } 1590 return AsmPrinter::emitFunctionEntryLabel(); 1591 } 1592 1593 // Emit an official procedure descriptor. 1594 MCSectionSubPair Current = OutStreamer->getCurrentSection(); 1595 MCSectionELF *Section = OutStreamer->getContext().getELFSection( 1596 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1597 OutStreamer->SwitchSection(Section); 1598 OutStreamer->emitLabel(CurrentFnSym); 1599 OutStreamer->emitValueToAlignment(8); 1600 MCSymbol *Symbol1 = CurrentFnSymForSize; 1601 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 1602 // entry point. 1603 OutStreamer->emitValue(MCSymbolRefExpr::create(Symbol1, OutContext), 1604 8 /*size*/); 1605 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1606 // Generates a R_PPC64_TOC relocation for TOC base insertion. 1607 OutStreamer->emitValue( 1608 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), 1609 8/*size*/); 1610 // Emit a null environment pointer. 1611 OutStreamer->emitIntValue(0, 8 /* size */); 1612 OutStreamer->SwitchSection(Current.first, Current.second); 1613 } 1614 1615 void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) { 1616 const DataLayout &DL = getDataLayout(); 1617 1618 bool isPPC64 = DL.getPointerSizeInBits() == 64; 1619 1620 PPCTargetStreamer *TS = 1621 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1622 1623 if (!TOC.empty()) { 1624 const char *Name = isPPC64 ? ".toc" : ".got2"; 1625 MCSectionELF *Section = OutContext.getELFSection( 1626 Name, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 1627 OutStreamer->SwitchSection(Section); 1628 if (!isPPC64) 1629 OutStreamer->emitValueToAlignment(4); 1630 1631 for (const auto &TOCMapPair : TOC) { 1632 const MCSymbol *const TOCEntryTarget = TOCMapPair.first.first; 1633 MCSymbol *const TOCEntryLabel = TOCMapPair.second; 1634 1635 OutStreamer->emitLabel(TOCEntryLabel); 1636 if (isPPC64 && TS != nullptr) 1637 TS->emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second); 1638 else 1639 OutStreamer->emitSymbolValue(TOCEntryTarget, 4); 1640 } 1641 } 1642 1643 PPCAsmPrinter::emitEndOfAsmFile(M); 1644 } 1645 1646 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 1647 void PPCLinuxAsmPrinter::emitFunctionBodyStart() { 1648 // In the ELFv2 ABI, in functions that use the TOC register, we need to 1649 // provide two entry points. The ABI guarantees that when calling the 1650 // local entry point, r2 is set up by the caller to contain the TOC base 1651 // for this function, and when calling the global entry point, r12 is set 1652 // up by the caller to hold the address of the global entry point. We 1653 // thus emit a prefix sequence along the following lines: 1654 // 1655 // func: 1656 // .Lfunc_gepNN: 1657 // # global entry point 1658 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha 1659 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l 1660 // .Lfunc_lepNN: 1661 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 1662 // # local entry point, followed by function body 1663 // 1664 // For the Large code model, we create 1665 // 1666 // .Lfunc_tocNN: 1667 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel 1668 // func: 1669 // .Lfunc_gepNN: 1670 // # global entry point 1671 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12) 1672 // add r2,r2,r12 1673 // .Lfunc_lepNN: 1674 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 1675 // # local entry point, followed by function body 1676 // 1677 // This ensures we have r2 set up correctly while executing the function 1678 // body, no matter which entry point is called. 1679 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); 1680 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) || 1681 !MF->getRegInfo().use_empty(PPC::R2); 1682 const bool PCrelGEPRequired = Subtarget->isUsingPCRelativeCalls() && 1683 UsesX2OrR2 && PPCFI->usesTOCBasePtr(); 1684 const bool NonPCrelGEPRequired = !Subtarget->isUsingPCRelativeCalls() && 1685 Subtarget->isELFv2ABI() && UsesX2OrR2; 1686 1687 // Only do all that if the function uses R2 as the TOC pointer 1688 // in the first place. We don't need the global entry point if the 1689 // function uses R2 as an allocatable register. 1690 if (NonPCrelGEPRequired || PCrelGEPRequired) { 1691 // Note: The logic here must be synchronized with the code in the 1692 // branch-selection pass which sets the offset of the first block in the 1693 // function. This matters because it affects the alignment. 1694 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol(*MF); 1695 OutStreamer->emitLabel(GlobalEntryLabel); 1696 const MCSymbolRefExpr *GlobalEntryLabelExp = 1697 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext); 1698 1699 if (TM.getCodeModel() != CodeModel::Large) { 1700 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC.")); 1701 const MCExpr *TOCDeltaExpr = 1702 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext), 1703 GlobalEntryLabelExp, OutContext); 1704 1705 const MCExpr *TOCDeltaHi = PPCMCExpr::createHa(TOCDeltaExpr, OutContext); 1706 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) 1707 .addReg(PPC::X2) 1708 .addReg(PPC::X12) 1709 .addExpr(TOCDeltaHi)); 1710 1711 const MCExpr *TOCDeltaLo = PPCMCExpr::createLo(TOCDeltaExpr, OutContext); 1712 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI) 1713 .addReg(PPC::X2) 1714 .addReg(PPC::X2) 1715 .addExpr(TOCDeltaLo)); 1716 } else { 1717 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol(*MF); 1718 const MCExpr *TOCOffsetDeltaExpr = 1719 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext), 1720 GlobalEntryLabelExp, OutContext); 1721 1722 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD) 1723 .addReg(PPC::X2) 1724 .addExpr(TOCOffsetDeltaExpr) 1725 .addReg(PPC::X12)); 1726 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8) 1727 .addReg(PPC::X2) 1728 .addReg(PPC::X2) 1729 .addReg(PPC::X12)); 1730 } 1731 1732 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol(*MF); 1733 OutStreamer->emitLabel(LocalEntryLabel); 1734 const MCSymbolRefExpr *LocalEntryLabelExp = 1735 MCSymbolRefExpr::create(LocalEntryLabel, OutContext); 1736 const MCExpr *LocalOffsetExp = 1737 MCBinaryExpr::createSub(LocalEntryLabelExp, 1738 GlobalEntryLabelExp, OutContext); 1739 1740 PPCTargetStreamer *TS = 1741 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1742 1743 if (TS) 1744 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp); 1745 } else if (Subtarget->isUsingPCRelativeCalls()) { 1746 // When generating the entry point for a function we have a few scenarios 1747 // based on whether or not that function uses R2 and whether or not that 1748 // function makes calls (or is a leaf function). 1749 // 1) A leaf function that does not use R2 (or treats it as callee-saved 1750 // and preserves it). In this case st_other=0 and both 1751 // the local and global entry points for the function are the same. 1752 // No special entry point code is required. 1753 // 2) A function uses the TOC pointer R2. This function may or may not have 1754 // calls. In this case st_other=[2,6] and the global and local entry 1755 // points are different. Code to correctly setup the TOC pointer in R2 1756 // is put between the global and local entry points. This case is 1757 // covered by the if statatement above. 1758 // 3) A function does not use the TOC pointer R2 but does have calls. 1759 // In this case st_other=1 since we do not know whether or not any 1760 // of the callees clobber R2. This case is dealt with in this else if 1761 // block. Tail calls are considered calls and the st_other should also 1762 // be set to 1 in that case as well. 1763 // 4) The function does not use the TOC pointer but R2 is used inside 1764 // the function. In this case st_other=1 once again. 1765 // 5) This function uses inline asm. We mark R2 as reserved if the function 1766 // has inline asm as we have to assume that it may be used. 1767 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() || 1768 MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) { 1769 PPCTargetStreamer *TS = 1770 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 1771 if (TS) 1772 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), 1773 MCConstantExpr::create(1, OutContext)); 1774 } 1775 } 1776 } 1777 1778 /// EmitFunctionBodyEnd - Print the traceback table before the .size 1779 /// directive. 1780 /// 1781 void PPCLinuxAsmPrinter::emitFunctionBodyEnd() { 1782 // Only the 64-bit target requires a traceback table. For now, 1783 // we only emit the word of zeroes that GDB requires to find 1784 // the end of the function, and zeroes for the eight-byte 1785 // mandatory fields. 1786 // FIXME: We should fill in the eight-byte mandatory fields as described in 1787 // the PPC64 ELF ABI (this is a low-priority item because GDB does not 1788 // currently make use of these fields). 1789 if (Subtarget->isPPC64()) { 1790 OutStreamer->emitIntValue(0, 4/*size*/); 1791 OutStreamer->emitIntValue(0, 8/*size*/); 1792 } 1793 } 1794 1795 void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV, 1796 MCSymbol *GVSym) const { 1797 1798 assert(MAI->hasVisibilityOnlyWithLinkage() && 1799 "AIX's linkage directives take a visibility setting."); 1800 1801 MCSymbolAttr LinkageAttr = MCSA_Invalid; 1802 switch (GV->getLinkage()) { 1803 case GlobalValue::ExternalLinkage: 1804 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global; 1805 break; 1806 case GlobalValue::LinkOnceAnyLinkage: 1807 case GlobalValue::LinkOnceODRLinkage: 1808 case GlobalValue::WeakAnyLinkage: 1809 case GlobalValue::WeakODRLinkage: 1810 case GlobalValue::ExternalWeakLinkage: 1811 LinkageAttr = MCSA_Weak; 1812 break; 1813 case GlobalValue::AvailableExternallyLinkage: 1814 LinkageAttr = MCSA_Extern; 1815 break; 1816 case GlobalValue::PrivateLinkage: 1817 return; 1818 case GlobalValue::InternalLinkage: 1819 assert(GV->getVisibility() == GlobalValue::DefaultVisibility && 1820 "InternalLinkage should not have other visibility setting."); 1821 LinkageAttr = MCSA_LGlobal; 1822 break; 1823 case GlobalValue::AppendingLinkage: 1824 llvm_unreachable("Should never emit this"); 1825 case GlobalValue::CommonLinkage: 1826 llvm_unreachable("CommonLinkage of XCOFF should not come to this path"); 1827 } 1828 1829 assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid."); 1830 1831 MCSymbolAttr VisibilityAttr = MCSA_Invalid; 1832 if (!TM.getIgnoreXCOFFVisibility()) { 1833 switch (GV->getVisibility()) { 1834 1835 // TODO: "exported" and "internal" Visibility needs to go here. 1836 case GlobalValue::DefaultVisibility: 1837 break; 1838 case GlobalValue::HiddenVisibility: 1839 VisibilityAttr = MAI->getHiddenVisibilityAttr(); 1840 break; 1841 case GlobalValue::ProtectedVisibility: 1842 VisibilityAttr = MAI->getProtectedVisibilityAttr(); 1843 break; 1844 } 1845 } 1846 1847 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr, 1848 VisibilityAttr); 1849 } 1850 1851 void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) { 1852 // Setup CurrentFnDescSym and its containing csect. 1853 MCSectionXCOFF *FnDescSec = 1854 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor( 1855 &MF.getFunction(), TM)); 1856 FnDescSec->setAlignment(Align(Subtarget->isPPC64() ? 8 : 4)); 1857 1858 CurrentFnDescSym = FnDescSec->getQualNameSymbol(); 1859 1860 return AsmPrinter::SetupMachineFunction(MF); 1861 } 1862 1863 void PPCAIXAsmPrinter::emitFunctionBodyEnd() { 1864 1865 if (!TM.getXCOFFTracebackTable()) 1866 return; 1867 1868 emitTracebackTable(); 1869 } 1870 1871 void PPCAIXAsmPrinter::emitTracebackTable() { 1872 1873 // Create a symbol for the end of function. 1874 MCSymbol *FuncEnd = createTempSymbol(MF->getName()); 1875 OutStreamer->emitLabel(FuncEnd); 1876 1877 OutStreamer->AddComment("Traceback table begin"); 1878 // Begin with a fullword of zero. 1879 OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/); 1880 1881 SmallString<128> CommentString; 1882 raw_svector_ostream CommentOS(CommentString); 1883 1884 auto EmitComment = [&]() { 1885 OutStreamer->AddComment(CommentOS.str()); 1886 CommentString.clear(); 1887 }; 1888 1889 auto EmitCommentAndValue = [&](uint64_t Value, int Size) { 1890 EmitComment(); 1891 OutStreamer->emitIntValueInHexWithPadding(Value, Size); 1892 }; 1893 1894 unsigned int Version = 0; 1895 CommentOS << "Version = " << Version; 1896 EmitCommentAndValue(Version, 1); 1897 1898 // There is a lack of information in the IR to assist with determining the 1899 // source language. AIX exception handling mechanism would only search for 1900 // personality routine and LSDA area when such language supports exception 1901 // handling. So to be conservatively correct and allow runtime to do its job, 1902 // we need to set it to C++ for now. 1903 TracebackTable::LanguageID LanguageIdentifier = 1904 TracebackTable::CPlusPlus; // C++ 1905 1906 CommentOS << "Language = " 1907 << getNameForTracebackTableLanguageId(LanguageIdentifier); 1908 EmitCommentAndValue(LanguageIdentifier, 1); 1909 1910 // This is only populated for the third and fourth bytes. 1911 uint32_t FirstHalfOfMandatoryField = 0; 1912 1913 // Emit the 3rd byte of the mandatory field. 1914 1915 // We always set traceback offset bit to true. 1916 FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask; 1917 1918 const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>(); 1919 const MachineRegisterInfo &MRI = MF->getRegInfo(); 1920 1921 // Check the function uses floating-point processor instructions or not 1922 for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) { 1923 if (MRI.isPhysRegUsed(Reg)) { 1924 FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask; 1925 break; 1926 } 1927 } 1928 1929 #define GENBOOLCOMMENT(Prefix, V, Field) \ 1930 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \ 1931 << #Field 1932 1933 #define GENVALUECOMMENT(PrefixAndName, V, Field) \ 1934 CommentOS << (PrefixAndName) << " = " \ 1935 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \ 1936 (TracebackTable::Field##Shift)) 1937 1938 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage); 1939 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue); 1940 EmitComment(); 1941 1942 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset); 1943 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure); 1944 EmitComment(); 1945 1946 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage); 1947 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless); 1948 EmitComment(); 1949 1950 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent); 1951 EmitComment(); 1952 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, 1953 IsFloatingPointOperationLogOrAbortEnabled); 1954 EmitComment(); 1955 1956 OutStreamer->emitIntValueInHexWithPadding( 1957 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1); 1958 1959 // Set the 4th byte of the mandatory field. 1960 FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask; 1961 1962 static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!"); 1963 if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31)) 1964 FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask; 1965 1966 const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs(); 1967 if (!MustSaveCRs.empty()) 1968 FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask; 1969 1970 if (FI->mustSaveLR()) 1971 FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask; 1972 1973 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler); 1974 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent); 1975 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed); 1976 EmitComment(); 1977 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField, 1978 OnConditionDirective); 1979 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved); 1980 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved); 1981 EmitComment(); 1982 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff), 1983 1); 1984 1985 // Set the 5th byte of mandatory field. 1986 uint32_t SecondHalfOfMandatoryField = 0; 1987 1988 // Always store back chain. 1989 SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask; 1990 1991 uint32_t FPRSaved = 0; 1992 for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) { 1993 if (MRI.isPhysRegModified(Reg)) { 1994 FPRSaved = PPC::F31 - Reg + 1; 1995 break; 1996 } 1997 } 1998 SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) & 1999 TracebackTable::FPRSavedMask; 2000 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored); 2001 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup); 2002 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved); 2003 EmitComment(); 2004 OutStreamer->emitIntValueInHexWithPadding( 2005 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1); 2006 2007 // Set the 6th byte of mandatory field. 2008 bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); 2009 if (ShouldEmitEHBlock) 2010 SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask; 2011 2012 uint32_t GPRSaved = 0; 2013 2014 // X13 is reserved under 64-bit environment. 2015 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13; 2016 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31; 2017 2018 for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) { 2019 if (MRI.isPhysRegModified(Reg)) { 2020 GPRSaved = GPREnd - Reg + 1; 2021 break; 2022 } 2023 } 2024 2025 SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) & 2026 TracebackTable::GPRSavedMask; 2027 2028 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasVectorInfo); 2029 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasExtensionTable); 2030 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved); 2031 EmitComment(); 2032 OutStreamer->emitIntValueInHexWithPadding( 2033 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1); 2034 2035 // Set the 7th byte of mandatory field. 2036 uint32_t NumberOfFixedPara = FI->getFixedParamNum(); 2037 SecondHalfOfMandatoryField |= 2038 (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) & 2039 TracebackTable::NumberOfFixedParmsMask; 2040 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField, 2041 NumberOfFixedParms); 2042 EmitComment(); 2043 OutStreamer->emitIntValueInHexWithPadding( 2044 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1); 2045 2046 // Set the 8th byte of mandatory field. 2047 2048 // Always set parameter on stack. 2049 SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask; 2050 2051 uint32_t NumberOfFPPara = FI->getFloatingPointParamNum(); 2052 SecondHalfOfMandatoryField |= 2053 (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) & 2054 TracebackTable::NumberOfFloatingPointParmsMask; 2055 2056 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField, 2057 NumberOfFloatingPointParms); 2058 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack); 2059 EmitComment(); 2060 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff, 2061 1); 2062 2063 // Generate the optional fields of traceback table. 2064 2065 // Parameter type. 2066 if (NumberOfFixedPara || NumberOfFPPara) { 2067 assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) == 2068 0 && 2069 "VectorInfo has not been implemented."); 2070 uint32_t ParaType = FI->getParameterType(); 2071 CommentOS << "Parameter type = " 2072 << XCOFF::parseParmsType(ParaType, 2073 NumberOfFixedPara + NumberOfFPPara); 2074 EmitComment(); 2075 OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType)); 2076 } 2077 2078 // Traceback table offset. 2079 OutStreamer->AddComment("Function size"); 2080 if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) { 2081 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol( 2082 &(MF->getFunction()), TM); 2083 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4); 2084 } 2085 2086 // Since we unset the Int_Handler. 2087 if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask) 2088 report_fatal_error("Hand_Mask not implement yet"); 2089 2090 if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask) 2091 report_fatal_error("Ctl_Info not implement yet"); 2092 2093 if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) { 2094 StringRef Name = MF->getName().substr(0, INT16_MAX); 2095 int16_t NameLength = Name.size(); 2096 CommentOS << "Function name len = " 2097 << static_cast<unsigned int>(NameLength); 2098 EmitCommentAndValue(NameLength, 2); 2099 OutStreamer->AddComment("Function Name"); 2100 OutStreamer->emitBytes(Name); 2101 } 2102 2103 if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) { 2104 uint8_t AllocReg = XCOFF::AllocRegNo; 2105 OutStreamer->AddComment("AllocaUsed"); 2106 OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg)); 2107 } 2108 2109 uint8_t ExtensionTableFlag = 0; 2110 if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) { 2111 if (ShouldEmitEHBlock) 2112 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO; 2113 2114 CommentOS << "ExtensionTableFlag = " 2115 << getExtendedTBTableFlagString(ExtensionTableFlag); 2116 EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag)); 2117 } 2118 2119 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) { 2120 auto &Ctx = OutStreamer->getContext(); 2121 MCSymbol *EHInfoSym = 2122 TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF); 2123 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym); 2124 const MCSymbol *TOCBaseSym = 2125 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) 2126 ->getQualNameSymbol(); 2127 const MCExpr *Exp = 2128 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), 2129 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); 2130 2131 const DataLayout &DL = getDataLayout(); 2132 OutStreamer->emitValueToAlignment(4); 2133 OutStreamer->AddComment("EHInfo Table"); 2134 OutStreamer->emitValue(Exp, DL.getPointerSize()); 2135 } 2136 2137 #undef GENBOOLCOMMENT 2138 #undef GENVALUECOMMENT 2139 } 2140 2141 static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) { 2142 return GV->hasAppendingLinkage() && 2143 StringSwitch<bool>(GV->getName()) 2144 // TODO: Linker could still eliminate the GV if we just skip 2145 // handling llvm.used array. Skipping them for now until we or the 2146 // AIX OS team come up with a good solution. 2147 .Case("llvm.used", true) 2148 // It's correct to just skip llvm.compiler.used array here. 2149 .Case("llvm.compiler.used", true) 2150 .Default(false); 2151 } 2152 2153 static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) { 2154 return StringSwitch<bool>(GV->getName()) 2155 .Cases("llvm.global_ctors", "llvm.global_dtors", true) 2156 .Default(false); 2157 } 2158 2159 void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { 2160 // Special LLVM global arrays have been handled at the initialization. 2161 if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV)) 2162 return; 2163 2164 // If the Global Variable has the toc-data attribute, it needs to be emitted 2165 // when we emit the .toc section. 2166 if (GV->hasAttribute("toc-data")) { 2167 TOCDataGlobalVars.push_back(GV); 2168 return; 2169 } 2170 2171 emitGlobalVariableHelper(GV); 2172 } 2173 2174 void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) { 2175 assert(!GV->getName().startswith("llvm.") && 2176 "Unhandled intrinsic global variable."); 2177 2178 if (GV->hasComdat()) 2179 report_fatal_error("COMDAT not yet supported by AIX."); 2180 2181 MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV)); 2182 2183 if (GV->isDeclarationForLinker()) { 2184 emitLinkage(GV, GVSym); 2185 return; 2186 } 2187 2188 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM); 2189 if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly() && 2190 !GVKind.isThreadLocal()) // Checks for both ThreadData and ThreadBSS. 2191 report_fatal_error("Encountered a global variable kind that is " 2192 "not supported yet."); 2193 2194 // Print GV in verbose mode 2195 if (isVerbose()) { 2196 if (GV->hasInitializer()) { 2197 GV->printAsOperand(OutStreamer->GetCommentOS(), 2198 /*PrintType=*/false, GV->getParent()); 2199 OutStreamer->GetCommentOS() << '\n'; 2200 } 2201 } 2202 2203 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>( 2204 getObjFileLowering().SectionForGlobal(GV, GVKind, TM)); 2205 2206 // Switch to the containing csect. 2207 OutStreamer->SwitchSection(Csect); 2208 2209 const DataLayout &DL = GV->getParent()->getDataLayout(); 2210 2211 // Handle common and zero-initialized local symbols. 2212 if (GV->hasCommonLinkage() || GVKind.isBSSLocal() || 2213 GVKind.isThreadBSSLocal()) { 2214 Align Alignment = GV->getAlign().getValueOr(DL.getPreferredAlign(GV)); 2215 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); 2216 GVSym->setStorageClass( 2217 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); 2218 2219 if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) 2220 OutStreamer->emitXCOFFLocalCommonSymbol( 2221 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size, 2222 GVSym, Alignment.value()); 2223 else 2224 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment.value()); 2225 return; 2226 } 2227 2228 MCSymbol *EmittedInitSym = GVSym; 2229 emitLinkage(GV, EmittedInitSym); 2230 emitAlignment(getGVAlignment(GV, DL), GV); 2231 2232 // When -fdata-sections is enabled, every GlobalVariable will 2233 // be put into its own csect; therefore, label is not necessary here. 2234 if (!TM.getDataSections() || GV->hasSection()) { 2235 OutStreamer->emitLabel(EmittedInitSym); 2236 } 2237 2238 // Emit aliasing label for global variable. 2239 llvm::for_each(GOAliasMap[GV], [this](const GlobalAlias *Alias) { 2240 OutStreamer->emitLabel(getSymbol(Alias)); 2241 }); 2242 2243 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer()); 2244 } 2245 2246 void PPCAIXAsmPrinter::emitFunctionDescriptor() { 2247 const DataLayout &DL = getDataLayout(); 2248 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4; 2249 2250 MCSectionSubPair Current = OutStreamer->getCurrentSection(); 2251 // Emit function descriptor. 2252 OutStreamer->SwitchSection( 2253 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect()); 2254 2255 // Emit aliasing label for function descriptor csect. 2256 llvm::for_each(GOAliasMap[&MF->getFunction()], 2257 [this](const GlobalAlias *Alias) { 2258 OutStreamer->emitLabel(getSymbol(Alias)); 2259 }); 2260 2261 // Emit function entry point address. 2262 OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext), 2263 PointerSize); 2264 // Emit TOC base address. 2265 const MCSymbol *TOCBaseSym = 2266 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) 2267 ->getQualNameSymbol(); 2268 OutStreamer->emitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext), 2269 PointerSize); 2270 // Emit a null environment pointer. 2271 OutStreamer->emitIntValue(0, PointerSize); 2272 2273 OutStreamer->SwitchSection(Current.first, Current.second); 2274 } 2275 2276 void PPCAIXAsmPrinter::emitFunctionEntryLabel() { 2277 // It's not necessary to emit the label when we have individual 2278 // function in its own csect. 2279 if (!TM.getFunctionSections()) 2280 PPCAsmPrinter::emitFunctionEntryLabel(); 2281 2282 // Emit aliasing label for function entry point label. 2283 llvm::for_each( 2284 GOAliasMap[&MF->getFunction()], [this](const GlobalAlias *Alias) { 2285 OutStreamer->emitLabel( 2286 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM)); 2287 }); 2288 } 2289 2290 void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) { 2291 // If there are no functions and there are no toc-data definitions in this 2292 // module, we will never need to reference the TOC base. 2293 if (M.empty() && TOCDataGlobalVars.empty()) 2294 return; 2295 2296 // Switch to section to emit TOC base. 2297 OutStreamer->SwitchSection(getObjFileLowering().getTOCBaseSection()); 2298 2299 PPCTargetStreamer *TS = 2300 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); 2301 2302 for (auto &I : TOC) { 2303 MCSectionXCOFF *TCEntry; 2304 // Setup the csect for the current TC entry. If the variant kind is 2305 // VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a 2306 // new symbol to prefix the name with a dot. 2307 if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) { 2308 SmallString<128> Name; 2309 StringRef Prefix = "."; 2310 Name += Prefix; 2311 Name += I.first.first->getName(); 2312 MCSymbol *S = OutContext.getOrCreateSymbol(Name); 2313 TCEntry = cast<MCSectionXCOFF>( 2314 getObjFileLowering().getSectionForTOCEntry(S, TM)); 2315 } else { 2316 TCEntry = cast<MCSectionXCOFF>( 2317 getObjFileLowering().getSectionForTOCEntry(I.first.first, TM)); 2318 } 2319 OutStreamer->SwitchSection(TCEntry); 2320 2321 OutStreamer->emitLabel(I.second); 2322 if (TS != nullptr) 2323 TS->emitTCEntry(*I.first.first, I.first.second); 2324 } 2325 2326 for (const auto *GV : TOCDataGlobalVars) 2327 emitGlobalVariableHelper(GV); 2328 } 2329 2330 bool PPCAIXAsmPrinter::doInitialization(Module &M) { 2331 const bool Result = PPCAsmPrinter::doInitialization(M); 2332 2333 auto setCsectAlignment = [this](const GlobalObject *GO) { 2334 // Declarations have 0 alignment which is set by default. 2335 if (GO->isDeclarationForLinker()) 2336 return; 2337 2338 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM); 2339 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>( 2340 getObjFileLowering().SectionForGlobal(GO, GOKind, TM)); 2341 2342 Align GOAlign = getGVAlignment(GO, GO->getParent()->getDataLayout()); 2343 if (GOAlign > Csect->getAlignment()) 2344 Csect->setAlignment(GOAlign); 2345 }; 2346 2347 // We need to know, up front, the alignment of csects for the assembly path, 2348 // because once a .csect directive gets emitted, we could not change the 2349 // alignment value on it. 2350 for (const auto &G : M.globals()) { 2351 if (isSpecialLLVMGlobalArrayToSkip(&G)) 2352 continue; 2353 2354 if (isSpecialLLVMGlobalArrayForStaticInit(&G)) { 2355 // Generate a format indicator and a unique module id to be a part of 2356 // the sinit and sterm function names. 2357 if (FormatIndicatorAndUniqueModId.empty()) { 2358 std::string UniqueModuleId = getUniqueModuleId(&M); 2359 if (UniqueModuleId != "") 2360 // TODO: Use source file full path to generate the unique module id 2361 // and add a format indicator as a part of function name in case we 2362 // will support more than one format. 2363 FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1); 2364 else 2365 // Use the Pid and current time as the unique module id when we cannot 2366 // generate one based on a module's strong external symbols. 2367 // FIXME: Adjust the comment accordingly after we use source file full 2368 // path instead. 2369 FormatIndicatorAndUniqueModId = 2370 "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) + 2371 "_" + llvm::itostr(time(nullptr)); 2372 } 2373 2374 emitSpecialLLVMGlobal(&G); 2375 continue; 2376 } 2377 2378 setCsectAlignment(&G); 2379 } 2380 2381 for (const auto &F : M) 2382 setCsectAlignment(&F); 2383 2384 // Construct an aliasing list for each GlobalObject. 2385 for (const auto &Alias : M.aliases()) { 2386 const GlobalObject *Base = Alias.getBaseObject(); 2387 if (!Base) 2388 report_fatal_error( 2389 "alias without a base object is not yet supported on AIX"); 2390 GOAliasMap[Base].push_back(&Alias); 2391 } 2392 2393 return Result; 2394 } 2395 2396 void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) { 2397 switch (MI->getOpcode()) { 2398 default: 2399 break; 2400 case PPC::GETtlsADDR64AIX: 2401 case PPC::GETtlsADDR32AIX: { 2402 // The reference to .__tls_get_addr is unknown to the assembler 2403 // so we need to emit an external symbol reference. 2404 MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext); 2405 ExtSymSDNodeSymbols.insert(TlsGetAddr); 2406 break; 2407 } 2408 case PPC::BL8: 2409 case PPC::BL: 2410 case PPC::BL8_NOP: 2411 case PPC::BL_NOP: { 2412 const MachineOperand &MO = MI->getOperand(0); 2413 if (MO.isSymbol()) { 2414 MCSymbolXCOFF *S = 2415 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName())); 2416 ExtSymSDNodeSymbols.insert(S); 2417 } 2418 } break; 2419 case PPC::BL_TLS: 2420 case PPC::BL8_TLS: 2421 case PPC::BL8_TLS_: 2422 case PPC::BL8_NOP_TLS: 2423 report_fatal_error("TLS call not yet implemented"); 2424 case PPC::TAILB: 2425 case PPC::TAILB8: 2426 case PPC::TAILBA: 2427 case PPC::TAILBA8: 2428 case PPC::TAILBCTR: 2429 case PPC::TAILBCTR8: 2430 if (MI->getOperand(0).isSymbol()) 2431 report_fatal_error("Tail call for extern symbol not yet supported."); 2432 break; 2433 } 2434 return PPCAsmPrinter::emitInstruction(MI); 2435 } 2436 2437 bool PPCAIXAsmPrinter::doFinalization(Module &M) { 2438 // Do streamer related finalization for DWARF. 2439 if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo()) 2440 OutStreamer->doFinalizationAtSectionEnd( 2441 OutStreamer->getContext().getObjectFileInfo()->getTextSection()); 2442 2443 for (MCSymbol *Sym : ExtSymSDNodeSymbols) 2444 OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern); 2445 return PPCAsmPrinter::doFinalization(M); 2446 } 2447 2448 static unsigned mapToSinitPriority(int P) { 2449 if (P < 0 || P > 65535) 2450 report_fatal_error("invalid init priority"); 2451 2452 if (P <= 20) 2453 return P; 2454 2455 if (P < 81) 2456 return 20 + (P - 20) * 16; 2457 2458 if (P <= 1124) 2459 return 1004 + (P - 81); 2460 2461 if (P < 64512) 2462 return 2047 + (P - 1124) * 33878; 2463 2464 return 2147482625u + (P - 64512); 2465 } 2466 2467 static std::string convertToSinitPriority(int Priority) { 2468 // This helper function converts clang init priority to values used in sinit 2469 // and sterm functions. 2470 // 2471 // The conversion strategies are: 2472 // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm 2473 // reserved priority range [0, 1023] by 2474 // - directly mapping the first 21 and the last 20 elements of the ranges 2475 // - linear interpolating the intermediate values with a step size of 16. 2476 // 2477 // We map the non reserved clang/gnu priority range of [101, 65535] into the 2478 // sinit/sterm priority range [1024, 2147483648] by: 2479 // - directly mapping the first and the last 1024 elements of the ranges 2480 // - linear interpolating the intermediate values with a step size of 33878. 2481 unsigned int P = mapToSinitPriority(Priority); 2482 2483 std::string PrioritySuffix; 2484 llvm::raw_string_ostream os(PrioritySuffix); 2485 os << llvm::format_hex_no_prefix(P, 8); 2486 os.flush(); 2487 return PrioritySuffix; 2488 } 2489 2490 void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL, 2491 const Constant *List, bool IsCtor) { 2492 SmallVector<Structor, 8> Structors; 2493 preprocessXXStructorList(DL, List, Structors); 2494 if (Structors.empty()) 2495 return; 2496 2497 unsigned Index = 0; 2498 for (Structor &S : Structors) { 2499 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func)) 2500 S.Func = CE->getOperand(0); 2501 2502 llvm::GlobalAlias::create( 2503 GlobalValue::ExternalLinkage, 2504 (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) + 2505 llvm::Twine(convertToSinitPriority(S.Priority)) + 2506 llvm::Twine("_", FormatIndicatorAndUniqueModId) + 2507 llvm::Twine("_", llvm::utostr(Index++)), 2508 cast<Function>(S.Func)); 2509 } 2510 } 2511 2512 void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV, 2513 unsigned Encoding) { 2514 if (GV) { 2515 MCSymbol *TypeInfoSym = TM.getSymbol(GV); 2516 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym); 2517 const MCSymbol *TOCBaseSym = 2518 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) 2519 ->getQualNameSymbol(); 2520 auto &Ctx = OutStreamer->getContext(); 2521 const MCExpr *Exp = 2522 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), 2523 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); 2524 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding)); 2525 } else 2526 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding)); 2527 } 2528 2529 // Return a pass that prints the PPC assembly code for a MachineFunction to the 2530 // given output stream. 2531 static AsmPrinter * 2532 createPPCAsmPrinterPass(TargetMachine &tm, 2533 std::unique_ptr<MCStreamer> &&Streamer) { 2534 if (tm.getTargetTriple().isOSAIX()) 2535 return new PPCAIXAsmPrinter(tm, std::move(Streamer)); 2536 2537 return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); 2538 } 2539 2540 // Force static initialization. 2541 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() { 2542 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(), 2543 createPPCAsmPrinterPass); 2544 TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(), 2545 createPPCAsmPrinterPass); 2546 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(), 2547 createPPCAsmPrinterPass); 2548 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(), 2549 createPPCAsmPrinterPass); 2550 } 2551