]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/AMDGPU/SIInstrInfo.h
Merge compiler-rt trunk r300890, and update build glue.
[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   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 isFoldableCopy(const MachineInstr &MI) const;
226
227   bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg,
228                      MachineRegisterInfo *MRI) const final;
229
230   unsigned getMachineCSELookAheadLimit() const override { return 500; }
231
232   MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
233                                       MachineInstr &MI,
234                                       LiveVariables *LV) const override;
235
236   bool isSchedulingBoundary(const MachineInstr &MI,
237                             const MachineBasicBlock *MBB,
238                             const MachineFunction &MF) const override;
239
240   static bool isSALU(const MachineInstr &MI) {
241     return MI.getDesc().TSFlags & SIInstrFlags::SALU;
242   }
243
244   bool isSALU(uint16_t Opcode) const {
245     return get(Opcode).TSFlags & SIInstrFlags::SALU;
246   }
247
248   static bool isVALU(const MachineInstr &MI) {
249     return MI.getDesc().TSFlags & SIInstrFlags::VALU;
250   }
251
252   bool isVALU(uint16_t Opcode) const {
253     return get(Opcode).TSFlags & SIInstrFlags::VALU;
254   }
255
256   static bool isVMEM(const MachineInstr &MI) {
257     return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
258   }
259
260   bool isVMEM(uint16_t Opcode) const {
261     return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
262   }
263
264   static bool isSOP1(const MachineInstr &MI) {
265     return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
266   }
267
268   bool isSOP1(uint16_t Opcode) const {
269     return get(Opcode).TSFlags & SIInstrFlags::SOP1;
270   }
271
272   static bool isSOP2(const MachineInstr &MI) {
273     return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
274   }
275
276   bool isSOP2(uint16_t Opcode) const {
277     return get(Opcode).TSFlags & SIInstrFlags::SOP2;
278   }
279
280   static bool isSOPC(const MachineInstr &MI) {
281     return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
282   }
283
284   bool isSOPC(uint16_t Opcode) const {
285     return get(Opcode).TSFlags & SIInstrFlags::SOPC;
286   }
287
288   static bool isSOPK(const MachineInstr &MI) {
289     return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
290   }
291
292   bool isSOPK(uint16_t Opcode) const {
293     return get(Opcode).TSFlags & SIInstrFlags::SOPK;
294   }
295
296   static bool isSOPP(const MachineInstr &MI) {
297     return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
298   }
299
300   bool isSOPP(uint16_t Opcode) const {
301     return get(Opcode).TSFlags & SIInstrFlags::SOPP;
302   }
303
304   static bool isVOP1(const MachineInstr &MI) {
305     return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
306   }
307
308   bool isVOP1(uint16_t Opcode) const {
309     return get(Opcode).TSFlags & SIInstrFlags::VOP1;
310   }
311
312   static bool isVOP2(const MachineInstr &MI) {
313     return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
314   }
315
316   bool isVOP2(uint16_t Opcode) const {
317     return get(Opcode).TSFlags & SIInstrFlags::VOP2;
318   }
319
320   static bool isVOP3(const MachineInstr &MI) {
321     return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
322   }
323
324   bool isVOP3(uint16_t Opcode) const {
325     return get(Opcode).TSFlags & SIInstrFlags::VOP3;
326   }
327
328   static bool isSDWA(const MachineInstr &MI) {
329     return MI.getDesc().TSFlags & SIInstrFlags::SDWA;
330   }
331
332   bool isSDWA(uint16_t Opcode) const {
333     return get(Opcode).TSFlags & SIInstrFlags::SDWA;
334   }
335
336   static bool isVOPC(const MachineInstr &MI) {
337     return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
338   }
339
340   bool isVOPC(uint16_t Opcode) const {
341     return get(Opcode).TSFlags & SIInstrFlags::VOPC;
342   }
343
344   static bool isMUBUF(const MachineInstr &MI) {
345     return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
346   }
347
348   bool isMUBUF(uint16_t Opcode) const {
349     return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
350   }
351
352   static bool isMTBUF(const MachineInstr &MI) {
353     return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
354   }
355
356   bool isMTBUF(uint16_t Opcode) const {
357     return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
358   }
359
360   static bool isSMRD(const MachineInstr &MI) {
361     return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
362   }
363
364   bool isSMRD(uint16_t Opcode) const {
365     return get(Opcode).TSFlags & SIInstrFlags::SMRD;
366   }
367
368   static bool isDS(const MachineInstr &MI) {
369     return MI.getDesc().TSFlags & SIInstrFlags::DS;
370   }
371
372   bool isDS(uint16_t Opcode) const {
373     return get(Opcode).TSFlags & SIInstrFlags::DS;
374   }
375
376   static bool isMIMG(const MachineInstr &MI) {
377     return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
378   }
379
380   bool isMIMG(uint16_t Opcode) const {
381     return get(Opcode).TSFlags & SIInstrFlags::MIMG;
382   }
383
384   static bool isGather4(const MachineInstr &MI) {
385     return MI.getDesc().TSFlags & SIInstrFlags::Gather4;
386   }
387
388   bool isGather4(uint16_t Opcode) const {
389     return get(Opcode).TSFlags & SIInstrFlags::Gather4;
390   }
391
392   static bool isFLAT(const MachineInstr &MI) {
393     return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
394   }
395
396   bool isFLAT(uint16_t Opcode) const {
397     return get(Opcode).TSFlags & SIInstrFlags::FLAT;
398   }
399
400   static bool isEXP(const MachineInstr &MI) {
401     return MI.getDesc().TSFlags & SIInstrFlags::EXP;
402   }
403
404   bool isEXP(uint16_t Opcode) const {
405     return get(Opcode).TSFlags & SIInstrFlags::EXP;
406   }
407
408   static bool isWQM(const MachineInstr &MI) {
409     return MI.getDesc().TSFlags & SIInstrFlags::WQM;
410   }
411
412   bool isWQM(uint16_t Opcode) const {
413     return get(Opcode).TSFlags & SIInstrFlags::WQM;
414   }
415
416   static bool isDisableWQM(const MachineInstr &MI) {
417     return MI.getDesc().TSFlags & SIInstrFlags::DisableWQM;
418   }
419
420   bool isDisableWQM(uint16_t Opcode) const {
421     return get(Opcode).TSFlags & SIInstrFlags::DisableWQM;
422   }
423
424   static bool isVGPRSpill(const MachineInstr &MI) {
425     return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
426   }
427
428   bool isVGPRSpill(uint16_t Opcode) const {
429     return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
430   }
431
432   static bool isSGPRSpill(const MachineInstr &MI) {
433     return MI.getDesc().TSFlags & SIInstrFlags::SGPRSpill;
434   }
435
436   bool isSGPRSpill(uint16_t Opcode) const {
437     return get(Opcode).TSFlags & SIInstrFlags::SGPRSpill;
438   }
439
440   static bool isDPP(const MachineInstr &MI) {
441     return MI.getDesc().TSFlags & SIInstrFlags::DPP;
442   }
443
444   bool isDPP(uint16_t Opcode) const {
445     return get(Opcode).TSFlags & SIInstrFlags::DPP;
446   }
447
448   static bool isVOP3P(const MachineInstr &MI) {
449     return MI.getDesc().TSFlags & SIInstrFlags::VOP3P;
450   }
451
452   bool isVOP3P(uint16_t Opcode) const {
453     return get(Opcode).TSFlags & SIInstrFlags::VOP3P;
454   }
455
456   static bool isVINTRP(const MachineInstr &MI) {
457     return MI.getDesc().TSFlags & SIInstrFlags::VINTRP;
458   }
459
460   bool isVINTRP(uint16_t Opcode) const {
461     return get(Opcode).TSFlags & SIInstrFlags::VINTRP;
462   }
463
464   static bool isScalarUnit(const MachineInstr &MI) {
465     return MI.getDesc().TSFlags & (SIInstrFlags::SALU | SIInstrFlags::SMRD);
466   }
467
468   static bool usesVM_CNT(const MachineInstr &MI) {
469     return MI.getDesc().TSFlags & SIInstrFlags::VM_CNT;
470   }
471
472   static bool sopkIsZext(const MachineInstr &MI) {
473     return MI.getDesc().TSFlags & SIInstrFlags::SOPK_ZEXT;
474   }
475
476   bool sopkIsZext(uint16_t Opcode) const {
477     return get(Opcode).TSFlags & SIInstrFlags::SOPK_ZEXT;
478   }
479
480   /// \returns true if this is an s_store_dword* instruction. This is more
481   /// specific than than isSMEM && mayStore.
482   static bool isScalarStore(const MachineInstr &MI) {
483     return MI.getDesc().TSFlags & SIInstrFlags::SCALAR_STORE;
484   }
485
486   bool isScalarStore(uint16_t Opcode) const {
487     return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
488   }
489
490   static bool isFixedSize(const MachineInstr &MI) {
491     return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
492   }
493
494   bool isFixedSize(uint16_t Opcode) const {
495     return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
496   }
497
498   static bool hasFPClamp(const MachineInstr &MI) {
499     return MI.getDesc().TSFlags & SIInstrFlags::HasFPClamp;
500   }
501
502   bool hasFPClamp(uint16_t Opcode) const {
503     return get(Opcode).TSFlags & SIInstrFlags::HasFPClamp;
504   }
505
506   bool isVGPRCopy(const MachineInstr &MI) const {
507     assert(MI.isCopy());
508     unsigned Dest = MI.getOperand(0).getReg();
509     const MachineFunction &MF = *MI.getParent()->getParent();
510     const MachineRegisterInfo &MRI = MF.getRegInfo();
511     return !RI.isSGPRReg(MRI, Dest);
512   }
513
514   bool isInlineConstant(const APInt &Imm) const;
515
516   bool isInlineConstant(const MachineOperand &MO, uint8_t OperandType) const;
517
518   bool isInlineConstant(const MachineOperand &MO,
519                         const MCOperandInfo &OpInfo) const {
520     return isInlineConstant(MO, OpInfo.OperandType);
521   }
522
523   /// \p returns true if \p UseMO is substituted with \p DefMO in \p MI it would
524   /// be an inline immediate.
525   bool isInlineConstant(const MachineInstr &MI,
526                         const MachineOperand &UseMO,
527                         const MachineOperand &DefMO) const {
528     assert(UseMO.getParent() == &MI);
529     int OpIdx = MI.getOperandNo(&UseMO);
530     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands) {
531       return false;
532     }
533
534     return isInlineConstant(DefMO, MI.getDesc().OpInfo[OpIdx]);
535   }
536
537   /// \p returns true if the operand \p OpIdx in \p MI is a valid inline
538   /// immediate.
539   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx) const {
540     const MachineOperand &MO = MI.getOperand(OpIdx);
541     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
542   }
543
544   bool isInlineConstant(const MachineInstr &MI, unsigned OpIdx,
545                         const MachineOperand &MO) const {
546     if (!MI.getDesc().OpInfo || OpIdx >= MI.getDesc().NumOperands)
547       return false;
548
549     if (MI.isCopy()) {
550       unsigned Size = getOpSize(MI, OpIdx);
551       assert(Size == 8 || Size == 4);
552
553       uint8_t OpType = (Size == 8) ?
554         AMDGPU::OPERAND_REG_IMM_INT64 : AMDGPU::OPERAND_REG_IMM_INT32;
555       return isInlineConstant(MO, OpType);
556     }
557
558     return isInlineConstant(MO, MI.getDesc().OpInfo[OpIdx].OperandType);
559   }
560
561   bool isInlineConstant(const MachineOperand &MO) const {
562     const MachineInstr *Parent = MO.getParent();
563     return isInlineConstant(*Parent, Parent->getOperandNo(&MO));
564   }
565
566   bool isLiteralConstant(const MachineOperand &MO,
567                          const MCOperandInfo &OpInfo) const {
568     return MO.isImm() && !isInlineConstant(MO, OpInfo.OperandType);
569   }
570
571   bool isLiteralConstant(const MachineInstr &MI, int OpIdx) const {
572     const MachineOperand &MO = MI.getOperand(OpIdx);
573     return MO.isImm() && !isInlineConstant(MI, OpIdx);
574   }
575
576   // Returns true if this operand could potentially require a 32-bit literal
577   // operand, but not necessarily. A FrameIndex for example could resolve to an
578   // inline immediate value that will not require an additional 4-bytes; this
579   // assumes that it will.
580   bool isLiteralConstantLike(const MachineOperand &MO,
581                              const MCOperandInfo &OpInfo) const;
582
583   bool isImmOperandLegal(const MachineInstr &MI, unsigned OpNo,
584                          const MachineOperand &MO) const;
585
586   /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
587   /// This function will return false if you pass it a 32-bit instruction.
588   bool hasVALU32BitEncoding(unsigned Opcode) const;
589
590   /// \brief Returns true if this operand uses the constant bus.
591   bool usesConstantBus(const MachineRegisterInfo &MRI,
592                        const MachineOperand &MO,
593                        const MCOperandInfo &OpInfo) const;
594
595   /// \brief Return true if this instruction has any modifiers.
596   ///  e.g. src[012]_mod, omod, clamp.
597   bool hasModifiers(unsigned Opcode) const;
598
599   bool hasModifiersSet(const MachineInstr &MI,
600                        unsigned OpName) const;
601   bool hasAnyModifiersSet(const MachineInstr &MI) const;
602
603   bool verifyInstruction(const MachineInstr &MI,
604                          StringRef &ErrInfo) const override;
605
606   static unsigned getVALUOp(const MachineInstr &MI);
607
608   bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
609
610   /// \brief Return the correct register class for \p OpNo.  For target-specific
611   /// instructions, this will return the register class that has been defined
612   /// in tablegen.  For generic instructions, like REG_SEQUENCE it will return
613   /// the register class of its machine operand.
614   /// to infer the correct register class base on the other operands.
615   const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
616                                            unsigned OpNo) const;
617
618   /// \brief Return the size in bytes of the operand OpNo on the given
619   // instruction opcode.
620   unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
621     const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
622
623     if (OpInfo.RegClass == -1) {
624       // If this is an immediate operand, this must be a 32-bit literal.
625       assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
626       return 4;
627     }
628
629     return RI.getRegClass(OpInfo.RegClass)->getSize();
630   }
631
632   /// \brief This form should usually be preferred since it handles operands
633   /// with unknown register classes.
634   unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
635     return getOpRegClass(MI, OpNo)->getSize();
636   }
637
638   /// \returns true if it is legal for the operand at index \p OpNo
639   /// to read a VGPR.
640   bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
641
642   /// \brief Legalize the \p OpIndex operand of this instruction by inserting
643   /// a MOV.  For example:
644   /// ADD_I32_e32 VGPR0, 15
645   /// to
646   /// MOV VGPR1, 15
647   /// ADD_I32_e32 VGPR0, VGPR1
648   ///
649   /// If the operand being legalized is a register, then a COPY will be used
650   /// instead of MOV.
651   void legalizeOpWithMove(MachineInstr &MI, unsigned OpIdx) const;
652
653   /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
654   /// for \p MI.
655   bool isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
656                       const MachineOperand *MO = nullptr) const;
657
658   /// \brief Check if \p MO would be a valid operand for the given operand
659   /// definition \p OpInfo. Note this does not attempt to validate constant bus
660   /// restrictions (e.g. literal constant usage).
661   bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
662                           const MCOperandInfo &OpInfo,
663                           const MachineOperand &MO) const;
664
665   /// \brief Check if \p MO (a register operand) is a legal register for the
666   /// given operand description.
667   bool isLegalRegOperand(const MachineRegisterInfo &MRI,
668                          const MCOperandInfo &OpInfo,
669                          const MachineOperand &MO) const;
670
671   /// \brief Legalize operands in \p MI by either commuting it or inserting a
672   /// copy of src1.
673   void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr &MI) const;
674
675   /// \brief Fix operands in \p MI to satisfy constant bus requirements.
676   void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr &MI) const;
677
678   /// Copy a value from a VGPR (\p SrcReg) to SGPR.  This function can only
679   /// be used when it is know that the value in SrcReg is same across all
680   /// threads in the wave.
681   /// \returns The SGPR register that \p SrcReg was copied to.
682   unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr &UseMI,
683                               MachineRegisterInfo &MRI) const;
684
685   void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr &MI) const;
686
687   void legalizeGenericOperand(MachineBasicBlock &InsertMBB,
688                               MachineBasicBlock::iterator I,
689                               const TargetRegisterClass *DstRC,
690                               MachineOperand &Op, MachineRegisterInfo &MRI,
691                               const DebugLoc &DL) const;
692
693   /// \brief Legalize all operands in this instruction.  This function may
694   /// create new instruction and insert them before \p MI.
695   void legalizeOperands(MachineInstr &MI) const;
696
697   /// \brief Replace this instruction's opcode with the equivalent VALU
698   /// opcode.  This function will also move the users of \p MI to the
699   /// VALU if necessary.
700   void moveToVALU(MachineInstr &MI) const;
701
702   void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
703                         int Count) const;
704
705   void insertNoop(MachineBasicBlock &MBB,
706                   MachineBasicBlock::iterator MI) const override;
707
708   /// \brief Return the number of wait states that result from executing this
709   /// instruction.
710   unsigned getNumWaitStates(const MachineInstr &MI) const;
711
712   /// \brief Returns the operand named \p Op.  If \p MI does not have an
713   /// operand named \c Op, this function returns nullptr.
714   LLVM_READONLY
715   MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
716
717   LLVM_READONLY
718   const MachineOperand *getNamedOperand(const MachineInstr &MI,
719                                         unsigned OpName) const {
720     return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
721   }
722
723   /// Get required immediate operand
724   int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
725     int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
726     return MI.getOperand(Idx).getImm();
727   }
728
729   uint64_t getDefaultRsrcDataFormat() const;
730   uint64_t getScratchRsrcWords23() const;
731
732   bool isLowLatencyInstruction(const MachineInstr &MI) const;
733   bool isHighLatencyInstruction(const MachineInstr &MI) const;
734
735   /// \brief Return the descriptor of the target-specific machine instruction
736   /// that corresponds to the specified pseudo or native opcode.
737   const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
738     return get(pseudoToMCOpcode(Opcode));
739   }
740
741   unsigned isStackAccess(const MachineInstr &MI, int &FrameIndex) const;
742   unsigned isSGPRStackAccess(const MachineInstr &MI, int &FrameIndex) const;
743
744   unsigned isLoadFromStackSlot(const MachineInstr &MI,
745                                int &FrameIndex) const override;
746   unsigned isStoreToStackSlot(const MachineInstr &MI,
747                               int &FrameIndex) const override;
748
749   unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
750
751   bool mayAccessFlatAddressSpace(const MachineInstr &MI) const;
752
753   ArrayRef<std::pair<int, const char *>>
754   getSerializableTargetIndices() const override;
755
756   ScheduleHazardRecognizer *
757   CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
758                                  const ScheduleDAG *DAG) const override;
759
760   ScheduleHazardRecognizer *
761   CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
762
763   bool isBasicBlockPrologue(const MachineInstr &MI) const override;
764
765   /// \brief Return a partially built integer add instruction without carry.
766   /// Caller must add source operands.
767   /// For pre-GFX9 it will generate unused carry destination operand.
768   /// TODO: After GFX9 it should return a no-carry operation.
769   MachineInstrBuilder getAddNoCarry(MachineBasicBlock &MBB,
770                                     MachineBasicBlock::iterator I,
771                                     const DebugLoc &DL,
772                                     unsigned DestReg) const;
773 };
774
775 namespace AMDGPU {
776   LLVM_READONLY
777   int getVOPe64(uint16_t Opcode);
778
779   LLVM_READONLY
780   int getVOPe32(uint16_t Opcode);
781
782   LLVM_READONLY
783   int getSDWAOp(uint16_t Opcode);
784
785   LLVM_READONLY
786   int getCommuteRev(uint16_t Opcode);
787
788   LLVM_READONLY
789   int getCommuteOrig(uint16_t Opcode);
790
791   LLVM_READONLY
792   int getAddr64Inst(uint16_t Opcode);
793
794   LLVM_READONLY
795   int getAtomicRetOp(uint16_t Opcode);
796
797   LLVM_READONLY
798   int getAtomicNoRetOp(uint16_t Opcode);
799
800   LLVM_READONLY
801   int getSOPKOp(uint16_t Opcode);
802
803   const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
804   const uint64_t RSRC_ELEMENT_SIZE_SHIFT = (32 + 19);
805   const uint64_t RSRC_INDEX_STRIDE_SHIFT = (32 + 21);
806   const uint64_t RSRC_TID_ENABLE = UINT64_C(1) << (32 + 23);
807
808   // For MachineOperands.
809   enum TargetFlags {
810     TF_LONG_BRANCH_FORWARD = 1 << 0,
811     TF_LONG_BRANCH_BACKWARD = 1 << 1
812   };
813 } // End namespace AMDGPU
814
815 namespace SI {
816 namespace KernelInputOffsets {
817
818 /// Offsets in bytes from the start of the input buffer
819 enum Offsets {
820   NGROUPS_X = 0,
821   NGROUPS_Y = 4,
822   NGROUPS_Z = 8,
823   GLOBAL_SIZE_X = 12,
824   GLOBAL_SIZE_Y = 16,
825   GLOBAL_SIZE_Z = 20,
826   LOCAL_SIZE_X = 24,
827   LOCAL_SIZE_Y = 28,
828   LOCAL_SIZE_Z = 32
829 };
830
831 } // End namespace KernelInputOffsets
832 } // End namespace SI
833
834 } // End namespace llvm
835
836 #endif