1 //===- SIInstrInfo.h - SI Instruction Info Interface ------------*- C++ -*-===// 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 /// \file 10 /// Interface definition for SIInstrInfo. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H 15 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H 16 17 #include "AMDGPUMIRFormatter.h" 18 #include "SIRegisterInfo.h" 19 #include "Utils/AMDGPUBaseInfo.h" 20 #include "llvm/ADT/SetVector.h" 21 #include "llvm/CodeGen/TargetInstrInfo.h" 22 #include "llvm/CodeGen/TargetSchedule.h" 23 24 #define GET_INSTRINFO_HEADER 25 #include "AMDGPUGenInstrInfo.inc" 26 27 namespace llvm { 28 29 class APInt; 30 class GCNSubtarget; 31 class LiveVariables; 32 class MachineDominatorTree; 33 class MachineRegisterInfo; 34 class RegScavenger; 35 class TargetRegisterClass; 36 class ScheduleHazardRecognizer; 37 38 class SIInstrInfo final : public AMDGPUGenInstrInfo { 39 private: 40 const SIRegisterInfo RI; 41 const GCNSubtarget &ST; 42 TargetSchedModel SchedModel; 43 mutable std::unique_ptr<AMDGPUMIRFormatter> Formatter; 44 45 // The inverse predicate should have the negative value. 46 enum BranchPredicate { 47 INVALID_BR = 0, 48 SCC_TRUE = 1, 49 SCC_FALSE = -1, 50 VCCNZ = 2, 51 VCCZ = -2, 52 EXECNZ = -3, 53 EXECZ = 3 54 }; 55 56 using SetVectorType = SmallSetVector<MachineInstr *, 32>; 57 58 static unsigned getBranchOpcode(BranchPredicate Cond); 59 static BranchPredicate getBranchPredicate(unsigned Opcode); 60 61 public: 62 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI, 63 MachineRegisterInfo &MRI, 64 MachineOperand &SuperReg, 65 const TargetRegisterClass *SuperRC, 66 unsigned SubIdx, 67 const TargetRegisterClass *SubRC) const; 68 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI, 69 MachineRegisterInfo &MRI, 70 MachineOperand &SuperReg, 71 const TargetRegisterClass *SuperRC, 72 unsigned SubIdx, 73 const TargetRegisterClass *SubRC) const; 74 private: 75 void swapOperands(MachineInstr &Inst) const; 76 77 std::pair<bool, MachineBasicBlock *> 78 moveScalarAddSub(SetVectorType &Worklist, MachineInstr &Inst, 79 MachineDominatorTree *MDT = nullptr) const; 80 81 void lowerSelect(SetVectorType &Worklist, MachineInstr &Inst, 82 MachineDominatorTree *MDT = nullptr) const; 83 84 void lowerScalarAbs(SetVectorType &Worklist, 85 MachineInstr &Inst) const; 86 87 void lowerScalarXnor(SetVectorType &Worklist, 88 MachineInstr &Inst) const; 89 90 void splitScalarNotBinop(SetVectorType &Worklist, 91 MachineInstr &Inst, 92 unsigned Opcode) const; 93 94 void splitScalarBinOpN2(SetVectorType &Worklist, 95 MachineInstr &Inst, 96 unsigned Opcode) const; 97 98 void splitScalar64BitUnaryOp(SetVectorType &Worklist, 99 MachineInstr &Inst, unsigned Opcode) const; 100 101 void splitScalar64BitAddSub(SetVectorType &Worklist, MachineInstr &Inst, 102 MachineDominatorTree *MDT = nullptr) const; 103 104 void splitScalar64BitBinaryOp(SetVectorType &Worklist, MachineInstr &Inst, 105 unsigned Opcode, 106 MachineDominatorTree *MDT = nullptr) const; 107 108 void splitScalar64BitXnor(SetVectorType &Worklist, MachineInstr &Inst, 109 MachineDominatorTree *MDT = nullptr) const; 110 111 void splitScalar64BitBCNT(SetVectorType &Worklist, 112 MachineInstr &Inst) const; 113 void splitScalar64BitBFE(SetVectorType &Worklist, 114 MachineInstr &Inst) const; 115 void movePackToVALU(SetVectorType &Worklist, 116 MachineRegisterInfo &MRI, 117 MachineInstr &Inst) const; 118 119 void addUsersToMoveToVALUWorklist(Register Reg, MachineRegisterInfo &MRI, 120 SetVectorType &Worklist) const; 121 122 void addSCCDefUsersToVALUWorklist(MachineOperand &Op, 123 MachineInstr &SCCDefInst, 124 SetVectorType &Worklist) const; 125 126 const TargetRegisterClass * 127 getDestEquivalentVGPRClass(const MachineInstr &Inst) const; 128 129 bool checkInstOffsetsDoNotOverlap(const MachineInstr &MIa, 130 const MachineInstr &MIb) const; 131 132 Register findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const; 133 134 protected: 135 bool swapSourceModifiers(MachineInstr &MI, 136 MachineOperand &Src0, unsigned Src0OpName, 137 MachineOperand &Src1, unsigned Src1OpName) const; 138 139 MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI, 140 unsigned OpIdx0, 141 unsigned OpIdx1) const override; 142 143 public: 144 enum TargetOperandFlags { 145 MO_MASK = 0xf, 146 147 MO_NONE = 0, 148 // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL. 149 MO_GOTPCREL = 1, 150 // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO. 151 MO_GOTPCREL32 = 2, 152 MO_GOTPCREL32_LO = 2, 153 // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI. 154 MO_GOTPCREL32_HI = 3, 155 // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO. 156 MO_REL32 = 4, 157 MO_REL32_LO = 4, 158 // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI. 159 MO_REL32_HI = 5, 160 161 MO_LONG_BRANCH_FORWARD = 6, 162 MO_LONG_BRANCH_BACKWARD = 7, 163 164 MO_ABS32_LO = 8, 165 MO_ABS32_HI = 9, 166 }; 167 168 explicit SIInstrInfo(const GCNSubtarget &ST); 169 170 const SIRegisterInfo &getRegisterInfo() const { 171 return RI; 172 } 173 174 bool isReallyTriviallyReMaterializable(const MachineInstr &MI, 175 AAResults *AA) const override; 176 177 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, 178 int64_t &Offset1, 179 int64_t &Offset2) const override; 180 181 bool getMemOperandsWithOffsetWidth( 182 const MachineInstr &LdSt, 183 SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset, 184 bool &OffsetIsScalable, unsigned &Width, 185 const TargetRegisterInfo *TRI) const final; 186 187 bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1, 188 ArrayRef<const MachineOperand *> BaseOps2, 189 unsigned NumLoads, unsigned NumBytes) const override; 190 191 bool shouldScheduleLoadsNear(SDNode *Load0, SDNode *Load1, int64_t Offset0, 192 int64_t Offset1, unsigned NumLoads) const override; 193 194 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 195 const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, 196 bool KillSrc) const override; 197 198 void materializeImmediate(MachineBasicBlock &MBB, 199 MachineBasicBlock::iterator MI, 200 const DebugLoc &DL, 201 unsigned DestReg, 202 int64_t Value) const; 203 204 const TargetRegisterClass *getPreferredSelectRegClass( 205 unsigned Size) const; 206 207 Register insertNE(MachineBasicBlock *MBB, 208 MachineBasicBlock::iterator I, const DebugLoc &DL, 209 Register SrcReg, int Value) const; 210 211 Register insertEQ(MachineBasicBlock *MBB, 212 MachineBasicBlock::iterator I, const DebugLoc &DL, 213 Register SrcReg, int Value) const; 214 215 void storeRegToStackSlot(MachineBasicBlock &MBB, 216 MachineBasicBlock::iterator MI, Register SrcReg, 217 bool isKill, int FrameIndex, 218 const TargetRegisterClass *RC, 219 const TargetRegisterInfo *TRI) const override; 220 221 void loadRegFromStackSlot(MachineBasicBlock &MBB, 222 MachineBasicBlock::iterator MI, Register DestReg, 223 int FrameIndex, const TargetRegisterClass *RC, 224 const TargetRegisterInfo *TRI) const override; 225 226 bool expandPostRAPseudo(MachineInstr &MI) const override; 227 228 // Splits a V_MOV_B64_DPP_PSEUDO opcode into a pair of v_mov_b32_dpp 229 // instructions. Returns a pair of generated instructions. 230 // Can split either post-RA with physical registers or pre-RA with 231 // virtual registers. In latter case IR needs to be in SSA form and 232 // and a REG_SEQUENCE is produced to define original register. 233 std::pair<MachineInstr*, MachineInstr*> 234 expandMovDPP64(MachineInstr &MI) const; 235 236 // Returns an opcode that can be used to move a value to a \p DstRC 237 // register. If there is no hardware instruction that can store to \p 238 // DstRC, then AMDGPU::COPY is returned. 239 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const; 240 241 const MCInstrDesc &getIndirectRegWriteMovRelPseudo(unsigned VecSize, 242 unsigned EltSize, 243 bool IsSGPR) const; 244 245 const MCInstrDesc &getIndirectGPRIDXPseudo(unsigned VecSize, 246 bool IsIndirectSrc) const; 247 LLVM_READONLY 248 int commuteOpcode(unsigned Opc) const; 249 250 LLVM_READONLY 251 inline int commuteOpcode(const MachineInstr &MI) const { 252 return commuteOpcode(MI.getOpcode()); 253 } 254 255 bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, 256 unsigned &SrcOpIdx2) const override; 257 258 bool findCommutedOpIndices(MCInstrDesc Desc, unsigned & SrcOpIdx0, 259 unsigned & SrcOpIdx1) const; 260 261 bool isBranchOffsetInRange(unsigned BranchOpc, 262 int64_t BrOffset) const override; 263 264 MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 265 266 unsigned insertIndirectBranch(MachineBasicBlock &MBB, 267 MachineBasicBlock &NewDestBB, 268 const DebugLoc &DL, 269 int64_t BrOffset, 270 RegScavenger *RS = nullptr) const override; 271 272 bool analyzeBranchImpl(MachineBasicBlock &MBB, 273 MachineBasicBlock::iterator I, 274 MachineBasicBlock *&TBB, 275 MachineBasicBlock *&FBB, 276 SmallVectorImpl<MachineOperand> &Cond, 277 bool AllowModify) const; 278 279 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 280 MachineBasicBlock *&FBB, 281 SmallVectorImpl<MachineOperand> &Cond, 282 bool AllowModify = false) const override; 283 284 unsigned removeBranch(MachineBasicBlock &MBB, 285 int *BytesRemoved = nullptr) const override; 286 287 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 288 MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 289 const DebugLoc &DL, 290 int *BytesAdded = nullptr) const override; 291 292 bool reverseBranchCondition( 293 SmallVectorImpl<MachineOperand> &Cond) const override; 294 295 bool canInsertSelect(const MachineBasicBlock &MBB, 296 ArrayRef<MachineOperand> Cond, Register DstReg, 297 Register TrueReg, Register FalseReg, int &CondCycles, 298 int &TrueCycles, int &FalseCycles) const override; 299 300 void insertSelect(MachineBasicBlock &MBB, 301 MachineBasicBlock::iterator I, const DebugLoc &DL, 302 Register DstReg, ArrayRef<MachineOperand> Cond, 303 Register TrueReg, Register FalseReg) const override; 304 305 void insertVectorSelect(MachineBasicBlock &MBB, 306 MachineBasicBlock::iterator I, const DebugLoc &DL, 307 Register DstReg, ArrayRef<MachineOperand> Cond, 308 Register TrueReg, Register FalseReg) const; 309 310 unsigned getAddressSpaceForPseudoSourceKind( 311 unsigned Kind) const override; 312 313 bool 314 areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, 315 const MachineInstr &MIb) const override; 316 317 bool isFoldableCopy(const MachineInstr &MI) const; 318 319 bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, 320 MachineRegisterInfo *MRI) const final; 321 322 unsigned getMachineCSELookAheadLimit() const override { return 500; } 323 324 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB, 325 MachineInstr &MI, 326 LiveVariables *LV) const override; 327 328 bool isSchedulingBoundary(const MachineInstr &MI, 329 const MachineBasicBlock *MBB, 330 const MachineFunction &MF) const override; 331 332 static bool isSALU(const MachineInstr &MI) { 333 return MI.getDesc().TSFlags & SIInstrFlags::SALU; 334 } 335 336 bool isSALU(uint16_t Opcode) const { 337 return get(Opcode).TSFlags & SIInstrFlags::SALU; 338 } 339 340 static bool isVALU(const MachineInstr &MI) { 341 return MI.getDesc().TSFlags & SIInstrFlags::VALU; 342 } 343 344 bool isVALU(uint16_t Opcode) const { 345 return get(Opcode).TSFlags & SIInstrFlags::VALU; 346 } 347 348 static bool isVMEM(const MachineInstr &MI) { 349 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI); 350 } 351 352 bool isVMEM(uint16_t Opcode) const { 353 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode); 354 } 355 356 static bool isSOP1(const MachineInstr &MI) { 357 return MI.getDesc().TSFlags & SIInstrFlags::SOP1; 358 } 359 360 bool isSOP1(uint16_t Opcode) const { 361 return get(Opcode).TSFlags & SIInstrFlags::SOP1; 362 } 363 364 static bool isSOP2(const MachineInstr &MI) { 365 return MI.getDesc().TSFlags & SIInstrFlags::SOP2; 366 } 367 368 bool isSOP2(uint16_t Opcode) const { 369 return get(Opcode).TSFlags & SIInstrFlags::SOP2; 370 } 371 372 static bool isSOPC(const MachineInstr &MI) { 373 return MI.getDesc().TSFlags & SIInstrFlags::SOPC; 374 } 375 376 bool isSOPC(uint16_t Opcode) const { 377 return get(Opcode).TSFlags & SIInstrFlags::SOPC; 378 } 379 380 static bool isSOPK(const MachineInstr &MI) { 381 return MI.getDesc().TSFlags & SIInstrFlags::SOPK; 382 } 383 384 bool isSOPK(uint16_t Opcode) const { 385 return get(Opcode).TSFlags & SIInstrFlags::SOPK; 386 } 387 388 static bool isSOPP(const MachineInstr &MI) { 389 return MI.getDesc().TSFlags & SIInstrFlags::SOPP; 390 } 391 392 bool isSOPP(uint16_t Opcode) const { 393 return get(Opcode).TSFlags & SIInstrFlags::SOPP; 394 } 395 396 static bool isPacked(const MachineInstr &MI) { 397 return MI.getDesc().TSFlags & SIInstrFlags::IsPacked; 398 } 399 400 bool isPacked(uint16_t Opcode) const { 401 return get(Opcode).TSFlags & SIInstrFlags::IsPacked; 402 } 403 404 static bool isVOP1(const MachineInstr &MI) { 405 return MI.getDesc().TSFlags & SIInstrFlags::VOP1; 406 } 407 408 bool isVOP1(uint16_t Opcode) const { 409 return get(Opcode).TSFlags & SIInstrFlags::VOP1; 410 } 411 412 static bool isVOP2(const MachineInstr &MI) { 413 return MI.getDesc().TSFlags & SIInstrFlags::VOP2; 414 } 415 416 bool isVOP2(uint16_t Opcode) const { 417 return get(Opcode).TSFlags & SIInstrFlags::VOP2; 418 } 419 420 static bool isVOP3(const MachineInstr &MI) { 421 return MI.getDesc().TSFlags & SIInstrFlags::VOP3; 422 } 423 424 bool isVOP3(uint16_t Opcode) const { 425 return get(Opcode).TSFlags & SIInstrFlags::VOP3; 426 } 427 428 static bool isSDWA(const MachineInstr &MI) { 429 return MI.getDesc().TSFlags & SIInstrFlags::SDWA; 430 } 431 432 bool isSDWA(uint16_t Opcode) const { 433 return get(Opcode).TSFlags & SIInstrFlags::SDWA; 434 } 435 436 static bool isVOPC(const MachineInstr &MI) { 437 return MI.getDesc().TSFlags & SIInstrFlags::VOPC; 438 } 439 440 bool isVOPC(uint16_t Opcode) const { 441 return get(Opcode).TSFlags & SIInstrFlags::VOPC; 442 } 443 444 static bool isMUBUF(const MachineInstr &MI) { 445 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF; 446 } 447 448 bool isMUBUF(uint16_t Opcode) const { 449 return get(Opcode).TSFlags & SIInstrFlags::MUBUF; 450 } 451 452 static bool isMTBUF(const MachineInstr &MI) { 453 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF; 454 } 455 456 bool isMTBUF(uint16_t Opcode) const { 457 return get(Opcode).TSFlags & SIInstrFlags::MTBUF; 458 } 459 460 static bool isSMRD(const MachineInstr &MI) { 461 return MI.getDesc().TSFlags & SIInstrFlags::SMRD; 462 } 463 464 bool isSMRD(uint16_t Opcode) const { 465 return get(Opcode).TSFlags & SIInstrFlags::SMRD; 466 } 467 468 bool isBufferSMRD(const MachineInstr &MI) const; 469 470 static bool isDS(const MachineInstr &MI) { 471 return MI.getDesc().TSFlags & SIInstrFlags::DS; 472 } 473 474 bool isDS(uint16_t Opcode) const { 475 return get(Opcode).TSFlags & SIInstrFlags::DS; 476 } 477 478 bool isAlwaysGDS(uint16_t Opcode) const; 479 480 static bool isMIMG(const MachineInstr &MI) { 481 return MI.getDesc().TSFlags & SIInstrFlags::MIMG; 482 } 483 484 bool isMIMG(uint16_t Opcode) const { 485 return get(Opcode).TSFlags & SIInstrFlags::MIMG; 486 } 487 488 static bool isGather4(const MachineInstr &MI) { 489 return MI.getDesc().TSFlags & SIInstrFlags::Gather4; 490 } 491 492 bool isGather4(uint16_t Opcode) const { 493 return get(Opcode).TSFlags & SIInstrFlags::Gather4; 494 } 495 496 static bool isFLAT(const MachineInstr &MI) { 497 return MI.getDesc().TSFlags & SIInstrFlags::FLAT; 498 } 499 500 // Is a FLAT encoded instruction which accesses a specific segment, 501 // i.e. global_* or scratch_*. 502 static bool isSegmentSpecificFLAT(const MachineInstr &MI) { 503 auto Flags = MI.getDesc().TSFlags; 504 return Flags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch); 505 } 506 507 bool isSegmentSpecificFLAT(uint16_t Opcode) const { 508 auto Flags = get(Opcode).TSFlags; 509 return Flags & (SIInstrFlags::IsFlatGlobal | SIInstrFlags::IsFlatScratch); 510 } 511 512 static bool isFLATGlobal(const MachineInstr &MI) { 513 return MI.getDesc().TSFlags & SIInstrFlags::IsFlatGlobal; 514 } 515 516 bool isFLATGlobal(uint16_t Opcode) const { 517 return get(Opcode).TSFlags & SIInstrFlags::IsFlatGlobal; 518 } 519 520 static bool isFLATScratch(const MachineInstr &MI) { 521 return MI.getDesc().TSFlags & SIInstrFlags::IsFlatScratch; 522 } 523 524 bool isFLATScratch(uint16_t Opcode) const { 525 return get(Opcode).TSFlags & SIInstrFlags::IsFlatScratch; 526 } 527 528 // Any FLAT encoded instruction, including global_* and scratch_*. 529 bool isFLAT(uint16_t Opcode) const { 530 return get(Opcode).TSFlags & SIInstrFlags::FLAT; 531 } 532 533 static bool isEXP(const MachineInstr &MI) { 534 return MI.getDesc().TSFlags & SIInstrFlags::EXP; 535 } 536 537 bool isEXP(uint16_t Opcode) const { 538 return get(Opcode).TSFlags & SIInstrFlags::EXP; 539 } 540 541 static bool isWQM(const MachineInstr &MI) { 542 return MI.getDesc().TSFlags & SIInstrFlags::WQM; 543 } 544 545 bool isWQM(uint16_t Opcode) const { 546 return get(Opcode).TSFlags & SIInstrFlags::WQM; 547 } 548 549 static bool isDisableWQM(const MachineInstr &MI) { 550 return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM; 551 } 552 553 bool isDisableWQM(uint16_t Opcode) const { 554 return get(Opcode).TSFlags & SIInstrFlags::DisableWQM; 555 } 556 557 static bool isVGPRSpill(const MachineInstr &MI) { 558 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill; 559 } 560 561 bool isVGPRSpill(uint16_t Opcode) const { 562 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill; 563 } 564 565 static bool isSGPRSpill(const MachineInstr &MI) { 566 return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill; 567 } 568 569 bool isSGPRSpill(uint16_t Opcode) const { 570 return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill; 571 } 572 573 static bool isDPP(const MachineInstr &MI) { 574 return MI.getDesc().TSFlags & SIInstrFlags::DPP; 575 } 576 577 bool isDPP(uint16_t Opcode) const { 578 return get(Opcode).TSFlags & SIInstrFlags::DPP; 579 } 580 581 static bool isTRANS(const MachineInstr &MI) { 582 return MI.getDesc().TSFlags & SIInstrFlags::TRANS; 583 } 584 585 bool isTRANS(uint16_t Opcode) const { 586 return get(Opcode).TSFlags & SIInstrFlags::TRANS; 587 } 588 589 static bool isVOP3P(const MachineInstr &MI) { 590 return MI.getDesc().TSFlags & SIInstrFlags::VOP3P; 591 } 592 593 bool isVOP3P(uint16_t Opcode) const { 594 return get(Opcode).TSFlags & SIInstrFlags::VOP3P; 595 } 596 597 static bool isVINTRP(const MachineInstr &MI) { 598 return MI.getDesc().TSFlags & SIInstrFlags::VINTRP; 599 } 600 601 bool isVINTRP(uint16_t Opcode) const { 602 return get(Opcode).TSFlags & SIInstrFlags::VINTRP; 603 } 604 605 static bool isMAI(const MachineInstr &MI) { 606 return MI.getDesc().TSFlags & SIInstrFlags::IsMAI; 607 } 608 609 bool isMAI(uint16_t Opcode) const { 610 return get(Opcode).TSFlags & SIInstrFlags::IsMAI; 611 } 612 613 static bool isDOT(const MachineInstr &MI) { 614 return MI.getDesc().TSFlags & SIInstrFlags::IsDOT; 615 } 616 617 bool isDOT(uint16_t Opcode) const { 618 return get(Opcode).TSFlags & SIInstrFlags::IsDOT; 619 } 620 621 static bool isScalarUnit(const MachineInstr &MI) { 622 return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD); 623 } 624 625 static bool usesVM_CNT(const MachineInstr &MI) { 626 return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT; 627 } 628 629 static bool usesLGKM_CNT(const MachineInstr &MI) { 630 return MI.getDesc().TSFlags & SIInstrFlags::LGKM_CNT; 631 } 632 633 static bool sopkIsZext(const MachineInstr &MI) { 634 return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT; 635 } 636 637 bool sopkIsZext(uint16_t Opcode) const { 638 return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT; 639 } 640 641 /// \returns true if this is an s_store_dword* instruction. This is more 642 /// specific than than isSMEM && mayStore. 643 static bool isScalarStore(const MachineInstr &MI) { 644 return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE; 645 } 646 647 bool isScalarStore(uint16_t Opcode) const { 648 return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE; 649 } 650 651 static bool isFixedSize(const MachineInstr &MI) { 652 return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE; 653 } 654 655 bool isFixedSize(uint16_t Opcode) const { 656 return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE; 657 } 658 659 static bool hasFPClamp(const MachineInstr &MI) { 660 return MI.getDesc().TSFlags & SIInstrFlags::FPClamp; 661 } 662 663 bool hasFPClamp(uint16_t Opcode) const { 664 return get(Opcode).TSFlags & SIInstrFlags::FPClamp; 665 } 666 667 static bool hasIntClamp(const MachineInstr &MI) { 668 return MI.getDesc().TSFlags & SIInstrFlags::IntClamp; 669 } 670 671 uint64_t getClampMask(const MachineInstr &MI) const { 672 const uint64_t ClampFlags = SIInstrFlags::FPClamp | 673 SIInstrFlags::IntClamp | 674 SIInstrFlags::ClampLo | 675 SIInstrFlags::ClampHi; 676 return MI.getDesc().TSFlags & ClampFlags; 677 } 678 679 static bool usesFPDPRounding(const MachineInstr &MI) { 680 return MI.getDesc().TSFlags & SIInstrFlags::FPDPRounding; 681 } 682 683 bool usesFPDPRounding(uint16_t Opcode) const { 684 return get(Opcode).TSFlags & SIInstrFlags::FPDPRounding; 685 } 686 687 static bool isFPAtomic(const MachineInstr &MI) { 688 return MI.getDesc().TSFlags & SIInstrFlags::FPAtomic; 689 } 690 691 bool isFPAtomic(uint16_t Opcode) const { 692 return get(Opcode).TSFlags & SIInstrFlags::FPAtomic; 693 } 694 695 bool isVGPRCopy(const MachineInstr &MI) const { 696 assert(MI.isCopy()); 697 Register Dest = MI.getOperand(0).getReg(); 698 const MachineFunction &MF = *MI.getParent()->getParent(); 699 const MachineRegisterInfo &MRI = MF.getRegInfo(); 700 return !RI.isSGPRReg(MRI, Dest); 701 } 702 703 bool hasVGPRUses(const MachineInstr &MI) const { 704 const MachineFunction &MF = *MI.getParent()->getParent(); 705 const MachineRegisterInfo &MRI = MF.getRegInfo(); 706 return llvm::any_of(MI.explicit_uses(), 707 [&MRI, this](const MachineOperand &MO) { 708 return MO.isReg() && RI.isVGPR(MRI, MO.getReg());}); 709 } 710 711 /// Return true if the instruction modifies the mode register.q 712 static bool modifiesModeRegister(const MachineInstr &MI); 713 714 /// Whether we must prevent this instruction from executing with EXEC = 0. 715 bool hasUnwantedEffectsWhenEXECEmpty(const MachineInstr &MI) const; 716 717 /// Returns true if the instruction could potentially depend on the value of 718 /// exec. If false, exec dependencies may safely be ignored. 719 bool mayReadEXEC(const MachineRegisterInfo &MRI, const MachineInstr &MI) const; 720 721 bool isInlineConstant(const APInt &Imm) const; 722 723 bool isInlineConstant(const APFloat &Imm) const { 724 return isInlineConstant(Imm.bitcastToAPInt()); 725 } 726 727 bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const; 728 729 bool isInlineConstant(const MachineOperand &MO, 730 const MCOperandInfo &OpInfo) const { 731 return isInlineConstant(MO, OpInfo.OperandType); 732 } 733 734 /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would 735 /// be an inline immediate. 736 bool isInlineConstant(const MachineInstr &MI, 737 const MachineOperand &UseMO, 738 const MachineOperand &DefMO) const { 739 assert(UseMO.getParent() == &MI); 740 int OpIdx = MI.getOperandNo(&UseMO); 741 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) { 742 return false; 743 } 744 745 return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]); 746 } 747 748 /// \p returns true if the operand \p OpIdx in \p MI is a valid inline 749 /// immediate. 750 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const { 751 const MachineOperand &MO = MI.getOperand(OpIdx); 752 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType); 753 } 754 755 bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx, 756 const MachineOperand &MO) const { 757 if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) 758 return false; 759 760 if (MI.isCopy()) { 761 unsigned Size = getOpSize(MI, OpIdx); 762 assert(Size == 8 || Size == 4); 763 764 uint8_t OpType = (Size == 8) ? 765 AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32; 766 return isInlineConstant(MO, OpType); 767 } 768 769 return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType); 770 } 771 772 bool isInlineConstant(const MachineOperand &MO) const { 773 const MachineInstr *Parent = MO.getParent(); 774 return isInlineConstant(*Parent, Parent->getOperandNo(&MO)); 775 } 776 777 bool isLiteralConstant(const MachineOperand &MO, 778 const MCOperandInfo &OpInfo) const { 779 return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType); 780 } 781 782 bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const { 783 const MachineOperand &MO = MI.getOperand(OpIdx); 784 return MO.isImm() && !isInlineConstant(MI, OpIdx); 785 } 786 787 // Returns true if this operand could potentially require a 32-bit literal 788 // operand, but not necessarily. A FrameIndex for example could resolve to an 789 // inline immediate value that will not require an additional 4-bytes; this 790 // assumes that it will. 791 bool isLiteralConstantLike(const MachineOperand &MO, 792 const MCOperandInfo &OpInfo) const; 793 794 bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo, 795 const MachineOperand &MO) const; 796 797 /// Return true if this 64-bit VALU instruction has a 32-bit encoding. 798 /// This function will return false if you pass it a 32-bit instruction. 799 bool hasVALU32BitEncoding(unsigned Opcode) const; 800 801 /// Returns true if this operand uses the constant bus. 802 bool usesConstantBus(const MachineRegisterInfo &MRI, 803 const MachineOperand &MO, 804 const MCOperandInfo &OpInfo) const; 805 806 /// Return true if this instruction has any modifiers. 807 /// e.g. src[012]_mod, omod, clamp. 808 bool hasModifiers(unsigned Opcode) const; 809 810 bool hasModifiersSet(const MachineInstr &MI, 811 unsigned OpName) const; 812 bool hasAnyModifiersSet(const MachineInstr &MI) const; 813 814 bool canShrink(const MachineInstr &MI, 815 const MachineRegisterInfo &MRI) const; 816 817 MachineInstr *buildShrunkInst(MachineInstr &MI, 818 unsigned NewOpcode) const; 819 820 bool verifyInstruction(const MachineInstr &MI, 821 StringRef &ErrInfo) const override; 822 823 unsigned getVALUOp(const MachineInstr &MI) const; 824 825 /// Return the correct register class for \p OpNo. For target-specific 826 /// instructions, this will return the register class that has been defined 827 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return 828 /// the register class of its machine operand. 829 /// to infer the correct register class base on the other operands. 830 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI, 831 unsigned OpNo) const; 832 833 /// Return the size in bytes of the operand OpNo on the given 834 // instruction opcode. 835 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const { 836 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo]; 837 838 if (OpInfo.RegClass == -1) { 839 // If this is an immediate operand, this must be a 32-bit literal. 840 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE); 841 return 4; 842 } 843 844 return RI.getRegSizeInBits(*RI.getRegClass(OpInfo.RegClass)) / 8; 845 } 846 847 /// This form should usually be preferred since it handles operands 848 /// with unknown register classes. 849 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const { 850 const MachineOperand &MO = MI.getOperand(OpNo); 851 if (MO.isReg()) { 852 if (unsigned SubReg = MO.getSubReg()) { 853 return RI.getSubRegIdxSize(SubReg) / 8; 854 } 855 } 856 return RI.getRegSizeInBits(*getOpRegClass(MI, OpNo)) / 8; 857 } 858 859 /// Legalize the \p OpIndex operand of this instruction by inserting 860 /// a MOV. For example: 861 /// ADD_I32_e32 VGPR0, 15 862 /// to 863 /// MOV VGPR1, 15 864 /// ADD_I32_e32 VGPR0, VGPR1 865 /// 866 /// If the operand being legalized is a register, then a COPY will be used 867 /// instead of MOV. 868 void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const; 869 870 /// Check if \p MO is a legal operand if it was the \p OpIdx Operand 871 /// for \p MI. 872 bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx, 873 const MachineOperand *MO = nullptr) const; 874 875 /// Check if \p MO would be a valid operand for the given operand 876 /// definition \p OpInfo. Note this does not attempt to validate constant bus 877 /// restrictions (e.g. literal constant usage). 878 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI, 879 const MCOperandInfo &OpInfo, 880 const MachineOperand &MO) const; 881 882 /// Check if \p MO (a register operand) is a legal register for the 883 /// given operand description. 884 bool isLegalRegOperand(const MachineRegisterInfo &MRI, 885 const MCOperandInfo &OpInfo, 886 const MachineOperand &MO) const; 887 888 /// Legalize operands in \p MI by either commuting it or inserting a 889 /// copy of src1. 890 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const; 891 892 /// Fix operands in \p MI to satisfy constant bus requirements. 893 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const; 894 895 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only 896 /// be used when it is know that the value in SrcReg is same across all 897 /// threads in the wave. 898 /// \returns The SGPR register that \p SrcReg was copied to. 899 Register readlaneVGPRToSGPR(Register SrcReg, MachineInstr &UseMI, 900 MachineRegisterInfo &MRI) const; 901 902 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const; 903 void legalizeOperandsFLAT(MachineRegisterInfo &MRI, MachineInstr &MI) const; 904 905 void legalizeGenericOperand(MachineBasicBlock &InsertMBB, 906 MachineBasicBlock::iterator I, 907 const TargetRegisterClass *DstRC, 908 MachineOperand &Op, MachineRegisterInfo &MRI, 909 const DebugLoc &DL) const; 910 911 /// Legalize all operands in this instruction. This function may create new 912 /// instructions and control-flow around \p MI. If present, \p MDT is 913 /// updated. 914 /// \returns A new basic block that contains \p MI if new blocks were created. 915 MachineBasicBlock * 916 legalizeOperands(MachineInstr &MI, MachineDominatorTree *MDT = nullptr) const; 917 918 /// Replace this instruction's opcode with the equivalent VALU 919 /// opcode. This function will also move the users of \p MI to the 920 /// VALU if necessary. If present, \p MDT is updated. 921 MachineBasicBlock *moveToVALU(MachineInstr &MI, 922 MachineDominatorTree *MDT = nullptr) const; 923 924 void insertNoop(MachineBasicBlock &MBB, 925 MachineBasicBlock::iterator MI) const override; 926 927 void insertNoops(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 928 unsigned Quantity) const override; 929 930 void insertReturn(MachineBasicBlock &MBB) const; 931 /// Return the number of wait states that result from executing this 932 /// instruction. 933 static unsigned getNumWaitStates(const MachineInstr &MI); 934 935 /// Returns the operand named \p Op. If \p MI does not have an 936 /// operand named \c Op, this function returns nullptr. 937 LLVM_READONLY 938 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const; 939 940 LLVM_READONLY 941 const MachineOperand *getNamedOperand(const MachineInstr &MI, 942 unsigned OpName) const { 943 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName); 944 } 945 946 /// Get required immediate operand 947 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const { 948 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName); 949 return MI.getOperand(Idx).getImm(); 950 } 951 952 uint64_t getDefaultRsrcDataFormat() const; 953 uint64_t getScratchRsrcWords23() const; 954 955 bool isLowLatencyInstruction(const MachineInstr &MI) const; 956 bool isHighLatencyDef(int Opc) const override; 957 958 /// Return the descriptor of the target-specific machine instruction 959 /// that corresponds to the specified pseudo or native opcode. 960 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const { 961 return get(pseudoToMCOpcode(Opcode)); 962 } 963 964 unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const; 965 unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const; 966 967 unsigned isLoadFromStackSlot(const MachineInstr &MI, 968 int &FrameIndex) const override; 969 unsigned isStoreToStackSlot(const MachineInstr &MI, 970 int &FrameIndex) const override; 971 972 unsigned getInstBundleSize(const MachineInstr &MI) const; 973 unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 974 975 bool mayAccessFlatAddressSpace(const MachineInstr &MI) const; 976 977 bool isNonUniformBranchInstr(MachineInstr &Instr) const; 978 979 void convertNonUniformIfRegion(MachineBasicBlock *IfEntry, 980 MachineBasicBlock *IfEnd) const; 981 982 void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry, 983 MachineBasicBlock *LoopEnd) const; 984 985 std::pair<unsigned, unsigned> 986 decomposeMachineOperandsTargetFlags(unsigned TF) const override; 987 988 ArrayRef<std::pair<int, const char *>> 989 getSerializableTargetIndices() const override; 990 991 ArrayRef<std::pair<unsigned, const char *>> 992 getSerializableDirectMachineOperandTargetFlags() const override; 993 994 ScheduleHazardRecognizer * 995 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, 996 const ScheduleDAG *DAG) const override; 997 998 ScheduleHazardRecognizer * 999 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override; 1000 1001 bool isBasicBlockPrologue(const MachineInstr &MI) const override; 1002 1003 MachineInstr *createPHIDestinationCopy(MachineBasicBlock &MBB, 1004 MachineBasicBlock::iterator InsPt, 1005 const DebugLoc &DL, Register Src, 1006 Register Dst) const override; 1007 1008 MachineInstr *createPHISourceCopy(MachineBasicBlock &MBB, 1009 MachineBasicBlock::iterator InsPt, 1010 const DebugLoc &DL, Register Src, 1011 unsigned SrcSubReg, 1012 Register Dst) const override; 1013 1014 bool isWave32() const; 1015 1016 /// Return a partially built integer add instruction without carry. 1017 /// Caller must add source operands. 1018 /// For pre-GFX9 it will generate unused carry destination operand. 1019 /// TODO: After GFX9 it should return a no-carry operation. 1020 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB, 1021 MachineBasicBlock::iterator I, 1022 const DebugLoc &DL, 1023 Register DestReg) const; 1024 1025 MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB, 1026 MachineBasicBlock::iterator I, 1027 const DebugLoc &DL, 1028 Register DestReg, 1029 RegScavenger &RS) const; 1030 1031 static bool isKillTerminator(unsigned Opcode); 1032 const MCInstrDesc &getKillTerminatorFromPseudo(unsigned Opcode) const; 1033 1034 static bool isLegalMUBUFImmOffset(unsigned Imm) { 1035 return isUInt<12>(Imm); 1036 } 1037 1038 /// Returns if \p Offset is legal for the subtarget as the offset to a FLAT 1039 /// encoded instruction. If \p Signed, this is for an instruction that 1040 /// interprets the offset as signed. 1041 bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace, 1042 bool Signed) const; 1043 1044 /// Split \p COffsetVal into {immediate offset field, remainder offset} 1045 /// values. 1046 std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal, 1047 unsigned AddrSpace, 1048 bool IsSigned) const; 1049 1050 /// \brief Return a target-specific opcode if Opcode is a pseudo instruction. 1051 /// Return -1 if the target-specific opcode for the pseudo instruction does 1052 /// not exist. If Opcode is not a pseudo instruction, this is identity. 1053 int pseudoToMCOpcode(int Opcode) const; 1054 1055 /// \brief Check if this instruction should only be used by assembler. 1056 /// Return true if this opcode should not be used by codegen. 1057 bool isAsmOnlyOpcode(int MCOp) const; 1058 1059 const TargetRegisterClass *getRegClass(const MCInstrDesc &TID, unsigned OpNum, 1060 const TargetRegisterInfo *TRI, 1061 const MachineFunction &MF) 1062 const override { 1063 if (OpNum >= TID.getNumOperands()) 1064 return nullptr; 1065 return RI.getRegClass(TID.OpInfo[OpNum].RegClass); 1066 } 1067 1068 void fixImplicitOperands(MachineInstr &MI) const; 1069 1070 MachineInstr *foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, 1071 ArrayRef<unsigned> Ops, 1072 MachineBasicBlock::iterator InsertPt, 1073 int FrameIndex, 1074 LiveIntervals *LIS = nullptr, 1075 VirtRegMap *VRM = nullptr) const override; 1076 1077 unsigned getInstrLatency(const InstrItineraryData *ItinData, 1078 const MachineInstr &MI, 1079 unsigned *PredCost = nullptr) const override; 1080 1081 const MIRFormatter *getMIRFormatter() const override { 1082 if (!Formatter.get()) 1083 Formatter = std::make_unique<AMDGPUMIRFormatter>(); 1084 return Formatter.get(); 1085 } 1086 1087 static unsigned getDSShaderTypeValue(const MachineFunction &MF); 1088 }; 1089 1090 /// \brief Returns true if a reg:subreg pair P has a TRC class 1091 inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P, 1092 const TargetRegisterClass &TRC, 1093 MachineRegisterInfo &MRI) { 1094 auto *RC = MRI.getRegClass(P.Reg); 1095 if (!P.SubReg) 1096 return RC == &TRC; 1097 auto *TRI = MRI.getTargetRegisterInfo(); 1098 return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg); 1099 } 1100 1101 /// \brief Create RegSubRegPair from a register MachineOperand 1102 inline 1103 TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O) { 1104 assert(O.isReg()); 1105 return TargetInstrInfo::RegSubRegPair(O.getReg(), O.getSubReg()); 1106 } 1107 1108 /// \brief Return the SubReg component from REG_SEQUENCE 1109 TargetInstrInfo::RegSubRegPair getRegSequenceSubReg(MachineInstr &MI, 1110 unsigned SubReg); 1111 1112 /// \brief Return the defining instruction for a given reg:subreg pair 1113 /// skipping copy like instructions and subreg-manipulation pseudos. 1114 /// Following another subreg of a reg:subreg isn't supported. 1115 MachineInstr *getVRegSubRegDef(const TargetInstrInfo::RegSubRegPair &P, 1116 MachineRegisterInfo &MRI); 1117 1118 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p 1119 /// DefMI and the use at \p UseMI. Should be run on SSA. Currently does not 1120 /// attempt to track between blocks. 1121 bool execMayBeModifiedBeforeUse(const MachineRegisterInfo &MRI, 1122 Register VReg, 1123 const MachineInstr &DefMI, 1124 const MachineInstr &UseMI); 1125 1126 /// \brief Return false if EXEC is not changed between the def of \p VReg at \p 1127 /// DefMI and all its uses. Should be run on SSA. Currently does not attempt to 1128 /// track between blocks. 1129 bool execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI, 1130 Register VReg, 1131 const MachineInstr &DefMI); 1132 1133 namespace AMDGPU { 1134 1135 LLVM_READONLY 1136 int getVOPe64(uint16_t Opcode); 1137 1138 LLVM_READONLY 1139 int getVOPe32(uint16_t Opcode); 1140 1141 LLVM_READONLY 1142 int getSDWAOp(uint16_t Opcode); 1143 1144 LLVM_READONLY 1145 int getDPPOp32(uint16_t Opcode); 1146 1147 LLVM_READONLY 1148 int getBasicFromSDWAOp(uint16_t Opcode); 1149 1150 LLVM_READONLY 1151 int getCommuteRev(uint16_t Opcode); 1152 1153 LLVM_READONLY 1154 int getCommuteOrig(uint16_t Opcode); 1155 1156 LLVM_READONLY 1157 int getAddr64Inst(uint16_t Opcode); 1158 1159 /// Check if \p Opcode is an Addr64 opcode. 1160 /// 1161 /// \returns \p Opcode if it is an Addr64 opcode, otherwise -1. 1162 LLVM_READONLY 1163 int getIfAddr64Inst(uint16_t Opcode); 1164 1165 LLVM_READONLY 1166 int getMUBUFNoLdsInst(uint16_t Opcode); 1167 1168 LLVM_READONLY 1169 int getAtomicRetOp(uint16_t Opcode); 1170 1171 LLVM_READONLY 1172 int getAtomicNoRetOp(uint16_t Opcode); 1173 1174 LLVM_READONLY 1175 int getSOPKOp(uint16_t Opcode); 1176 1177 LLVM_READONLY 1178 int getGlobalSaddrOp(uint16_t Opcode); 1179 1180 LLVM_READONLY 1181 int getVCMPXNoSDstOp(uint16_t Opcode); 1182 1183 LLVM_READONLY 1184 int getFlatScratchInstSTfromSS(uint16_t Opcode); 1185 1186 LLVM_READONLY 1187 int getFlatScratchInstSSfromSV(uint16_t Opcode); 1188 1189 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL; 1190 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19); 1191 const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21); 1192 const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23); 1193 1194 } // end namespace AMDGPU 1195 1196 namespace SI { 1197 namespace KernelInputOffsets { 1198 1199 /// Offsets in bytes from the start of the input buffer 1200 enum Offsets { 1201 NGROUPS_X = 0, 1202 NGROUPS_Y = 4, 1203 NGROUPS_Z = 8, 1204 GLOBAL_SIZE_X = 12, 1205 GLOBAL_SIZE_Y = 16, 1206 GLOBAL_SIZE_Z = 20, 1207 LOCAL_SIZE_X = 24, 1208 LOCAL_SIZE_Y = 28, 1209 LOCAL_SIZE_Z = 32 1210 }; 1211 1212 } // end namespace KernelInputOffsets 1213 } // end namespace SI 1214 1215 } // end namespace llvm 1216 1217 #endif // LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H 1218