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