blob: 32881c745fafd26611696756d07f1abcc6e4038f [file] [log] [blame]
Matt Arsenaultdf90c022013-10-15 23:44:45 +00001//===-- SIInstrInfo.h - SI Instruction Info Interface -----------*- C++ -*-===//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
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
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000016#ifndef LLVM_LIB_TARGET_R600_SIINSTRINFO_H
17#define LLVM_LIB_TARGET_R600_SIINSTRINFO_H
Tom Stellard75aadc22012-12-11 21:25:42 +000018
19#include "AMDGPUInstrInfo.h"
Matt Arsenaultc5f174d2014-12-01 15:52:46 +000020#include "SIDefines.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000021#include "SIRegisterInfo.h"
22
23namespace llvm {
24
25class SIInstrInfo : public AMDGPUInstrInfo {
26private:
27 const SIRegisterInfo RI;
28
Tom Stellard15834092014-03-21 15:51:57 +000029 unsigned buildExtractSubReg(MachineBasicBlock::iterator MI,
30 MachineRegisterInfo &MRI,
31 MachineOperand &SuperReg,
32 const TargetRegisterClass *SuperRC,
33 unsigned SubIdx,
34 const TargetRegisterClass *SubRC) const;
Matt Arsenault248b7b62014-03-24 20:08:09 +000035 MachineOperand buildExtractSubRegOrImm(MachineBasicBlock::iterator MI,
36 MachineRegisterInfo &MRI,
37 MachineOperand &SuperReg,
38 const TargetRegisterClass *SuperRC,
39 unsigned SubIdx,
40 const TargetRegisterClass *SubRC) const;
Tom Stellard15834092014-03-21 15:51:57 +000041
Matt Arsenaultbd995802014-03-24 18:26:52 +000042 unsigned split64BitImm(SmallVectorImpl<MachineInstr *> &Worklist,
43 MachineBasicBlock::iterator MI,
44 MachineRegisterInfo &MRI,
45 const TargetRegisterClass *RC,
46 const MachineOperand &Op) const;
47
Matt Arsenault689f3252014-06-09 16:36:31 +000048 void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
49 MachineInstr *Inst, unsigned Opcode) const;
50
51 void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
52 MachineInstr *Inst, unsigned Opcode) const;
Matt Arsenaultf35182c2014-03-24 20:08:05 +000053
Matt Arsenault8333e432014-06-10 19:18:24 +000054 void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
55 MachineInstr *Inst) const;
Matt Arsenault94812212014-11-14 18:18:16 +000056 void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
57 MachineInstr *Inst) const;
Matt Arsenault8333e432014-06-10 19:18:24 +000058
Matt Arsenault27cc9582014-04-18 01:53:18 +000059 void addDescImplicitUseDef(const MCInstrDesc &Desc, MachineInstr *MI) const;
Matt Arsenaultf35182c2014-03-24 20:08:05 +000060
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +000061 bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
62 MachineInstr *MIb) const;
63
Matt Arsenaultee522bf2014-09-26 17:55:06 +000064 unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
65
Tom Stellard75aadc22012-12-11 21:25:42 +000066public:
Tom Stellard2e59a452014-06-13 01:32:00 +000067 explicit SIInstrInfo(const AMDGPUSubtarget &st);
Tom Stellard75aadc22012-12-11 21:25:42 +000068
Craig Topper5656db42014-04-29 07:57:24 +000069 const SIRegisterInfo &getRegisterInfo() const override {
Matt Arsenault6dde3032014-03-11 00:01:34 +000070 return RI;
71 }
Tom Stellard75aadc22012-12-11 21:25:42 +000072
Matt Arsenaultc10853f2014-08-06 00:29:43 +000073 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
74 int64_t &Offset1,
75 int64_t &Offset2) const override;
76
Matt Arsenault1acc72f2014-07-29 21:34:55 +000077 bool getLdStBaseRegImmOfs(MachineInstr *LdSt,
78 unsigned &BaseReg, unsigned &Offset,
79 const TargetRegisterInfo *TRI) const final;
80
Matt Arsenault0e75a062014-09-17 17:48:30 +000081 bool shouldClusterLoads(MachineInstr *FirstLdSt,
82 MachineInstr *SecondLdSt,
83 unsigned NumLoads) const final;
84
Craig Topper5656db42014-04-29 07:57:24 +000085 void copyPhysReg(MachineBasicBlock &MBB,
86 MachineBasicBlock::iterator MI, DebugLoc DL,
87 unsigned DestReg, unsigned SrcReg,
88 bool KillSrc) const override;
Tom Stellard75aadc22012-12-11 21:25:42 +000089
Tom Stellard96468902014-09-24 01:33:17 +000090 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
91 MachineBasicBlock::iterator MI,
92 RegScavenger *RS,
93 unsigned TmpReg,
94 unsigned Offset,
95 unsigned Size) const;
96
Tom Stellardc149dc02013-11-27 21:23:35 +000097 void storeRegToStackSlot(MachineBasicBlock &MBB,
98 MachineBasicBlock::iterator MI,
99 unsigned SrcReg, bool isKill, int FrameIndex,
100 const TargetRegisterClass *RC,
Craig Topper5656db42014-04-29 07:57:24 +0000101 const TargetRegisterInfo *TRI) const override;
Tom Stellardc149dc02013-11-27 21:23:35 +0000102
103 void loadRegFromStackSlot(MachineBasicBlock &MBB,
104 MachineBasicBlock::iterator MI,
105 unsigned DestReg, int FrameIndex,
106 const TargetRegisterClass *RC,
Craig Topper5656db42014-04-29 07:57:24 +0000107 const TargetRegisterInfo *TRI) const override;
Tom Stellardc149dc02013-11-27 21:23:35 +0000108
Benjamin Kramer8c90fd72014-09-03 11:41:21 +0000109 bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
Tom Stellardeba61072014-05-02 15:41:42 +0000110
Christian Konig3c145802013-03-27 09:12:59 +0000111 unsigned commuteOpcode(unsigned Opcode) const;
112
Craig Topper5656db42014-04-29 07:57:24 +0000113 MachineInstr *commuteInstruction(MachineInstr *MI,
Matt Arsenault92befe72014-09-26 17:54:54 +0000114 bool NewMI = false) const override;
115 bool findCommutedOpIndices(MachineInstr *MI,
116 unsigned &SrcOpIdx1,
117 unsigned &SrcOpIdx2) const override;
Christian Konig76edd4f2013-02-26 17:52:29 +0000118
Tom Stellard30f59412014-03-31 14:01:56 +0000119 bool isTriviallyReMaterializable(const MachineInstr *MI,
Craig Toppere73658d2014-04-28 04:05:08 +0000120 AliasAnalysis *AA = nullptr) const;
Tom Stellard30f59412014-03-31 14:01:56 +0000121
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +0000122 bool areMemAccessesTriviallyDisjoint(
123 MachineInstr *MIa, MachineInstr *MIb,
124 AliasAnalysis *AA = nullptr) const override;
125
Tom Stellard26a3b672013-10-22 18:19:10 +0000126 MachineInstr *buildMovInstr(MachineBasicBlock *MBB,
127 MachineBasicBlock::iterator I,
Craig Topper5656db42014-04-29 07:57:24 +0000128 unsigned DstReg, unsigned SrcReg) const override;
129 bool isMov(unsigned Opcode) const override;
Tom Stellard75aadc22012-12-11 21:25:42 +0000130
Craig Topper5656db42014-04-29 07:57:24 +0000131 bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const override;
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000132
133 bool isSALU(uint16_t Opcode) const {
134 return get(Opcode).TSFlags & SIInstrFlags::SALU;
135 }
136
137 bool isVALU(uint16_t Opcode) const {
138 return get(Opcode).TSFlags & SIInstrFlags::VALU;
139 }
140
141 bool isSOP1(uint16_t Opcode) const {
142 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
143 }
144
145 bool isSOP2(uint16_t Opcode) const {
146 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
147 }
148
149 bool isSOPC(uint16_t Opcode) const {
150 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
151 }
152
153 bool isSOPK(uint16_t Opcode) const {
154 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
155 }
156
157 bool isSOPP(uint16_t Opcode) const {
158 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
159 }
160
161 bool isVOP1(uint16_t Opcode) const {
162 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
163 }
164
165 bool isVOP2(uint16_t Opcode) const {
166 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
167 }
168
169 bool isVOP3(uint16_t Opcode) const {
170 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
171 }
172
173 bool isVOPC(uint16_t Opcode) const {
174 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
175 }
176
177 bool isMUBUF(uint16_t Opcode) const {
178 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
179 }
180
181 bool isMTBUF(uint16_t Opcode) const {
182 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
183 }
184
185 bool isSMRD(uint16_t Opcode) const {
186 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
187 }
188
189 bool isDS(uint16_t Opcode) const {
190 return get(Opcode).TSFlags & SIInstrFlags::DS;
191 }
192
193 bool isMIMG(uint16_t Opcode) const {
194 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
195 }
196
197 bool isFLAT(uint16_t Opcode) const {
198 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
199 }
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +0000200
Matt Arsenaultd7bdcc42014-03-31 19:54:27 +0000201 bool isInlineConstant(const APInt &Imm) const;
Tom Stellard93fabce2013-10-10 17:11:55 +0000202 bool isInlineConstant(const MachineOperand &MO) const;
203 bool isLiteralConstant(const MachineOperand &MO) const;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000204
Tom Stellardb02094e2014-07-21 15:45:01 +0000205 bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
206 const MachineOperand &MO) const;
207
Matt Arsenaultb2baffa2014-08-15 17:49:05 +0000208 /// \brief Return true if the given offset Size in bytes can be folded into
209 /// the immediate offsets of a memory instruction for the given address space.
210 static bool canFoldOffset(unsigned OffsetSize, unsigned AS) LLVM_READNONE;
211
Tom Stellard86d12eb2014-08-01 00:32:28 +0000212 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
213 /// This function will return false if you pass it a 32-bit instruction.
214 bool hasVALU32BitEncoding(unsigned Opcode) const;
215
Tom Stellard73ae1cb2014-09-23 21:26:25 +0000216 /// \brief Returns true if this operand uses the constant bus.
217 bool usesConstantBus(const MachineRegisterInfo &MRI,
218 const MachineOperand &MO) const;
219
Tom Stellardb4a313a2014-08-01 00:32:39 +0000220 /// \brief Return true if this instruction has any modifiers.
221 /// e.g. src[012]_mod, omod, clamp.
222 bool hasModifiers(unsigned Opcode) const;
Matt Arsenaultace5b762014-10-17 18:00:43 +0000223
224 bool hasModifiersSet(const MachineInstr &MI,
225 unsigned OpName) const;
226
Craig Topper5656db42014-04-29 07:57:24 +0000227 bool verifyInstruction(const MachineInstr *MI,
228 StringRef &ErrInfo) const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000229
Matt Arsenaultf14032a2013-11-15 22:02:28 +0000230 static unsigned getVALUOp(const MachineInstr &MI);
Matt Arsenaultf35182c2014-03-24 20:08:05 +0000231
Tom Stellard82166022013-11-13 23:36:37 +0000232 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
233
234 /// \brief Return the correct register class for \p OpNo. For target-specific
235 /// instructions, this will return the register class that has been defined
236 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
237 /// the register class of its machine operand.
238 /// to infer the correct register class base on the other operands.
239 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
240 unsigned OpNo) const;\
241
242 /// \returns true if it is legal for the operand at index \p OpNo
243 /// to read a VGPR.
244 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
245
246 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
247 /// a MOV. For example:
248 /// ADD_I32_e32 VGPR0, 15
249 /// to
250 /// MOV VGPR1, 15
251 /// ADD_I32_e32 VGPR0, VGPR1
252 ///
253 /// If the operand being legalized is a register, then a COPY will be used
254 /// instead of MOV.
255 void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
256
Tom Stellard0e975cf2014-08-01 00:32:35 +0000257 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
258 /// for \p MI.
259 bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
260 const MachineOperand *MO = nullptr) const;
261
Tom Stellard82166022013-11-13 23:36:37 +0000262 /// \brief Legalize all operands in this instruction. This function may
263 /// create new instruction and insert them before \p MI.
264 void legalizeOperands(MachineInstr *MI) const;
265
Tom Stellard745f2ed2014-08-21 20:41:00 +0000266 /// \brief Split an SMRD instruction into two smaller loads of half the
267 // size storing the results in \p Lo and \p Hi.
268 void splitSMRD(MachineInstr *MI, const TargetRegisterClass *HalfRC,
269 unsigned HalfImmOp, unsigned HalfSGPROp,
270 MachineInstr *&Lo, MachineInstr *&Hi) const;
271
Tom Stellard0c354f22014-04-30 15:31:29 +0000272 void moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) const;
273
Tom Stellard82166022013-11-13 23:36:37 +0000274 /// \brief Replace this instruction's opcode with the equivalent VALU
275 /// opcode. This function will also move the users of \p MI to the
276 /// VALU if necessary.
277 void moveToVALU(MachineInstr &MI) const;
278
Craig Topper5656db42014-04-29 07:57:24 +0000279 unsigned calculateIndirectAddress(unsigned RegIndex,
280 unsigned Channel) const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000281
Craig Topper5656db42014-04-29 07:57:24 +0000282 const TargetRegisterClass *getIndirectAddrRegClass() const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000283
Craig Topper5656db42014-04-29 07:57:24 +0000284 MachineInstrBuilder buildIndirectWrite(MachineBasicBlock *MBB,
285 MachineBasicBlock::iterator I,
286 unsigned ValueReg,
287 unsigned Address,
288 unsigned OffsetReg) const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000289
Craig Topper5656db42014-04-29 07:57:24 +0000290 MachineInstrBuilder buildIndirectRead(MachineBasicBlock *MBB,
291 MachineBasicBlock::iterator I,
292 unsigned ValueReg,
293 unsigned Address,
294 unsigned OffsetReg) const override;
Tom Stellard81d871d2013-11-13 23:36:50 +0000295 void reserveIndirectRegisters(BitVector &Reserved,
296 const MachineFunction &MF) const;
297
298 void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
299 unsigned SavReg, unsigned IndexReg) const;
Tom Stellardeba61072014-05-02 15:41:42 +0000300
301 void insertNOPs(MachineBasicBlock::iterator MI, int Count) const;
Tom Stellard1aaad692014-07-21 16:55:33 +0000302
303 /// \brief Returns the operand named \p Op. If \p MI does not have an
304 /// operand named \c Op, this function returns nullptr.
Tom Stellard6407e1e2014-08-01 00:32:33 +0000305 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
Matt Arsenaultace5b762014-10-17 18:00:43 +0000306
307 const MachineOperand *getNamedOperand(const MachineInstr &MI,
308 unsigned OpName) const {
309 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
310 }
Tom Stellard794c8c02014-12-02 17:05:41 +0000311
312 uint64_t getDefaultRsrcDataFormat() const;
313
Tom Stellard81d871d2013-11-13 23:36:50 +0000314};
Tom Stellard75aadc22012-12-11 21:25:42 +0000315
Christian Konigf741fbf2013-02-26 17:52:42 +0000316namespace AMDGPU {
317
318 int getVOPe64(uint16_t Opcode);
Tom Stellard1aaad692014-07-21 16:55:33 +0000319 int getVOPe32(uint16_t Opcode);
Christian Konig3c145802013-03-27 09:12:59 +0000320 int getCommuteRev(uint16_t Opcode);
321 int getCommuteOrig(uint16_t Opcode);
Tom Stellardc721a232014-05-16 20:56:47 +0000322 int getMCOpcode(uint16_t Opcode, unsigned Gen);
Tom Stellard155bbb72014-08-11 22:18:17 +0000323 int getAddr64Inst(uint16_t Opcode);
Matt Arsenault9903ccf2014-09-08 15:07:27 +0000324 int getAtomicRetOp(uint16_t Opcode);
325 int getAtomicNoRetOp(uint16_t Opcode);
Christian Konigf741fbf2013-02-26 17:52:42 +0000326
Tom Stellard15834092014-03-21 15:51:57 +0000327 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
Tom Stellardb02094e2014-07-21 15:45:01 +0000328 const uint64_t RSRC_TID_ENABLE = 1LL << 55;
Tom Stellard15834092014-03-21 15:51:57 +0000329
Christian Konigf741fbf2013-02-26 17:52:42 +0000330} // End namespace AMDGPU
331
Tom Stellardec2e43c2014-09-22 15:35:29 +0000332namespace SI {
333namespace KernelInputOffsets {
334
335/// Offsets in bytes from the start of the input buffer
336enum Offsets {
337 NGROUPS_X = 0,
338 NGROUPS_Y = 4,
339 NGROUPS_Z = 8,
340 GLOBAL_SIZE_X = 12,
341 GLOBAL_SIZE_Y = 16,
342 GLOBAL_SIZE_Z = 20,
343 LOCAL_SIZE_X = 24,
344 LOCAL_SIZE_Y = 28,
345 LOCAL_SIZE_Z = 32
346};
347
348} // End namespace KernelInputOffsets
349} // End namespace SI
350
Tom Stellard75aadc22012-12-11 21:25:42 +0000351} // End namespace llvm
352
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000353#endif