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