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