blob: 3aa543e27de5a25e02a41ba363670771db8d2508 [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
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000016#ifndef LLVM_LIB_TARGET_AMDGPU_SIINSTRINFO_H
17#define LLVM_LIB_TARGET_AMDGPU_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
Matt Arsenault6b6a2c32016-03-11 08:00:27 +000025class SIInstrInfo final : public AMDGPUInstrInfo {
Tom Stellard75aadc22012-12-11 21:25:42 +000026private:
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
Marek Olsakbe047802014-12-07 12:19:03 +000042 void swapOperands(MachineBasicBlock::iterator Inst) const;
43
Marek Olsak7ed6b2f2015-11-25 21:22:45 +000044 void lowerScalarAbs(SmallVectorImpl<MachineInstr *> &Worklist,
45 MachineInstr *Inst) const;
46
Matt Arsenault689f3252014-06-09 16:36:31 +000047 void splitScalar64BitUnaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
48 MachineInstr *Inst, unsigned Opcode) const;
49
50 void splitScalar64BitBinaryOp(SmallVectorImpl<MachineInstr *> &Worklist,
51 MachineInstr *Inst, unsigned Opcode) const;
Matt Arsenaultf35182c2014-03-24 20:08:05 +000052
Matt Arsenault8333e432014-06-10 19:18:24 +000053 void splitScalar64BitBCNT(SmallVectorImpl<MachineInstr *> &Worklist,
54 MachineInstr *Inst) const;
Matt Arsenault94812212014-11-14 18:18:16 +000055 void splitScalar64BitBFE(SmallVectorImpl<MachineInstr *> &Worklist,
56 MachineInstr *Inst) const;
Matt Arsenault8333e432014-06-10 19:18:24 +000057
Matt Arsenaultf003c382015-08-26 20:47:50 +000058 void addUsersToMoveToVALUWorklist(
59 unsigned Reg, MachineRegisterInfo &MRI,
60 SmallVectorImpl<MachineInstr *> &Worklist) const;
61
Tom Stellardbc4497b2016-02-12 23:45:29 +000062 void addSCCDefUsersToVALUWorklist(
63 MachineInstr *SCCDefInst, SmallVectorImpl<MachineInstr *> &Worklist) const;
64
Matt Arsenaultba6aae72015-09-28 20:54:57 +000065 const TargetRegisterClass *
66 getDestEquivalentVGPRClass(const MachineInstr &Inst) const;
67
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +000068 bool checkInstOffsetsDoNotOverlap(MachineInstr *MIa,
69 MachineInstr *MIb) const;
70
Matt Arsenaultee522bf2014-09-26 17:55:06 +000071 unsigned findUsedSGPR(const MachineInstr *MI, int OpIndices[3]) const;
72
Andrew Kaylor16c4da02015-09-28 20:33:22 +000073protected:
74 MachineInstr *commuteInstructionImpl(MachineInstr *MI,
75 bool NewMI,
76 unsigned OpIdx0,
77 unsigned OpIdx1) const override;
78
Tom Stellard75aadc22012-12-11 21:25:42 +000079public:
Tom Stellard2e59a452014-06-13 01:32:00 +000080 explicit SIInstrInfo(const AMDGPUSubtarget &st);
Tom Stellard75aadc22012-12-11 21:25:42 +000081
Craig Topper5656db42014-04-29 07:57:24 +000082 const SIRegisterInfo &getRegisterInfo() const override {
Matt Arsenault6dde3032014-03-11 00:01:34 +000083 return RI;
84 }
Tom Stellard75aadc22012-12-11 21:25:42 +000085
Matt Arsenaulta48b8662015-04-23 23:34:48 +000086 bool isReallyTriviallyReMaterializable(const MachineInstr *MI,
87 AliasAnalysis *AA) const override;
88
Matt Arsenaultc10853f2014-08-06 00:29:43 +000089 bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
90 int64_t &Offset1,
91 int64_t &Offset2) const override;
92
Sanjoy Dasb666ea32015-06-15 18:44:14 +000093 bool getMemOpBaseRegImmOfs(MachineInstr *LdSt, unsigned &BaseReg,
Chad Rosierc27a18f2016-03-09 16:00:35 +000094 int64_t &Offset,
Sanjoy Dasb666ea32015-06-15 18:44:14 +000095 const TargetRegisterInfo *TRI) const final;
Matt Arsenault1acc72f2014-07-29 21:34:55 +000096
Jun Bum Lim4c5bd582016-04-15 14:58:38 +000097 bool shouldClusterMemOps(MachineInstr *FirstLdSt,
98 MachineInstr *SecondLdSt,
99 unsigned NumLoads) const final;
Matt Arsenault0e75a062014-09-17 17:48:30 +0000100
Craig Topper5656db42014-04-29 07:57:24 +0000101 void copyPhysReg(MachineBasicBlock &MBB,
102 MachineBasicBlock::iterator MI, DebugLoc DL,
103 unsigned DestReg, unsigned SrcReg,
104 bool KillSrc) const override;
Tom Stellard75aadc22012-12-11 21:25:42 +0000105
Tom Stellard96468902014-09-24 01:33:17 +0000106 unsigned calculateLDSSpillAddress(MachineBasicBlock &MBB,
107 MachineBasicBlock::iterator MI,
108 RegScavenger *RS,
109 unsigned TmpReg,
110 unsigned Offset,
111 unsigned Size) const;
112
Tom Stellardc149dc02013-11-27 21:23:35 +0000113 void storeRegToStackSlot(MachineBasicBlock &MBB,
114 MachineBasicBlock::iterator MI,
115 unsigned SrcReg, bool isKill, int FrameIndex,
116 const TargetRegisterClass *RC,
Craig Topper5656db42014-04-29 07:57:24 +0000117 const TargetRegisterInfo *TRI) const override;
Tom Stellardc149dc02013-11-27 21:23:35 +0000118
119 void loadRegFromStackSlot(MachineBasicBlock &MBB,
120 MachineBasicBlock::iterator MI,
121 unsigned DestReg, int FrameIndex,
122 const TargetRegisterClass *RC,
Craig Topper5656db42014-04-29 07:57:24 +0000123 const TargetRegisterInfo *TRI) const override;
Tom Stellardc149dc02013-11-27 21:23:35 +0000124
Benjamin Kramer8c90fd72014-09-03 11:41:21 +0000125 bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const override;
Tom Stellardeba61072014-05-02 15:41:42 +0000126
Tom Stellardef3b8642015-01-07 19:56:17 +0000127 // \brief Returns an opcode that can be used to move a value to a \p DstRC
128 // register. If there is no hardware instruction that can store to \p
129 // DstRC, then AMDGPU::COPY is returned.
130 unsigned getMovOpcode(const TargetRegisterClass *DstRC) const;
Matt Arsenaultfa242962015-09-24 07:51:23 +0000131
132 LLVM_READONLY
Marek Olsakcfbdba22015-06-26 20:29:10 +0000133 int commuteOpcode(const MachineInstr &MI) const;
Christian Konig3c145802013-03-27 09:12:59 +0000134
Matt Arsenault92befe72014-09-26 17:54:54 +0000135 bool findCommutedOpIndices(MachineInstr *MI,
136 unsigned &SrcOpIdx1,
137 unsigned &SrcOpIdx2) const override;
Christian Konig76edd4f2013-02-26 17:52:29 +0000138
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +0000139 bool areMemAccessesTriviallyDisjoint(
140 MachineInstr *MIa, MachineInstr *MIb,
141 AliasAnalysis *AA = nullptr) const override;
142
Matt Arsenault0325d3d2015-02-21 21:29:07 +0000143 bool FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
144 unsigned Reg, MachineRegisterInfo *MRI) const final;
145
Tom Stellardf01af292015-05-09 00:56:07 +0000146 unsigned getMachineCSELookAheadLimit() const override { return 500; }
147
Tom Stellarddb5a11f2015-07-13 15:47:57 +0000148 MachineInstr *convertToThreeAddress(MachineFunction::iterator &MBB,
149 MachineBasicBlock::iterator &MI,
150 LiveVariables *LV) const override;
151
Nicolai Haehnle213e87f2016-03-21 20:28:33 +0000152 bool isSchedulingBoundary(const MachineInstr *MI,
153 const MachineBasicBlock *MBB,
154 const MachineFunction &MF) const override;
155
Matt Arsenault3add6432015-10-20 04:35:43 +0000156 static bool isSALU(const MachineInstr &MI) {
157 return MI.getDesc().TSFlags & SIInstrFlags::SALU;
158 }
159
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000160 bool isSALU(uint16_t Opcode) const {
161 return get(Opcode).TSFlags & SIInstrFlags::SALU;
162 }
163
Matt Arsenault3add6432015-10-20 04:35:43 +0000164 static bool isVALU(const MachineInstr &MI) {
165 return MI.getDesc().TSFlags & SIInstrFlags::VALU;
166 }
167
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000168 bool isVALU(uint16_t Opcode) const {
169 return get(Opcode).TSFlags & SIInstrFlags::VALU;
170 }
171
Tom Stellardcb6ba622016-04-30 00:23:06 +0000172 static bool isVMEM(const MachineInstr &MI) {
173 return isMUBUF(MI) || isMTBUF(MI) || isMIMG(MI);
174 }
175
176 bool isVMEM(uint16_t Opcode) const {
177 return isMUBUF(Opcode) || isMTBUF(Opcode) || isMIMG(Opcode);
178 }
179
Matt Arsenault3add6432015-10-20 04:35:43 +0000180 static bool isSOP1(const MachineInstr &MI) {
181 return MI.getDesc().TSFlags & SIInstrFlags::SOP1;
182 }
183
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000184 bool isSOP1(uint16_t Opcode) const {
185 return get(Opcode).TSFlags & SIInstrFlags::SOP1;
186 }
187
Matt Arsenault3add6432015-10-20 04:35:43 +0000188 static bool isSOP2(const MachineInstr &MI) {
189 return MI.getDesc().TSFlags & SIInstrFlags::SOP2;
190 }
191
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000192 bool isSOP2(uint16_t Opcode) const {
193 return get(Opcode).TSFlags & SIInstrFlags::SOP2;
194 }
195
Matt Arsenault3add6432015-10-20 04:35:43 +0000196 static bool isSOPC(const MachineInstr &MI) {
197 return MI.getDesc().TSFlags & SIInstrFlags::SOPC;
198 }
199
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000200 bool isSOPC(uint16_t Opcode) const {
201 return get(Opcode).TSFlags & SIInstrFlags::SOPC;
202 }
203
Matt Arsenault3add6432015-10-20 04:35:43 +0000204 static bool isSOPK(const MachineInstr &MI) {
205 return MI.getDesc().TSFlags & SIInstrFlags::SOPK;
206 }
207
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000208 bool isSOPK(uint16_t Opcode) const {
209 return get(Opcode).TSFlags & SIInstrFlags::SOPK;
210 }
211
Matt Arsenault3add6432015-10-20 04:35:43 +0000212 static bool isSOPP(const MachineInstr &MI) {
213 return MI.getDesc().TSFlags & SIInstrFlags::SOPP;
214 }
215
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000216 bool isSOPP(uint16_t Opcode) const {
217 return get(Opcode).TSFlags & SIInstrFlags::SOPP;
218 }
219
Matt Arsenault3add6432015-10-20 04:35:43 +0000220 static bool isVOP1(const MachineInstr &MI) {
221 return MI.getDesc().TSFlags & SIInstrFlags::VOP1;
222 }
223
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000224 bool isVOP1(uint16_t Opcode) const {
225 return get(Opcode).TSFlags & SIInstrFlags::VOP1;
226 }
227
Matt Arsenault3add6432015-10-20 04:35:43 +0000228 static bool isVOP2(const MachineInstr &MI) {
229 return MI.getDesc().TSFlags & SIInstrFlags::VOP2;
230 }
231
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000232 bool isVOP2(uint16_t Opcode) const {
233 return get(Opcode).TSFlags & SIInstrFlags::VOP2;
234 }
235
Matt Arsenault3add6432015-10-20 04:35:43 +0000236 static bool isVOP3(const MachineInstr &MI) {
237 return MI.getDesc().TSFlags & SIInstrFlags::VOP3;
238 }
239
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000240 bool isVOP3(uint16_t Opcode) const {
241 return get(Opcode).TSFlags & SIInstrFlags::VOP3;
242 }
243
Matt Arsenault3add6432015-10-20 04:35:43 +0000244 static bool isVOPC(const MachineInstr &MI) {
245 return MI.getDesc().TSFlags & SIInstrFlags::VOPC;
246 }
247
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000248 bool isVOPC(uint16_t Opcode) const {
249 return get(Opcode).TSFlags & SIInstrFlags::VOPC;
250 }
251
Matt Arsenault3add6432015-10-20 04:35:43 +0000252 static bool isMUBUF(const MachineInstr &MI) {
253 return MI.getDesc().TSFlags & SIInstrFlags::MUBUF;
254 }
255
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000256 bool isMUBUF(uint16_t Opcode) const {
257 return get(Opcode).TSFlags & SIInstrFlags::MUBUF;
258 }
259
Matt Arsenault3add6432015-10-20 04:35:43 +0000260 static bool isMTBUF(const MachineInstr &MI) {
261 return MI.getDesc().TSFlags & SIInstrFlags::MTBUF;
262 }
263
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000264 bool isMTBUF(uint16_t Opcode) const {
265 return get(Opcode).TSFlags & SIInstrFlags::MTBUF;
266 }
267
Matt Arsenault3add6432015-10-20 04:35:43 +0000268 static bool isSMRD(const MachineInstr &MI) {
269 return MI.getDesc().TSFlags & SIInstrFlags::SMRD;
270 }
271
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000272 bool isSMRD(uint16_t Opcode) const {
273 return get(Opcode).TSFlags & SIInstrFlags::SMRD;
274 }
275
Matt Arsenault3add6432015-10-20 04:35:43 +0000276 static bool isDS(const MachineInstr &MI) {
277 return MI.getDesc().TSFlags & SIInstrFlags::DS;
278 }
279
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000280 bool isDS(uint16_t Opcode) const {
281 return get(Opcode).TSFlags & SIInstrFlags::DS;
282 }
283
Matt Arsenault3add6432015-10-20 04:35:43 +0000284 static bool isMIMG(const MachineInstr &MI) {
285 return MI.getDesc().TSFlags & SIInstrFlags::MIMG;
286 }
287
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000288 bool isMIMG(uint16_t Opcode) const {
289 return get(Opcode).TSFlags & SIInstrFlags::MIMG;
290 }
291
Matt Arsenault3add6432015-10-20 04:35:43 +0000292 static bool isFLAT(const MachineInstr &MI) {
293 return MI.getDesc().TSFlags & SIInstrFlags::FLAT;
294 }
295
Matt Arsenaultc5f174d2014-12-01 15:52:46 +0000296 bool isFLAT(uint16_t Opcode) const {
297 return get(Opcode).TSFlags & SIInstrFlags::FLAT;
298 }
Matt Arsenaultc09cc3c2014-11-19 00:01:31 +0000299
Matt Arsenault3add6432015-10-20 04:35:43 +0000300 static bool isWQM(const MachineInstr &MI) {
301 return MI.getDesc().TSFlags & SIInstrFlags::WQM;
302 }
303
Michel Danzer494391b2015-02-06 02:51:20 +0000304 bool isWQM(uint16_t Opcode) const {
305 return get(Opcode).TSFlags & SIInstrFlags::WQM;
306 }
307
Matt Arsenault3add6432015-10-20 04:35:43 +0000308 static bool isVGPRSpill(const MachineInstr &MI) {
309 return MI.getDesc().TSFlags & SIInstrFlags::VGPRSpill;
310 }
311
Tom Stellarda77c3f72015-05-12 18:59:17 +0000312 bool isVGPRSpill(uint16_t Opcode) const {
313 return get(Opcode).TSFlags & SIInstrFlags::VGPRSpill;
314 }
315
Tom Stellard331f9812016-03-14 17:05:56 +0000316 static bool isDPP(const MachineInstr &MI) {
317 return MI.getDesc().TSFlags & SIInstrFlags::DPP;
318 }
319
320 bool isDPP(uint16_t Opcode) const {
321 return get(Opcode).TSFlags & SIInstrFlags::DPP;
322 }
323
Matt Arsenaultd7bdcc42014-03-31 19:54:27 +0000324 bool isInlineConstant(const APInt &Imm) const;
Matt Arsenault11a4d672015-02-13 19:05:03 +0000325 bool isInlineConstant(const MachineOperand &MO, unsigned OpSize) const;
326 bool isLiteralConstant(const MachineOperand &MO, unsigned OpSize) const;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000327
Tom Stellardb02094e2014-07-21 15:45:01 +0000328 bool isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
329 const MachineOperand &MO) const;
330
Tom Stellard86d12eb2014-08-01 00:32:28 +0000331 /// \brief Return true if this 64-bit VALU instruction has a 32-bit encoding.
332 /// This function will return false if you pass it a 32-bit instruction.
333 bool hasVALU32BitEncoding(unsigned Opcode) const;
334
Tom Stellard73ae1cb2014-09-23 21:26:25 +0000335 /// \brief Returns true if this operand uses the constant bus.
336 bool usesConstantBus(const MachineRegisterInfo &MRI,
Matt Arsenault11a4d672015-02-13 19:05:03 +0000337 const MachineOperand &MO,
338 unsigned OpSize) const;
Tom Stellard73ae1cb2014-09-23 21:26:25 +0000339
Tom Stellardb4a313a2014-08-01 00:32:39 +0000340 /// \brief Return true if this instruction has any modifiers.
341 /// e.g. src[012]_mod, omod, clamp.
342 bool hasModifiers(unsigned Opcode) const;
Matt Arsenaultace5b762014-10-17 18:00:43 +0000343
344 bool hasModifiersSet(const MachineInstr &MI,
345 unsigned OpName) const;
346
Craig Topper5656db42014-04-29 07:57:24 +0000347 bool verifyInstruction(const MachineInstr *MI,
348 StringRef &ErrInfo) const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000349
Matt Arsenaultf14032a2013-11-15 22:02:28 +0000350 static unsigned getVALUOp(const MachineInstr &MI);
Matt Arsenaultf35182c2014-03-24 20:08:05 +0000351
Tom Stellard82166022013-11-13 23:36:37 +0000352 bool isSALUOpSupportedOnVALU(const MachineInstr &MI) const;
353
354 /// \brief Return the correct register class for \p OpNo. For target-specific
355 /// instructions, this will return the register class that has been defined
356 /// in tablegen. For generic instructions, like REG_SEQUENCE it will return
357 /// the register class of its machine operand.
358 /// to infer the correct register class base on the other operands.
359 const TargetRegisterClass *getOpRegClass(const MachineInstr &MI,
Matt Arsenault11a4d672015-02-13 19:05:03 +0000360 unsigned OpNo) const;
361
362 /// \brief Return the size in bytes of the operand OpNo on the given
363 // instruction opcode.
364 unsigned getOpSize(uint16_t Opcode, unsigned OpNo) const {
365 const MCOperandInfo &OpInfo = get(Opcode).OpInfo[OpNo];
Matt Arsenault657b1cb2015-02-21 21:29:04 +0000366
367 if (OpInfo.RegClass == -1) {
368 // If this is an immediate operand, this must be a 32-bit literal.
369 assert(OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE);
370 return 4;
371 }
372
Matt Arsenault11a4d672015-02-13 19:05:03 +0000373 return RI.getRegClass(OpInfo.RegClass)->getSize();
374 }
375
376 /// \brief This form should usually be preferred since it handles operands
377 /// with unknown register classes.
378 unsigned getOpSize(const MachineInstr &MI, unsigned OpNo) const {
379 return getOpRegClass(MI, OpNo)->getSize();
380 }
Tom Stellard82166022013-11-13 23:36:37 +0000381
382 /// \returns true if it is legal for the operand at index \p OpNo
383 /// to read a VGPR.
384 bool canReadVGPR(const MachineInstr &MI, unsigned OpNo) const;
385
386 /// \brief Legalize the \p OpIndex operand of this instruction by inserting
387 /// a MOV. For example:
388 /// ADD_I32_e32 VGPR0, 15
389 /// to
390 /// MOV VGPR1, 15
391 /// ADD_I32_e32 VGPR0, VGPR1
392 ///
393 /// If the operand being legalized is a register, then a COPY will be used
394 /// instead of MOV.
395 void legalizeOpWithMove(MachineInstr *MI, unsigned OpIdx) const;
396
Tom Stellard0e975cf2014-08-01 00:32:35 +0000397 /// \brief Check if \p MO is a legal operand if it was the \p OpIdx Operand
398 /// for \p MI.
399 bool isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
400 const MachineOperand *MO = nullptr) const;
401
Matt Arsenault856d1922015-12-01 19:57:17 +0000402 /// \brief Check if \p MO would be a valid operand for the given operand
403 /// definition \p OpInfo. Note this does not attempt to validate constant bus
404 /// restrictions (e.g. literal constant usage).
405 bool isLegalVSrcOperand(const MachineRegisterInfo &MRI,
406 const MCOperandInfo &OpInfo,
407 const MachineOperand &MO) const;
408
409 /// \brief Check if \p MO (a register operand) is a legal register for the
410 /// given operand description.
411 bool isLegalRegOperand(const MachineRegisterInfo &MRI,
412 const MCOperandInfo &OpInfo,
413 const MachineOperand &MO) const;
414
415 /// \brief Legalize operands in \p MI by either commuting it or inserting a
416 /// copy of src1.
417 void legalizeOperandsVOP2(MachineRegisterInfo &MRI, MachineInstr *MI) const;
418
Matt Arsenault6005fcb2015-10-21 21:51:02 +0000419 /// \brief Fix operands in \p MI to satisfy constant bus requirements.
420 void legalizeOperandsVOP3(MachineRegisterInfo &MRI, MachineInstr *MI) const;
421
Tom Stellard1397d492016-02-11 21:45:07 +0000422 /// Copy a value from a VGPR (\p SrcReg) to SGPR. This function can only
423 /// be used when it is know that the value in SrcReg is same across all
424 /// threads in the wave.
425 /// \returns The SGPR register that \p SrcReg was copied to.
426 unsigned readlaneVGPRToSGPR(unsigned SrcReg, MachineInstr *UseMI,
427 MachineRegisterInfo &MRI) const;
428
Tom Stellard467b5b92016-02-20 00:37:25 +0000429 void legalizeOperandsSMRD(MachineRegisterInfo &MRI, MachineInstr *MI) const;
430
Tom Stellard82166022013-11-13 23:36:37 +0000431 /// \brief Legalize all operands in this instruction. This function may
432 /// create new instruction and insert them before \p MI.
433 void legalizeOperands(MachineInstr *MI) const;
434
435 /// \brief Replace this instruction's opcode with the equivalent VALU
436 /// opcode. This function will also move the users of \p MI to the
437 /// VALU if necessary.
438 void moveToVALU(MachineInstr &MI) const;
439
Craig Topper5656db42014-04-29 07:57:24 +0000440 const TargetRegisterClass *getIndirectAddrRegClass() const override;
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000441
Tom Stellard81d871d2013-11-13 23:36:50 +0000442 void reserveIndirectRegisters(BitVector &Reserved,
443 const MachineFunction &MF) const;
444
445 void LoadM0(MachineInstr *MoveRel, MachineBasicBlock::iterator I,
446 unsigned SavReg, unsigned IndexReg) const;
Tom Stellardeba61072014-05-02 15:41:42 +0000447
Tom Stellardd37630e2016-04-07 14:47:07 +0000448 void insertWaitStates(MachineBasicBlock &MBB,MachineBasicBlock::iterator MI,
449 int Count) const;
Tom Stellard1aaad692014-07-21 16:55:33 +0000450
Rafael Espindola92dd7b82016-04-30 15:18:21 +0000451 void insertNoop(MachineBasicBlock &MBB,
452 MachineBasicBlock::iterator MI) const override;
Tom Stellardcb6ba622016-04-30 00:23:06 +0000453
454 /// \brief Return the number of wait states that result from executing this
455 /// instruction.
456 unsigned getNumWaitStates(const MachineInstr &MI) const;
457
Tom Stellard1aaad692014-07-21 16:55:33 +0000458 /// \brief Returns the operand named \p Op. If \p MI does not have an
459 /// operand named \c Op, this function returns nullptr.
Matt Arsenaultf743b832015-09-25 18:09:15 +0000460 LLVM_READONLY
Tom Stellard6407e1e2014-08-01 00:32:33 +0000461 MachineOperand *getNamedOperand(MachineInstr &MI, unsigned OperandName) const;
Matt Arsenaultace5b762014-10-17 18:00:43 +0000462
Matt Arsenaultf743b832015-09-25 18:09:15 +0000463 LLVM_READONLY
Matt Arsenaultace5b762014-10-17 18:00:43 +0000464 const MachineOperand *getNamedOperand(const MachineInstr &MI,
465 unsigned OpName) const {
466 return getNamedOperand(const_cast<MachineInstr &>(MI), OpName);
467 }
Tom Stellard794c8c02014-12-02 17:05:41 +0000468
Matt Arsenaulta40450c2015-11-05 02:46:56 +0000469 /// Get required immediate operand
470 int64_t getNamedImmOperand(const MachineInstr &MI, unsigned OpName) const {
471 int Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpName);
472 return MI.getOperand(Idx).getImm();
473 }
474
Tom Stellard794c8c02014-12-02 17:05:41 +0000475 uint64_t getDefaultRsrcDataFormat() const;
Marek Olsakd1a69a22015-09-29 23:37:32 +0000476 uint64_t getScratchRsrcWords23() const;
Nicolai Haehnle02c32912016-01-13 16:10:10 +0000477
478 bool isLowLatencyInstruction(const MachineInstr *MI) const;
479 bool isHighLatencyInstruction(const MachineInstr *MI) const;
Tom Stellard2ff72622016-01-28 16:04:37 +0000480
481 /// \brief Return the descriptor of the target-specific machine instruction
482 /// that corresponds to the specified pseudo or native opcode.
483 const MCInstrDesc &getMCOpcodeFromPseudo(unsigned Opcode) const {
484 return get(pseudoToMCOpcode(Opcode));
485 }
486
487 ArrayRef<std::pair<int, const char *>>
488 getSerializableTargetIndices() const override;
489
Tom Stellardcb6ba622016-04-30 00:23:06 +0000490 ScheduleHazardRecognizer *
491 CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
492 const ScheduleDAG *DAG) const override;
493
494 ScheduleHazardRecognizer *
495 CreateTargetPostRAHazardRecognizer(const MachineFunction &MF) const override;
496
Tom Stellard81d871d2013-11-13 23:36:50 +0000497};
Tom Stellard75aadc22012-12-11 21:25:42 +0000498
Christian Konigf741fbf2013-02-26 17:52:42 +0000499namespace AMDGPU {
Matt Arsenaultfa242962015-09-24 07:51:23 +0000500 LLVM_READONLY
Christian Konigf741fbf2013-02-26 17:52:42 +0000501 int getVOPe64(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000502
503 LLVM_READONLY
Tom Stellard1aaad692014-07-21 16:55:33 +0000504 int getVOPe32(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000505
506 LLVM_READONLY
Christian Konig3c145802013-03-27 09:12:59 +0000507 int getCommuteRev(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000508
509 LLVM_READONLY
Christian Konig3c145802013-03-27 09:12:59 +0000510 int getCommuteOrig(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000511
512 LLVM_READONLY
Tom Stellard155bbb72014-08-11 22:18:17 +0000513 int getAddr64Inst(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000514
515 LLVM_READONLY
Matt Arsenault9903ccf2014-09-08 15:07:27 +0000516 int getAtomicRetOp(uint16_t Opcode);
Matt Arsenaultfa242962015-09-24 07:51:23 +0000517
518 LLVM_READONLY
Matt Arsenault9903ccf2014-09-08 15:07:27 +0000519 int getAtomicNoRetOp(uint16_t Opcode);
Christian Konigf741fbf2013-02-26 17:52:42 +0000520
Tom Stellard15834092014-03-21 15:51:57 +0000521 const uint64_t RSRC_DATA_FORMAT = 0xf00000000000LL;
Tom Stellardb02094e2014-07-21 15:45:01 +0000522 const uint64_t RSRC_TID_ENABLE = 1LL << 55;
Matt Arsenault24ee0782016-02-12 02:40:47 +0000523 const uint64_t RSRC_ELEMENT_SIZE_SHIFT = 51;
Christian Konigf741fbf2013-02-26 17:52:42 +0000524} // End namespace AMDGPU
525
Tom Stellardec2e43c2014-09-22 15:35:29 +0000526namespace SI {
527namespace KernelInputOffsets {
528
529/// Offsets in bytes from the start of the input buffer
530enum Offsets {
531 NGROUPS_X = 0,
532 NGROUPS_Y = 4,
533 NGROUPS_Z = 8,
534 GLOBAL_SIZE_X = 12,
535 GLOBAL_SIZE_Y = 16,
536 GLOBAL_SIZE_Z = 20,
537 LOCAL_SIZE_X = 24,
538 LOCAL_SIZE_Y = 28,
539 LOCAL_SIZE_Z = 32
540};
541
542} // End namespace KernelInputOffsets
543} // End namespace SI
544
Tom Stellard75aadc22012-12-11 21:25:42 +0000545} // End namespace llvm
546
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000547#endif