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