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