1 //===-- SIInstrInfo.h - SI Instruction Info Interface -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// \brief Interface definition for SIInstrInfo.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 
16 #ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17 #define LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
18 
19 #include "AMDGPUInstrInfo.h"
20 #include "SIDefines.h"
21 #include "SIRegisterInfo.h"
22 
23 namespace llvm {
24 
25 class SIInstrInfo final : public AMDGPUInstrInfo {
26 private:
27   const SIRegisterInfo RI;
28   const SISubtarget &ST;
29 
30   // The the inverse predicate should have the negative value.
31   enum BranchPredicate {
32     INVALID_BR = 0,
33     SCC_TRUE = 1,
34     SCC_FALSE = -1,
35     VCCNZ = 2,
36     VCCZ = -2,
37     EXECNZ = -3,
38     EXECZ = 3
39   };
40 
41   static unsigned getBranchOpcode(BranchPredicate Cond);
42   static BranchPredicate getBranchPredicate(unsigned Opcode);
43 
44   unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
45                               MachineRegisterInfo &MRI,
46                               MachineOperand &SuperReg,
47                               const TargetRegisterClass *SuperRC,
48                               unsigned SubIdx,
49                               const TargetRegisterClass *SubRC) const;
50   MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
51                                          MachineRegisterInfo &MRI,
52                                          MachineOperand &SuperReg,
53                                          const TargetRegisterClass *SuperRC,
54                                          unsigned SubIdx,
55                                          const TargetRegisterClass *SubRC) const;
56 
57   void swapOperands(MachineInstr &Inst) const;
58 
59   void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist,
60                       MachineInstr &Inst) const;
61 
62   void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
63                                MachineInstr &Inst, unsigned Opcode) const;
64 
65   void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
66                                 MachineInstr &Inst, unsigned Opcode) const;
67 
68   void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
69                             MachineInstr &Inst) const;
70   void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
71                            MachineInstr &Inst) const;
72   void movePackToVALU(SmallVectorImpl<MachineInstr *> &Worklist,
73                       MachineRegisterInfo &MRI,
74                       MachineInstr &Inst) const;
75 
76   void addUsersToMoveToVALUWorklist(
77     unsigned Reg, MachineRegisterInfo &MRI,
78     SmallVectorImpl<MachineInstr *> &Worklist) const;
79 
80   void
81   addSCCDefUsersToVALUWorklist(MachineInstr &SCCDefInst,
82                                SmallVectorImpl<MachineInstr *> &Worklist) const;
83 
84   const TargetRegisterClass *
85   getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
86 
87   bool checkInstOffsetsDoNotOverlap(MachineInstr &MIa, MachineInstr &MIb) const;
88 
89   unsigned findUsedSGPR(const MachineInstr &MI, int OpIndices[3]) const;
90 
91 protected:
92   bool swapSourceModifiers(MachineInstr &MI,
93                            MachineOperand &Src0, unsigned Src0OpName,
94                            MachineOperand &Src1, unsigned Src1OpName) const;
95 
96   MachineInstr *commuteInstructionImpl(MachineInstr &MI, bool NewMI,
97                                        unsigned OpIdx0,
98                                        unsigned OpIdx1) const override;
99 
100 public:
101 
102   enum TargetOperandFlags {
103     MO_NONE = 0,
104     // MO_GOTPCREL -> symbol@GOTPCREL -> R_AMDGPU_GOTPCREL.
105     MO_GOTPCREL = 1,
106     // MO_GOTPCREL32_LO -> symbol@gotpcrel32@lo -> R_AMDGPU_GOTPCREL32_LO.
107     MO_GOTPCREL32 = 2,
108     MO_GOTPCREL32_LO = 2,
109     // MO_GOTPCREL32_HI -> symbol@gotpcrel32@hi -> R_AMDGPU_GOTPCREL32_HI.
110     MO_GOTPCREL32_HI = 3,
111     // MO_REL32_LO -> symbol@rel32@lo -> R_AMDGPU_REL32_LO.
112     MO_REL32 = 4,
113     MO_REL32_LO = 4,
114     // MO_REL32_HI -> symbol@rel32@hi -> R_AMDGPU_REL32_HI.
115     MO_REL32_HI = 5
116   };
117 
118   explicit SIInstrInfo(const SISubtarget &);
119 
120   const SIRegisterInfo &getRegisterInfo() const {
121     return RI;
122   }
123 
124   bool isReallyTriviallyReMaterializable(const MachineInstr &MI,
125                                          AliasAnalysis *AA) const override;
126 
127   bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
128                                int64_t &Offset1,
129                                int64_t &Offset2) const override;
130 
131   bool getMemOpBaseRegImmOfs(MachineInstr &LdSt, unsigned &BaseReg,
132                              int64_t &Offset,
133                              const TargetRegisterInfo *TRI) const final;
134 
135   bool shouldClusterMemOps(MachineInstr &FirstLdSt, MachineInstr &SecondLdSt,
136                            unsigned NumLoads) const final;
137 
138   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
139                    const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
140                    bool KillSrc) const override;
141 
142   unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB, MachineInstr &MI,
143                                     RegScavenger *RS, unsigned TmpReg,
144                                     unsigned Offset, unsigned Size) const;
145 
146   void storeRegToStackSlot(MachineBasicBlock &MBB,
147                            MachineBasicBlock::iterator MI, unsigned SrcReg,
148                            bool isKill, int FrameIndex,
149                            const TargetRegisterClass *RC,
150                            const TargetRegisterInfo *TRI) const override;
151 
152   void loadRegFromStackSlot(MachineBasicBlock &MBB,
153                             MachineBasicBlock::iterator MI, unsigned DestReg,
154                             int FrameIndex, const TargetRegisterClass *RC,
155                             const TargetRegisterInfo *TRI) const override;
156 
157   bool expandPostRAPseudo(MachineInstr &MI) const override;
158 
159   // \brief Returns an opcode that can be used to move a value to a \p DstRC
160   // register.  If there is no hardware instruction that can store to \p
161   // DstRC, then AMDGPU::COPY is returned.
162   unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
163 
164   LLVM_READONLY
165   int commuteOpcode(unsigned Opc) const;
166 
167   LLVM_READONLY
168   inline int commuteOpcode(const MachineInstr &MI) const {
169     return commuteOpcode(MI.getOpcode());
170   }
171 
172   bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1,
173                              unsigned &SrcOpIdx2) const override;
174 
175   bool isBranchOffsetInRange(unsigned BranchOpc,
176                              int64_t BrOffset) const override;
177 
178   MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
179 
180   unsigned insertIndirectBranch(MachineBasicBlock &MBB,
181                                 MachineBasicBlock &NewDestBB,
182                                 const DebugLoc &DL,
183                                 int64_t BrOffset,
184                                 RegScavenger *RS = nullptr) const override;
185 
186   bool analyzeBranchImpl(MachineBasicBlock &MBB,
187                          MachineBasicBlock::iterator I,
188                          MachineBasicBlock *&TBB,
189                          MachineBasicBlock *&FBB,
190                          SmallVectorImpl<MachineOperand> &Cond,
191                          bool AllowModify) const;
192 
193   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
194                      MachineBasicBlock *&FBB,
195                      SmallVectorImpl<MachineOperand> &Cond,
196                      bool AllowModify) const override;
197 
198   unsigned removeBranch(MachineBasicBlock &MBB,
199                         int *BytesRemoved = nullptr) const override;
200 
201   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
202                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
203                         const DebugLoc &DL,
204                         int *BytesAdded = nullptr) const override;
205 
206   bool reverseBranchCondition(
207     SmallVectorImpl<MachineOperand> &Cond) const override;
208 
209 
210   bool canInsertSelect(const MachineBasicBlock &MBB,
211                        ArrayRef<MachineOperand> Cond,
212                        unsigned TrueReg, unsigned FalseReg,
213                        int &CondCycles,
214                        int &TrueCycles, int &FalseCycles) const override;
215 
216   void insertSelect(MachineBasicBlock &MBB,
217                     MachineBasicBlock::iterator I, const DebugLoc &DL,
218                     unsigned DstReg, ArrayRef<MachineOperand> Cond,
219                     unsigned TrueReg, unsigned FalseReg) const override;
220 
221   bool
222   areMemAccessesTriviallyDisjoint(MachineInstr &MIa, MachineInstr &MIb,
223                                   AliasAnalysis *AA = nullptr) const override;
224 
225   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
226                      MachineRegisterInfo *MRI) const final;
227 
228   unsigned getMachineCSELookAheadLimit() const override { return 500; }
229 
230   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
231                                       MachineInstr &MI,
232                                       LiveVariables *LV) const override;
233 
234   bool isSchedulingBoundary(const MachineInstr &MI,
235                             const MachineBasicBlock *MBB,
236                             const MachineFunction &MF) const override;
237 
238   static bool isSALU(const MachineInstr &MI) {
239     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
240   }
241 
242   bool isSALU(uint16_t Opcode) const {
243     return get(Opcode).TSFlags & SIInstrFlags::SALU;
244   }
245 
246   static bool isVALU(const MachineInstr &MI) {
247     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
248   }
249 
250   bool isVALU(uint16_t Opcode) const {
251     return get(Opcode).TSFlags & SIInstrFlags::VALU;
252   }
253 
254   static bool isVMEM(const MachineInstr &MI) {
255     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
256   }
257 
258   bool isVMEM(uint16_t Opcode) const {
259     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
260   }
261 
262   static bool isSOP1(const MachineInstr &MI) {
263     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
264   }
265 
266   bool isSOP1(uint16_t Opcode) const {
267     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
268   }
269 
270   static bool isSOP2(const MachineInstr &MI) {
271     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
272   }
273 
274   bool isSOP2(uint16_t Opcode) const {
275     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
276   }
277 
278   static bool isSOPC(const MachineInstr &MI) {
279     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
280   }
281 
282   bool isSOPC(uint16_t Opcode) const {
283     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
284   }
285 
286   static bool isSOPK(const MachineInstr &MI) {
287     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
288   }
289 
290   bool isSOPK(uint16_t Opcode) const {
291     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
292   }
293 
294   static bool isSOPP(const MachineInstr &MI) {
295     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
296   }
297 
298   bool isSOPP(uint16_t Opcode) const {
299     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
300   }
301 
302   static bool isVOP1(const MachineInstr &MI) {
303     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
304   }
305 
306   bool isVOP1(uint16_t Opcode) const {
307     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
308   }
309 
310   static bool isVOP2(const MachineInstr &MI) {
311     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
312   }
313 
314   bool isVOP2(uint16_t Opcode) const {
315     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
316   }
317 
318   static bool isVOP3(const MachineInstr &MI) {
319     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
320   }
321 
322   bool isVOP3(uint16_t Opcode) const {
323     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
324   }
325 
326   static bool isSDWA(const MachineInstr &MI) {
327     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
328   }
329 
330   bool isSDWA(uint16_t Opcode) const {
331     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
332   }
333 
334   static bool isVOPC(const MachineInstr &MI) {
335     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
336   }
337 
338   bool isVOPC(uint16_t Opcode) const {
339     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
340   }
341 
342   static bool isMUBUF(const MachineInstr &MI) {
343     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
344   }
345 
346   bool isMUBUF(uint16_t Opcode) const {
347     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
348   }
349 
350   static bool isMTBUF(const MachineInstr &MI) {
351     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
352   }
353 
354   bool isMTBUF(uint16_t Opcode) const {
355     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
356   }
357 
358   static bool isSMRD(const MachineInstr &MI) {
359     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
360   }
361 
362   bool isSMRD(uint16_t Opcode) const {
363     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
364   }
365 
366   static bool isDS(const MachineInstr &MI) {
367     return MI.getDesc().TSFlags & SIInstrFlags::DS;
368   }
369 
370   bool isDS(uint16_t Opcode) const {
371     return get(Opcode).TSFlags & SIInstrFlags::DS;
372   }
373 
374   static bool isMIMG(const MachineInstr &MI) {
375     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
376   }
377 
378   bool isMIMG(uint16_t Opcode) const {
379     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
380   }
381 
382   static bool isGather4(const MachineInstr &MI) {
383     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
384   }
385 
386   bool isGather4(uint16_t Opcode) const {
387     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
388   }
389 
390   static bool isFLAT(const MachineInstr &MI) {
391     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
392   }
393 
394   bool isFLAT(uint16_t Opcode) const {
395     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
396   }
397 
398   static bool isEXP(const MachineInstr &MI) {
399     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
400   }
401 
402   bool isEXP(uint16_t Opcode) const {
403     return get(Opcode).TSFlags & SIInstrFlags::EXP;
404   }
405 
406   static bool isWQM(const MachineInstr &MI) {
407     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
408   }
409 
410   bool isWQM(uint16_t Opcode) const {
411     return get(Opcode).TSFlags & SIInstrFlags::WQM;
412   }
413 
414   static bool isDisableWQM(const MachineInstr &MI) {
415     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
416   }
417 
418   bool isDisableWQM(uint16_t Opcode) const {
419     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
420   }
421 
422   static bool isVGPRSpill(const MachineInstr &MI) {
423     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
424   }
425 
426   bool isVGPRSpill(uint16_t Opcode) const {
427     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
428   }
429 
430   static bool isSGPRSpill(const MachineInstr &MI) {
431     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
432   }
433 
434   bool isSGPRSpill(uint16_t Opcode) const {
435     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
436   }
437 
438   static bool isDPP(const MachineInstr &MI) {
439     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
440   }
441 
442   bool isDPP(uint16_t Opcode) const {
443     return get(Opcode).TSFlags & SIInstrFlags::DPP;
444   }
445 
446   static bool isVOP3P(const MachineInstr &MI) {
447     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
448   }
449 
450   bool isVOP3P(uint16_t Opcode) const {
451     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
452   }
453 
454   static bool isScalarUnit(const MachineInstr &MI) {
455     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
456   }
457 
458   static bool usesVM_CNT(const MachineInstr &MI) {
459     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
460   }
461 
462   static bool sopkIsZext(const MachineInstr &MI) {
463     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
464   }
465 
466   bool sopkIsZext(uint16_t Opcode) const {
467     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
468   }
469 
470   /// \returns true if this is an s_store_dword* instruction. This is more
471   /// specific than than isSMEM && mayStore.
472   static bool isScalarStore(const MachineInstr &MI) {
473     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
474   }
475 
476   bool isScalarStore(uint16_t Opcode) const {
477     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
478   }
479 
480   static bool isFixedSize(const MachineInstr &MI) {
481     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
482   }
483 
484   bool isFixedSize(uint16_t Opcode) const {
485     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
486   }
487 
488   static bool hasFPClamp(const MachineInstr &MI) {
489     return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
490   }
491 
492   bool hasFPClamp(uint16_t Opcode) const {
493     return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
494   }
495 
496   bool isVGPRCopy(const MachineInstr &MI) const {
497     assert(MI.isCopy());
498     unsigned Dest = MI.getOperand(0).getReg();
499     const MachineFunction &MF = *MI.getParent()->getParent();
500     const MachineRegisterInfo &MRI = MF.getRegInfo();
501     return !RI.isSGPRReg(MRI, Dest);
502   }
503 
504   bool isInlineConstant(const APInt &Imm) const;
505 
506   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
507 
508   bool isInlineConstant(const MachineOperand &MO,
509                         const MCOperandInfo &OpInfo) const {
510     return isInlineConstant(MO, OpInfo.OperandType);
511   }
512 
513   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
514   /// be an inline immediate.
515   bool isInlineConstant(const MachineInstr &MI,
516                         const MachineOperand &UseMO,
517                         const MachineOperand &DefMO) const {
518     assert(UseMO.getParent() == &MI);
519     int OpIdx = MI.getOperandNo(&UseMO);
520     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
521       return false;
522     }
523 
524     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
525   }
526 
527   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
528   /// immediate.
529   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
530     const MachineOperand &MO = MI.getOperand(OpIdx);
531     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
532   }
533 
534   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
535                         const MachineOperand &MO) const {
536     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
537       return false;
538 
539     if (MI.isCopy()) {
540       unsigned Size = getOpSize(MI, OpIdx);
541       assert(Size == 8 || Size == 4);
542 
543       uint8_t OpType = (Size == 8) ?
544         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
545       return isInlineConstant(MO, OpType);
546     }
547 
548     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
549   }
550 
551   bool isInlineConstant(const MachineOperand &MO) const {
552     const MachineInstr *Parent = MO.getParent();
553     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
554   }
555 
556   bool isLiteralConstant(const MachineOperand &MO,
557                          const MCOperandInfo &OpInfo) const {
558     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
559   }
560 
561   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
562     const MachineOperand &MO = MI.getOperand(OpIdx);
563     return MO.isImm() && !isInlineConstant(MI, OpIdx);
564   }
565 
566   // Returns true if this operand could potentially require a 32-bit literal
567   // operand, but not necessarily. A FrameIndex for example could resolve to an
568   // inline immediate value that will not require an additional 4-bytes; this
569   // assumes that it will.
570   bool isLiteralConstantLike(const MachineOperand &MO,
571                              const MCOperandInfo &OpInfo) const;
572 
573   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
574                          const MachineOperand &MO) const;
575 
576   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
577   /// This function will return false if you pass it a 32-bit instruction.
578   bool hasVALU32BitEncoding(unsigned Opcode) const;
579 
580   /// \brief Returns true if this operand uses the constant bus.
581   bool usesConstantBus(const MachineRegisterInfo &MRI,
582                        const MachineOperand &MO,
583                        const MCOperandInfo &OpInfo) const;
584 
585   /// \brief Return true if this instruction has any modifiers.
586   ///  e.g. src[012]_mod, omod, clamp.
587   bool hasModifiers(unsigned Opcode) const;
588 
589   bool hasModifiersSet(const MachineInstr &MI,
590                        unsigned OpName) const;
591   bool hasAnyModifiersSet(const MachineInstr &MI) const;
592 
593   bool verifyInstruction(const MachineInstr &MI,
594                          StringRef &ErrInfo) const override;
595 
596   static unsigned getVALUOp(const MachineInstr &MI);
597 
598   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
599 
600   /// \brief Return the correct register class for \p OpNo.  For target-specific
601   /// instructions, this will return the register class that has been defined
602   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
603   /// the register class of its machine operand.
604   /// to infer the correct register class base on the other operands.
605   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
606                                            unsigned OpNo) const;
607 
608   /// \brief Return the size in bytes of the operand OpNo on the given
609   // instruction opcode.
610   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
611     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
612 
613     if (OpInfo.RegClass == -1) {
614       // If this is an immediate operand, this must be a 32-bit literal.
615       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
616       return 4;
617     }
618 
619     return RI.getRegClass(OpInfo.RegClass)->getSize();
620   }
621 
622   /// \brief This form should usually be preferred since it handles operands
623   /// with unknown register classes.
624   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
625     return getOpRegClass(MI, OpNo)->getSize();
626   }
627 
628   /// \returns true if it is legal for the operand at index \p OpNo
629   /// to read a VGPR.
630   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
631 
632   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
633   /// a MOV.  For example:
634   /// ADD_I32_e32 VGPR0, 15
635   /// to
636   /// MOV VGPR1, 15
637   /// ADD_I32_e32 VGPR0, VGPR1
638   ///
639   /// If the operand being legalized is a register, then a COPY will be used
640   /// instead of MOV.
641   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
642 
643   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
644   /// for \p MI.
645   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
646                       const MachineOperand *MO = nullptr) const;
647 
648   /// \brief Check if \p MO would be a valid operand for the given operand
649   /// definition \p OpInfo. Note this does not attempt to validate constant bus
650   /// restrictions (e.g. literal constant usage).
651   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
652                           const MCOperandInfo &OpInfo,
653                           const MachineOperand &MO) const;
654 
655   /// \brief Check if \p MO (a register operand) is a legal register for the
656   /// given operand description.
657   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
658                          const MCOperandInfo &OpInfo,
659                          const MachineOperand &MO) const;
660 
661   /// \brief Legalize operands in \p MI by either commuting it or inserting a
662   /// copy of src1.
663   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
664 
665   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
666   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
667 
668   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
669   /// be used when it is know that the value in SrcReg is same across all
670   /// threads in the wave.
671   /// \returns The SGPR register that \p SrcReg was copied to.
672   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
673                               MachineRegisterInfo &MRI) const;
674 
675   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
676 
677   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
678                               MachineBasicBlock::iterator I,
679                               const TargetRegisterClass *DstRC,
680                               MachineOperand &Op, MachineRegisterInfo &MRI,
681                               const DebugLoc &DL) const;
682 
683   /// \brief Legalize all operands in this instruction.  This function may
684   /// create new instruction and insert them before \p MI.
685   void legalizeOperands(MachineInstr &MI) const;
686 
687   /// \brief Replace this instruction's opcode with the equivalent VALU
688   /// opcode.  This function will also move the users of \p MI to the
689   /// VALU if necessary.
690   void moveToVALU(MachineInstr &MI) const;
691 
692   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
693                         int Count) const;
694 
695   void insertNoop(MachineBasicBlock &MBB,
696                   MachineBasicBlock::iterator MI) const override;
697 
698   /// \brief Return the number of wait states that result from executing this
699   /// instruction.
700   unsigned getNumWaitStates(const MachineInstr &MI) const;
701 
702   /// \brief Returns the operand named \p Op.  If \p MI does not have an
703   /// operand named \c Op, this function returns nullptr.
704   LLVM_READONLY
705   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
706 
707   LLVM_READONLY
708   const MachineOperand *getNamedOperand(const MachineInstr &MI,
709                                         unsigned OpName) const {
710     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
711   }
712 
713   /// Get required immediate operand
714   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
715     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
716     return MI.getOperand(Idx).getImm();
717   }
718 
719   uint64_t getDefaultRsrcDataFormat() const;
720   uint64_t getScratchRsrcWords23() const;
721 
722   bool isLowLatencyInstruction(const MachineInstr &MI) const;
723   bool isHighLatencyInstruction(const MachineInstr &MI) const;
724 
725   /// \brief Return the descriptor of the target-specific machine instruction
726   /// that corresponds to the specified pseudo or native opcode.
727   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
728     return get(pseudoToMCOpcode(Opcode));
729   }
730 
731   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
732   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
733 
734   unsigned isLoadFromStackSlot(const MachineInstr &MI,
735                                int &FrameIndex) const override;
736   unsigned isStoreToStackSlot(const MachineInstr &MI,
737                               int &FrameIndex) const override;
738 
739   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
740 
741   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
742 
743   ArrayRef<std::pair<int, const char *>>
744   getSerializableTargetIndices() const override;
745 
746   ScheduleHazardRecognizer *
747   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
748                                  const ScheduleDAG *DAG) const override;
749 
750   ScheduleHazardRecognizer *
751   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
752 
753   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
754 };
755 
756 namespace AMDGPU {
757   LLVM_READONLY
758   int getVOPe64(uint16_t Opcode);
759 
760   LLVM_READONLY
761   int getVOPe32(uint16_t Opcode);
762 
763   LLVM_READONLY
764   int getCommuteRev(uint16_t Opcode);
765 
766   LLVM_READONLY
767   int getCommuteOrig(uint16_t Opcode);
768 
769   LLVM_READONLY
770   int getAddr64Inst(uint16_t Opcode);
771 
772   LLVM_READONLY
773   int getAtomicRetOp(uint16_t Opcode);
774 
775   LLVM_READONLY
776   int getAtomicNoRetOp(uint16_t Opcode);
777 
778   LLVM_READONLY
779   int getSOPKOp(uint16_t Opcode);
780 
781   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
782   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
783   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
784   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
785 
786   // For MachineOperands.
787   enum TargetFlags {
788     TF_LONG_BRANCH_FORWARD = 1 << 0,
789     TF_LONG_BRANCH_BACKWARD = 1 << 1
790   };
791 } // End namespace AMDGPU
792 
793 namespace SI {
794 namespace KernelInputOffsets {
795 
796 /// Offsets in bytes from the start of the input buffer
797 enum Offsets {
798   NGROUPS_X = 0,
799   NGROUPS_Y = 4,
800   NGROUPS_Z = 8,
801   GLOBAL_SIZE_X = 12,
802   GLOBAL_SIZE_Y = 16,
803   GLOBAL_SIZE_Z = 20,
804   LOCAL_SIZE_X = 24,
805   LOCAL_SIZE_Y = 28,
806   LOCAL_SIZE_Z = 32
807 };
808 
809 } // End namespace KernelInputOffsets
810 } // End namespace SI
811 
812 } // End namespace llvm
813 
814 #endif
815