1//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
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//===----------------------------------------------------------------------===//
9def isCI : Predicate<"Subtarget->getGeneration() "
10                      ">= AMDGPUSubtarget::SEA_ISLANDS">;
11def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12                         "AMDGPUSubtarget::SEA_ISLANDS">,
13  AssemblerPredicate <"FeatureSeaIslands">;
14
15def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
16
17class vop {
18  field bits<9> SI3;
19  field bits<10> VI3;
20}
21
22class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
23  field bits<8> SI = si;
24  field bits<8> VI = vi;
25
26  field bits<9>  SI3 = {0, si{7-0}};
27  field bits<10> VI3 = {0, 0, vi{7-0}};
28}
29
30class vop1 <bits<8> si, bits<8> vi = si> : vop {
31  field bits<8> SI = si;
32  field bits<8> VI = vi;
33
34  field bits<9>  SI3 = {1, 1, si{6-0}};
35  field bits<10> VI3 = !add(0x140, vi);
36}
37
38class vop2 <bits<6> si, bits<6> vi = si> : vop {
39  field bits<6> SI = si;
40  field bits<6> VI = vi;
41
42  field bits<9>  SI3 = {1, 0, 0, si{5-0}};
43  field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
44}
45
46// Specify a VOP2 opcode for SI and VOP3 opcode for VI
47// that doesn't have VOP2 encoding on VI
48class vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
49  let VI3 = vi;
50}
51
52class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
53  let SI3 = si;
54  let VI3 = vi;
55}
56
57class sop1 <bits<8> si, bits<8> vi = si> {
58  field bits<8> SI = si;
59  field bits<8> VI = vi;
60}
61
62class sop2 <bits<7> si, bits<7> vi = si> {
63  field bits<7> SI = si;
64  field bits<7> VI = vi;
65}
66
67class sopk <bits<5> si, bits<5> vi = si> {
68  field bits<5> SI = si;
69  field bits<5> VI = vi;
70}
71
72// Specify an SMRD opcode for SI and SMEM opcode for VI
73
74// FIXME: This should really be bits<5> si, Tablegen crashes if
75// parameter default value is other parameter with different bit size
76class smrd<bits<8> si, bits<8> vi = si> {
77  field bits<5> SI = si{4-0};
78  field bits<8> VI = vi;
79}
80
81// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
82// in AMDGPUInstrInfo.cpp
83def SISubtarget {
84  int NONE = -1;
85  int SI = 0;
86  int VI = 1;
87}
88
89//===----------------------------------------------------------------------===//
90// SI DAG Nodes
91//===----------------------------------------------------------------------===//
92
93def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
94  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
95                      [SDNPMayLoad, SDNPMemOperand]
96>;
97
98def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
99  SDTypeProfile<0, 13,
100    [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
101     SDTCisVT<1, iAny>,   // vdata(VGPR)
102     SDTCisVT<2, i32>,    // num_channels(imm)
103     SDTCisVT<3, i32>,    // vaddr(VGPR)
104     SDTCisVT<4, i32>,    // soffset(SGPR)
105     SDTCisVT<5, i32>,    // inst_offset(imm)
106     SDTCisVT<6, i32>,    // dfmt(imm)
107     SDTCisVT<7, i32>,    // nfmt(imm)
108     SDTCisVT<8, i32>,    // offen(imm)
109     SDTCisVT<9, i32>,    // idxen(imm)
110     SDTCisVT<10, i32>,   // glc(imm)
111     SDTCisVT<11, i32>,   // slc(imm)
112     SDTCisVT<12, i32>    // tfe(imm)
113    ]>,
114  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
115>;
116
117def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
118  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
119                       SDTCisVT<3, i32>]>
120>;
121
122class SDSample<string opcode> : SDNode <opcode,
123  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>,
124                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
125>;
126
127def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
128def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
129def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
130def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
131
132def SIconstdata_ptr : SDNode<
133  "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 1, [SDTCisVT<0, i64>,
134                                                     SDTCisVT<0, i64>]>
135>;
136
137//===----------------------------------------------------------------------===//
138// PatFrags for FLAT instructions
139//===----------------------------------------------------------------------===//
140
141class flat_ld <SDPatternOperator ld> : PatFrag<(ops node:$ptr),
142                                               (ld node:$ptr), [{
143  return isFlatLoad(dyn_cast<LoadSDNode>(N)) ||
144         isGlobalLoad(dyn_cast<LoadSDNode>(N)) ||
145         isConstantLoad(cast<LoadSDNode>(N), -1);
146}]>;
147
148def flat_load : flat_ld <load>;
149def flat_az_extloadi8 : flat_ld <az_extloadi8>;
150def flat_sextloadi8 : flat_ld <sextloadi8>;
151def flat_az_extloadi16 : flat_ld <az_extloadi16>;
152def flat_sextloadi16 : flat_ld <sextloadi16>;
153
154class flat_st <SDPatternOperator st> : PatFrag<(ops node:$val, node:$ptr),
155                                               (st node:$val, node:$ptr), [{
156  return isFlatStore(dyn_cast<StoreSDNode>(N)) ||
157         isGlobalStore(dyn_cast<StoreSDNode>(N));
158}]>;
159
160def flat_store: flat_st <store>;
161def flat_truncstorei8 : flat_st <truncstorei8>;
162def flat_truncstorei16 : flat_st <truncstorei16>;
163
164
165def mubuf_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{
166	return isGlobalLoad(cast<LoadSDNode>(N)) ||
167         isConstantLoad(cast<LoadSDNode>(N), -1);
168}]>;
169
170def smrd_load : PatFrag <(ops node:$ptr), (load node:$ptr), [{
171  return isConstantLoad(cast<LoadSDNode>(N), -1) &&
172  static_cast<const SITargetLowering *>(getTargetLowering())->isMemOpUniform(N);
173}]>;
174
175//===----------------------------------------------------------------------===//
176// SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
177// to be glued to the memory instructions.
178//===----------------------------------------------------------------------===//
179
180def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
181  [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
182>;
183
184def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
185  return isLocalLoad(cast<LoadSDNode>(N));
186}]>;
187
188def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
189  return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
190         cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
191}]>;
192
193def si_load_local_align8 : Aligned8Bytes <
194  (ops node:$ptr), (si_load_local node:$ptr)
195>;
196
197def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
198  return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
199}]>;
200def si_az_extload_local : AZExtLoadBase <si_ld_local>;
201
202multiclass SIExtLoadLocal <PatFrag ld_node> {
203
204  def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
205                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
206  >;
207
208  def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
209                     [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
210  >;
211}
212
213defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
214defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
215
216def SIst_local : SDNode <"ISD::STORE", SDTStore,
217  [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
218>;
219
220def si_st_local : PatFrag <
221  (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
222  return isLocalStore(cast<StoreSDNode>(N));
223}]>;
224
225def si_store_local : PatFrag <
226  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
227  return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
228         !cast<StoreSDNode>(N)->isTruncatingStore();
229}]>;
230
231def si_store_local_align8 : Aligned8Bytes <
232  (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
233>;
234
235def si_truncstore_local : PatFrag <
236  (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
237  return cast<StoreSDNode>(N)->isTruncatingStore();
238}]>;
239
240def si_truncstore_local_i8 : PatFrag <
241  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
242  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
243}]>;
244
245def si_truncstore_local_i16 : PatFrag <
246  (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
247  return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
248}]>;
249
250def si_setcc_uniform : PatFrag <
251  (ops node:$lhs, node:$rhs, node:$cond),
252  (setcc node:$lhs, node:$rhs, node:$cond), [{
253  for (SDNode *Use : N->uses()) {
254    if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg)
255      return false;
256
257    unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
258    if (Reg != AMDGPU::SCC)
259      return false;
260  }
261  return true;
262}]>;
263
264def si_uniform_br : PatFrag <
265  (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{
266  return isUniformBr(N);
267}]>;
268
269def si_uniform_br_scc : PatFrag <
270  (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{
271  return isCBranchSCC(N);
272}]>;
273
274multiclass SIAtomicM0Glue2 <string op_name> {
275
276  def _glue : SDNode <"ISD::ATOMIC_"#op_name, SDTAtomic2,
277    [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
278  >;
279
280  def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
281}
282
283defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
284defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
285defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
286defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
287defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
288defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
289defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
290defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
291defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
292defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
293
294def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
295  [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
296>;
297
298defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
299
300// Transformation function, extract the lower 32bit of a 64bit immediate
301def LO32 : SDNodeXForm<imm, [{
302  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, SDLoc(N),
303                                   MVT::i32);
304}]>;
305
306def LO32f : SDNodeXForm<fpimm, [{
307  APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
308  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
309}]>;
310
311// Transformation function, extract the upper 32bit of a 64bit immediate
312def HI32 : SDNodeXForm<imm, [{
313  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, SDLoc(N), MVT::i32);
314}]>;
315
316def HI32f : SDNodeXForm<fpimm, [{
317  APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
318  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), SDLoc(N),
319                                     MVT::f32);
320}]>;
321
322def IMM8bitDWORD : PatLeaf <(imm),
323  [{return (N->getZExtValue() & ~0x3FC) == 0;}]
324>;
325
326def as_dword_i32imm : SDNodeXForm<imm, [{
327  return CurDAG->getTargetConstant(N->getZExtValue() >> 2, SDLoc(N), MVT::i32);
328}]>;
329
330def as_i1imm : SDNodeXForm<imm, [{
331  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
332}]>;
333
334def as_i8imm : SDNodeXForm<imm, [{
335  return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
336}]>;
337
338def as_i16imm : SDNodeXForm<imm, [{
339  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
340}]>;
341
342def as_i32imm: SDNodeXForm<imm, [{
343  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
344}]>;
345
346def as_i64imm: SDNodeXForm<imm, [{
347  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
348}]>;
349
350// Copied from the AArch64 backend:
351def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
352return CurDAG->getTargetConstant(
353  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
354}]>;
355
356// Copied from the AArch64 backend:
357def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
358return CurDAG->getTargetConstant(
359  N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
360}]>;
361
362def IMM8bit : PatLeaf <(imm),
363  [{return isUInt<8>(N->getZExtValue());}]
364>;
365
366def IMM12bit : PatLeaf <(imm),
367  [{return isUInt<12>(N->getZExtValue());}]
368>;
369
370def IMM16bit : PatLeaf <(imm),
371  [{return isUInt<16>(N->getZExtValue());}]
372>;
373
374def SIMM16bit : PatLeaf <(imm),
375  [{return isInt<16>(N->getSExtValue());}]
376>;
377
378def IMM20bit : PatLeaf <(imm),
379  [{return isUInt<20>(N->getZExtValue());}]
380>;
381
382def IMM32bit : PatLeaf <(imm),
383  [{return isUInt<32>(N->getZExtValue());}]
384>;
385
386def mubuf_vaddr_offset : PatFrag<
387  (ops node:$ptr, node:$offset, node:$imm_offset),
388  (add (add node:$ptr, node:$offset), node:$imm_offset)
389>;
390
391class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
392  return isInlineImmediate(N);
393}]>;
394
395class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
396  return isInlineImmediate(N);
397}]>;
398
399class SGPRImm <dag frag> : PatLeaf<frag, [{
400  if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) {
401    return false;
402  }
403  const SIRegisterInfo *SIRI =
404      static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
405  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
406                                                U != E; ++U) {
407    const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo());
408    if (RC && SIRI->isSGPRClass(RC))
409      return true;
410  }
411  return false;
412}]>;
413
414//===----------------------------------------------------------------------===//
415// Custom Operands
416//===----------------------------------------------------------------------===//
417
418def FRAMEri32 : Operand<iPTR> {
419  let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
420}
421
422def SoppBrTarget : AsmOperandClass {
423  let Name = "SoppBrTarget";
424  let ParserMethod = "parseSOppBrTarget";
425}
426
427def sopp_brtarget : Operand<OtherVT> {
428  let EncoderMethod = "getSOPPBrEncoding";
429  let OperandType = "OPERAND_PCREL";
430  let ParserMatchClass = SoppBrTarget;
431}
432
433def const_ga : Operand<iPTR>;
434
435include "SIInstrFormats.td"
436include "VIInstrFormats.td"
437
438def MubufOffsetMatchClass : AsmOperandClass {
439  let Name = "MubufOffset";
440  let ParserMethod = "parseMubufOptionalOps";
441  let RenderMethod = "addImmOperands";
442  let IsOptional = 1;
443}
444
445class DSOffsetBaseMatchClass <string parser> : AsmOperandClass {
446  let Name = "DSOffset"#parser;
447  let ParserMethod = parser;
448  let RenderMethod = "addImmOperands";
449  let PredicateMethod = "isDSOffset";
450  let IsOptional = 1;
451}
452
453def DSOffsetMatchClass : DSOffsetBaseMatchClass <"parseDSOptionalOps">;
454def DSOffsetGDSMatchClass : DSOffsetBaseMatchClass <"parseDSOffsetOptional">;
455
456def DSOffset01MatchClass : AsmOperandClass {
457  let Name = "DSOffset1";
458  let ParserMethod = "parseDSOff01OptionalOps";
459  let RenderMethod = "addImmOperands";
460  let PredicateMethod = "isDSOffset01";
461  let IsOptional = 1;
462}
463
464class GDSBaseMatchClass <string parser> : AsmOperandClass {
465  let Name = "GDS"#parser;
466  let PredicateMethod = "isGDS";
467  let ParserMethod = parser;
468  let RenderMethod = "addImmOperands";
469  let IsOptional = 1;
470}
471
472def GDSMatchClass : GDSBaseMatchClass <"parseDSOptionalOps">;
473def GDS01MatchClass : GDSBaseMatchClass <"parseDSOff01OptionalOps">;
474
475class GLCBaseMatchClass <string parser> : AsmOperandClass {
476  let Name = "GLC"#parser;
477  let PredicateMethod = "isGLC";
478  let ParserMethod = parser;
479  let RenderMethod = "addImmOperands";
480  let IsOptional = 1;
481}
482
483def GLCMubufMatchClass : GLCBaseMatchClass <"parseMubufOptionalOps">;
484def GLCFlatMatchClass : GLCBaseMatchClass <"parseFlatOptionalOps">;
485
486class SLCBaseMatchClass <string parser> : AsmOperandClass {
487  let Name = "SLC"#parser;
488  let PredicateMethod = "isSLC";
489  let ParserMethod = parser;
490  let RenderMethod = "addImmOperands";
491  let IsOptional = 1;
492}
493
494def SLCMubufMatchClass : SLCBaseMatchClass <"parseMubufOptionalOps">;
495def SLCFlatMatchClass : SLCBaseMatchClass <"parseFlatOptionalOps">;
496def SLCFlatAtomicMatchClass : SLCBaseMatchClass <"parseFlatAtomicOptionalOps">;
497
498class TFEBaseMatchClass <string parser> : AsmOperandClass {
499  let Name = "TFE"#parser;
500  let PredicateMethod = "isTFE";
501  let ParserMethod = parser;
502  let RenderMethod = "addImmOperands";
503  let IsOptional = 1;
504}
505
506def TFEMubufMatchClass : TFEBaseMatchClass <"parseMubufOptionalOps">;
507def TFEFlatMatchClass : TFEBaseMatchClass <"parseFlatOptionalOps">;
508def TFEFlatAtomicMatchClass : TFEBaseMatchClass <"parseFlatAtomicOptionalOps">;
509
510def OModMatchClass : AsmOperandClass {
511  let Name = "OMod";
512  let PredicateMethod = "isOMod";
513  let ParserMethod = "parseVOP3OptionalOps";
514  let RenderMethod = "addImmOperands";
515  let IsOptional = 1;
516}
517
518def ClampMatchClass : AsmOperandClass {
519  let Name = "Clamp";
520  let PredicateMethod = "isClamp";
521  let ParserMethod = "parseVOP3OptionalOps";
522  let RenderMethod = "addImmOperands";
523  let IsOptional = 1;
524}
525
526class SMRDOffsetBaseMatchClass <string predicate> : AsmOperandClass {
527  let Name = "SMRDOffset"#predicate;
528  let PredicateMethod = predicate;
529  let RenderMethod = "addImmOperands";
530}
531
532def SMRDOffsetMatchClass : SMRDOffsetBaseMatchClass <"isSMRDOffset">;
533def SMRDLiteralOffsetMatchClass : SMRDOffsetBaseMatchClass <
534  "isSMRDLiteralOffset"
535>;
536
537def DPPCtrlMatchClass : AsmOperandClass {
538  let Name = "DPPCtrl";
539  let PredicateMethod = "isDPPCtrl";
540  let ParserMethod = "parseDPPCtrlOps";
541  let RenderMethod = "addImmOperands";
542  let IsOptional = 0;
543}
544
545class DPPOptionalMatchClass <string OpName>: AsmOperandClass {
546  let Name = "DPPOptional"#OpName;
547  let PredicateMethod = "is"#OpName;
548  let ParserMethod = "parseDPPOptionalOps";
549  let RenderMethod = "addImmOperands";
550  let IsOptional = 1;
551}
552
553class OptionalImmAsmOperand <string OpName> : AsmOperandClass {
554  let Name = "Imm"#OpName;
555  let PredicateMethod = "isImm";
556  let RenderMethod = "addImmOperands";
557  let IsOptional = 1;
558}
559
560def DMaskMatchClass : AsmOperandClass {
561  let Name = "DMask";
562  let PredicateMethod = "isDMask";
563  let ParserMethod = "parseDMask";
564  let RenderMethod = "addImmOperands";
565  let IsOptional = 1;
566}
567
568class NamedBitMatchClass<string BitName> : AsmOperandClass {
569  let Name = "Imm"#BitName;
570  let PredicateMethod = "is"#BitName;
571  let ParserMethod = "parse"#BitName;
572  let RenderMethod = "addImmOperands";
573  let IsOptional = 1;
574}
575
576class NamedBitOperand<string BitName> : Operand<i1> {
577  let PrintMethod = "print"#BitName;
578}
579
580let OperandType = "OPERAND_IMMEDIATE" in {
581
582def offen : Operand<i1> {
583  let PrintMethod = "printOffen";
584  let ParserMatchClass = OptionalImmAsmOperand<"offen">;
585}
586def idxen : Operand<i1> {
587  let PrintMethod = "printIdxen";
588  let ParserMatchClass = OptionalImmAsmOperand<"idxen">;
589}
590def addr64 : Operand<i1> {
591  let PrintMethod = "printAddr64";
592}
593def mbuf_offset : Operand<i16> {
594  let PrintMethod = "printMBUFOffset";
595  let ParserMatchClass = MubufOffsetMatchClass;
596}
597class ds_offset_base <AsmOperandClass mc> : Operand<i16> {
598  let PrintMethod = "printDSOffset";
599  let ParserMatchClass = mc;
600}
601def ds_offset : ds_offset_base <DSOffsetMatchClass>;
602def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>;
603
604def ds_offset0 : Operand<i8> {
605  let PrintMethod = "printDSOffset0";
606  let ParserMatchClass = DSOffset01MatchClass;
607}
608def ds_offset1 : Operand<i8> {
609  let PrintMethod = "printDSOffset1";
610  let ParserMatchClass = DSOffset01MatchClass;
611}
612class gds_base <AsmOperandClass mc> : Operand <i1> {
613  let PrintMethod = "printGDS";
614  let ParserMatchClass = mc;
615}
616def gds : gds_base <GDSMatchClass>;
617
618def gds01 : gds_base <GDS01MatchClass>;
619
620class glc_base <AsmOperandClass mc> : Operand <i1> {
621  let PrintMethod = "printGLC";
622  let ParserMatchClass = mc;
623}
624
625def glc : glc_base <GLCMubufMatchClass>;
626def glc_flat : glc_base <GLCFlatMatchClass>;
627
628class slc_base <AsmOperandClass mc> : Operand <i1> {
629  let PrintMethod = "printSLC";
630  let ParserMatchClass = mc;
631}
632
633def slc : slc_base <SLCMubufMatchClass>;
634def slc_flat : slc_base <SLCFlatMatchClass>;
635def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>;
636
637class tfe_base <AsmOperandClass mc> : Operand <i1> {
638  let PrintMethod = "printTFE";
639  let ParserMatchClass = mc;
640}
641
642def tfe : tfe_base <TFEMubufMatchClass>;
643def tfe_flat : tfe_base <TFEFlatMatchClass>;
644def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>;
645
646def omod : Operand <i32> {
647  let PrintMethod = "printOModSI";
648  let ParserMatchClass = OModMatchClass;
649}
650
651def ClampMod : Operand <i1> {
652  let PrintMethod = "printClampSI";
653  let ParserMatchClass = ClampMatchClass;
654}
655
656def smrd_offset : Operand <i32> {
657  let PrintMethod = "printU32ImmOperand";
658  let ParserMatchClass = SMRDOffsetMatchClass;
659}
660
661def smrd_literal_offset : Operand <i32> {
662  let PrintMethod = "printU32ImmOperand";
663  let ParserMatchClass = SMRDLiteralOffsetMatchClass;
664}
665
666def dmask : Operand <i32> {
667  let PrintMethod = "printDMask";
668  let ParserMatchClass = DMaskMatchClass;
669}
670
671def unorm : NamedBitOperand<"UNorm"> {
672  let ParserMatchClass = NamedBitMatchClass<"UNorm">;
673}
674
675def da : NamedBitOperand<"DA"> {
676  let ParserMatchClass = NamedBitMatchClass<"DA">;
677}
678
679def r128 : NamedBitOperand<"R128"> {
680  let ParserMatchClass = NamedBitMatchClass<"R128">;
681}
682
683def lwe : NamedBitOperand<"LWE"> {
684  let ParserMatchClass = NamedBitMatchClass<"LWE">;
685}
686
687def dpp_ctrl : Operand <i32> {
688  let PrintMethod = "printDPPCtrlOperand";
689  let ParserMatchClass = DPPCtrlMatchClass;
690}
691
692def row_mask : Operand <i32> {
693  let PrintMethod = "printRowMaskOperand";
694  let ParserMatchClass = DPPOptionalMatchClass<"RowMask">;
695}
696
697def bank_mask : Operand <i32> {
698  let PrintMethod = "printBankMaskOperand";
699  let ParserMatchClass = DPPOptionalMatchClass<"BankMask">;
700}
701
702def bound_ctrl : Operand <i1> {
703  let PrintMethod = "printBoundCtrlOperand";
704  let ParserMatchClass = DPPOptionalMatchClass<"BoundCtrl">;
705}
706
707} // End OperandType = "OPERAND_IMMEDIATE"
708
709
710def VOPDstS64 : VOPDstOperand <SReg_64>;
711
712//===----------------------------------------------------------------------===//
713// Complex patterns
714//===----------------------------------------------------------------------===//
715
716def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
717def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
718
719def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
720def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
721def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
722def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
723def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
724def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
725def MUBUFIntrinsicOffset : ComplexPattern<i32, 2, "SelectMUBUFIntrinsicOffset">;
726def MUBUFIntrinsicVOffset : ComplexPattern<i32, 3, "SelectMUBUFIntrinsicVOffset">;
727
728def SMRDImm   : ComplexPattern<i64, 2, "SelectSMRDImm">;
729def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
730def SMRDSgpr  : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
731def SMRDBufferImm   : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
732def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
733def SMRDBufferSgpr  : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
734
735def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
736def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
737def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
738def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
739def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
740def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
741
742//===----------------------------------------------------------------------===//
743// SI assembler operands
744//===----------------------------------------------------------------------===//
745
746def SIOperand {
747  int ZERO = 0x80;
748  int VCC = 0x6A;
749  int FLAT_SCR = 0x68;
750}
751
752def SRCMODS {
753  int NONE = 0;
754  int NEG = 1;
755}
756
757def DSTCLAMP {
758  int NONE = 0;
759}
760
761def DSTOMOD {
762  int NONE = 0;
763}
764
765//===----------------------------------------------------------------------===//
766//
767// SI Instruction multiclass helpers.
768//
769// Instructions with _32 take 32-bit operands.
770// Instructions with _64 take 64-bit operands.
771//
772// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
773// encoding is the standard encoding, but instruction that make use of
774// any of the instruction modifiers must use the 64-bit encoding.
775//
776// Instructions with _e32 use the 32-bit encoding.
777// Instructions with _e64 use the 64-bit encoding.
778//
779//===----------------------------------------------------------------------===//
780
781class SIMCInstr <string pseudo, int subtarget> {
782  string PseudoInstr = pseudo;
783  int Subtarget = subtarget;
784}
785
786//===----------------------------------------------------------------------===//
787// EXP classes
788//===----------------------------------------------------------------------===//
789
790class EXPCommon : InstSI<
791  (outs),
792  (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
793       VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
794  "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
795  [] > {
796
797  let EXP_CNT = 1;
798  let Uses = [EXEC];
799}
800
801multiclass EXP_m {
802
803  let isPseudo = 1, isCodeGenOnly = 1 in {
804    def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
805  }
806
807  def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe {
808    let DecoderNamespace="SICI";
809    let DisableDecoder = DisableSIDecoder;
810  }
811
812  def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi {
813    let DecoderNamespace="VI";
814    let DisableDecoder = DisableVIDecoder;
815  }
816}
817
818//===----------------------------------------------------------------------===//
819// Scalar classes
820//===----------------------------------------------------------------------===//
821
822class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
823  SOP1 <outs, ins, "", pattern>,
824  SIMCInstr<opName, SISubtarget.NONE> {
825  let isPseudo = 1;
826  let isCodeGenOnly = 1;
827}
828
829class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
830  SOP1 <outs, ins, asm, []>,
831  SOP1e <op.SI>,
832  SIMCInstr<opName, SISubtarget.SI> {
833  let isCodeGenOnly = 0;
834  let AssemblerPredicates = [isSICI];
835  let DecoderNamespace = "SICI";
836  let DisableDecoder = DisableSIDecoder;
837}
838
839class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
840  SOP1 <outs, ins, asm, []>,
841  SOP1e <op.VI>,
842  SIMCInstr<opName, SISubtarget.VI> {
843  let isCodeGenOnly = 0;
844  let AssemblerPredicates = [isVI];
845  let DecoderNamespace = "VI";
846  let DisableDecoder = DisableVIDecoder;
847}
848
849multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm,
850                   list<dag> pattern> {
851
852  def "" : SOP1_Pseudo <opName, outs, ins, pattern>;
853
854  def _si : SOP1_Real_si <op, opName, outs, ins, asm>;
855
856  def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>;
857
858}
859
860multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
861    op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0),
862    opName#" $sdst, $src0", pattern
863>;
864
865multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
866    op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0),
867    opName#" $sdst, $src0", pattern
868>;
869
870// no input, 64-bit output.
871multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
872  def "" : SOP1_Pseudo <opName, (outs SReg_64:$sdst), (ins), pattern>;
873
874  def _si : SOP1_Real_si <op, opName, (outs SReg_64:$sdst), (ins),
875    opName#" $sdst"> {
876    let src0 = 0;
877  }
878
879  def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$sdst), (ins),
880    opName#" $sdst"> {
881    let src0 = 0;
882  }
883}
884
885// 64-bit input, no output
886multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
887  def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
888
889  def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
890    opName#" $src0"> {
891    let sdst = 0;
892  }
893
894  def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
895    opName#" $src0"> {
896    let sdst = 0;
897  }
898}
899
900// 64-bit input, 32-bit output.
901multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
902    op, opName, (outs SReg_32:$sdst), (ins SSrc_64:$src0),
903    opName#" $sdst, $src0", pattern
904>;
905
906// 32-bit input, 64-bit output.
907multiclass SOP1_64_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
908    op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0),
909    opName#" $sdst, $src0", pattern
910>;
911
912class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
913  SOP2<outs, ins, "", pattern>,
914  SIMCInstr<opName, SISubtarget.NONE> {
915  let isPseudo = 1;
916  let isCodeGenOnly = 1;
917  let Size = 4;
918
919  // Pseudo instructions have no encodings, but adding this field here allows
920  // us to do:
921  // let sdst = xxx in {
922  // for multiclasses that include both real and pseudo instructions.
923  field bits<7> sdst = 0;
924}
925
926class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
927  SOP2<outs, ins, asm, []>,
928  SOP2e<op.SI>,
929  SIMCInstr<opName, SISubtarget.SI> {
930  let AssemblerPredicates = [isSICI];
931  let DecoderNamespace = "SICI";
932  let DisableDecoder = DisableSIDecoder;
933}
934
935class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
936  SOP2<outs, ins, asm, []>,
937  SOP2e<op.VI>,
938  SIMCInstr<opName, SISubtarget.VI> {
939  let AssemblerPredicates = [isVI];
940  let DecoderNamespace = "VI";
941  let DisableDecoder = DisableVIDecoder;
942}
943
944multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm,
945                   list<dag> pattern> {
946
947  def "" : SOP2_Pseudo <opName, outs, ins, pattern>;
948
949  def _si : SOP2_Real_si <op, opName, outs, ins, asm>;
950
951  def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>;
952
953}
954
955multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
956    op, opName, (outs SReg_32:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1),
957    opName#" $sdst, $src0, $src1", pattern
958>;
959
960multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
961    op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_64:$src1),
962    opName#" $sdst, $src0, $src1", pattern
963>;
964
965multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
966    op, opName, (outs SReg_64:$sdst), (ins SSrc_64:$src0, SSrc_32:$src1),
967    opName#" $sdst, $src0, $src1", pattern
968>;
969
970multiclass SOP2_64_32_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
971    op, opName, (outs SReg_64:$sdst), (ins SSrc_32:$src0, SSrc_32:$src1),
972    opName#" $sdst, $src0, $src1", pattern
973>;
974
975class SOPC_Base <bits<7> op, RegisterOperand rc0, RegisterOperand rc1,
976                 string opName, list<dag> pattern = []> : SOPC <
977  op, (outs), (ins rc0:$src0, rc1:$src1),
978  opName#" $src0, $src1", pattern > {
979  let Defs = [SCC];
980}
981class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
982                    string opName, PatLeaf cond> : SOPC_Base <
983  op, rc, rc, opName,
984  [(set SCC, (si_setcc_uniform vt:$src0, vt:$src1, cond))] > {
985}
986
987class SOPC_CMP_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
988  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
989
990class SOPC_32<bits<7> op, string opName, list<dag> pattern = []>
991  : SOPC_Base<op, SSrc_32, SSrc_32, opName, pattern>;
992
993class SOPC_64_32<bits<7> op, string opName, list<dag> pattern = []>
994  : SOPC_Base<op, SSrc_64, SSrc_32, opName, pattern>;
995
996class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
997  SOPK <outs, ins, "", pattern>,
998  SIMCInstr<opName, SISubtarget.NONE> {
999  let isPseudo = 1;
1000  let isCodeGenOnly = 1;
1001}
1002
1003class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
1004  SOPK <outs, ins, asm, []>,
1005  SOPKe <op.SI>,
1006  SIMCInstr<opName, SISubtarget.SI> {
1007  let AssemblerPredicates = [isSICI];
1008  let DecoderNamespace = "SICI";
1009  let DisableDecoder = DisableSIDecoder;
1010  let isCodeGenOnly = 0;
1011}
1012
1013class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
1014  SOPK <outs, ins, asm, []>,
1015  SOPKe <op.VI>,
1016  SIMCInstr<opName, SISubtarget.VI> {
1017  let AssemblerPredicates = [isVI];
1018  let DecoderNamespace = "VI";
1019  let DisableDecoder = DisableVIDecoder;
1020  let isCodeGenOnly = 0;
1021}
1022
1023multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm,
1024                   string asm = opName#opAsm> {
1025  def "" : SOPK_Pseudo <opName, outs, ins, []>;
1026
1027  def _si : SOPK_Real_si <op, opName, outs, ins, asm>;
1028
1029  def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>;
1030
1031}
1032
1033multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
1034  def "" : SOPK_Pseudo <opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
1035    pattern>;
1036
1037  def _si : SOPK_Real_si <op, opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
1038    opName#" $sdst, $simm16">;
1039
1040  def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$sdst), (ins u16imm:$simm16),
1041    opName#" $sdst, $simm16">;
1042}
1043
1044multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
1045  def "" : SOPK_Pseudo <opName, (outs),
1046    (ins SReg_32:$src0, u16imm:$src1), pattern> {
1047    let Defs = [SCC];
1048  }
1049
1050
1051  def _si : SOPK_Real_si <op, opName, (outs),
1052    (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
1053    let Defs = [SCC];
1054  }
1055
1056  def _vi : SOPK_Real_vi <op, opName, (outs),
1057    (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
1058    let Defs = [SCC];
1059  }
1060}
1061
1062multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m <
1063  op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16),
1064  " $sdst, $simm16"
1065>;
1066
1067multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins,
1068                       string argAsm, string asm = opName#argAsm> {
1069
1070  def "" : SOPK_Pseudo <opName, outs, ins, []>;
1071
1072  def _si : SOPK <outs, ins, asm, []>,
1073            SOPK64e <op.SI>,
1074            SIMCInstr<opName, SISubtarget.SI> {
1075              let AssemblerPredicates = [isSICI];
1076              let DecoderNamespace = "SICI";
1077              let DisableDecoder = DisableSIDecoder;
1078              let isCodeGenOnly = 0;
1079            }
1080
1081  def _vi : SOPK <outs, ins, asm, []>,
1082            SOPK64e <op.VI>,
1083            SIMCInstr<opName, SISubtarget.VI> {
1084              let AssemblerPredicates = [isVI];
1085              let DecoderNamespace = "VI";
1086              let DisableDecoder = DisableVIDecoder;
1087              let isCodeGenOnly = 0;
1088            }
1089}
1090//===----------------------------------------------------------------------===//
1091// SMRD classes
1092//===----------------------------------------------------------------------===//
1093
1094class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1095  SMRD <outs, ins, "", pattern>,
1096  SIMCInstr<opName, SISubtarget.NONE> {
1097  let isPseudo = 1;
1098  let isCodeGenOnly = 1;
1099}
1100
1101class SMRD_IMM_Real_si <bits<5> op, string opName, dag outs, dag ins,
1102                        string asm> :
1103  SMRD <outs, ins, asm, []>,
1104  SMRD_IMMe <op>,
1105  SIMCInstr<opName, SISubtarget.SI> {
1106  let AssemblerPredicates = [isSICI];
1107  let DecoderNamespace = "SICI";
1108  let DisableDecoder = DisableSIDecoder;
1109}
1110
1111class SMRD_SOFF_Real_si <bits<5> op, string opName, dag outs, dag ins,
1112                         string asm> :
1113  SMRD <outs, ins, asm, []>,
1114  SMRD_SOFFe <op>,
1115  SIMCInstr<opName, SISubtarget.SI> {
1116  let AssemblerPredicates = [isSICI];
1117  let DecoderNamespace = "SICI";
1118  let DisableDecoder = DisableSIDecoder;
1119}
1120
1121
1122class SMRD_IMM_Real_vi <bits<8> op, string opName, dag outs, dag ins,
1123                        string asm, list<dag> pattern = []> :
1124  SMRD <outs, ins, asm, pattern>,
1125  SMEM_IMMe_vi <op>,
1126  SIMCInstr<opName, SISubtarget.VI> {
1127  let AssemblerPredicates = [isVI];
1128  let DecoderNamespace = "VI";
1129  let DisableDecoder = DisableVIDecoder;
1130}
1131
1132class SMRD_SOFF_Real_vi <bits<8> op, string opName, dag outs, dag ins,
1133                         string asm, list<dag> pattern = []> :
1134  SMRD <outs, ins, asm, pattern>,
1135  SMEM_SOFFe_vi <op>,
1136  SIMCInstr<opName, SISubtarget.VI> {
1137  let AssemblerPredicates = [isVI];
1138  let DecoderNamespace = "VI";
1139  let DisableDecoder = DisableVIDecoder;
1140}
1141
1142
1143multiclass SMRD_IMM_m <smrd op, string opName, dag outs, dag ins,
1144                   string asm, list<dag> pattern> {
1145
1146  def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
1147
1148  def _si : SMRD_IMM_Real_si <op.SI, opName, outs, ins, asm>;
1149
1150  // glc is only applicable to scalar stores, which are not yet
1151  // implemented.
1152  let glc = 0 in {
1153    def _vi : SMRD_IMM_Real_vi <op.VI, opName, outs, ins, asm>;
1154  }
1155}
1156
1157multiclass SMRD_SOFF_m <smrd op, string opName, dag outs, dag ins,
1158                        string asm, list<dag> pattern> {
1159
1160  def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
1161
1162  def _si : SMRD_SOFF_Real_si <op.SI, opName, outs, ins, asm>;
1163
1164  // glc is only applicable to scalar stores, which are not yet
1165  // implemented.
1166  let glc = 0 in {
1167    def _vi : SMRD_SOFF_Real_vi <op.VI, opName, outs, ins, asm>;
1168  }
1169}
1170
1171multiclass SMRD_Special <smrd op, string opName, dag outs,
1172                       int sdst_ = ?,
1173                       string opStr = "",
1174                       list<dag> pattern = []> {
1175  let hasSideEffects = 1 in {
1176    def "" : SMRD_Pseudo <opName, outs, (ins), pattern>;
1177
1178    let sbase = 0, soff = 0, sdst = sdst_ in {
1179      def _si : SMRD_SOFF_Real_si <op.SI, opName, outs, (ins), opName#opStr>;
1180
1181      let glc = 0 in {
1182        def _vi : SMRD_SOFF_Real_vi <op.VI, opName, outs, (ins), opName#opStr>;
1183      }
1184    }
1185  }
1186}
1187
1188multiclass SMRD_Inval <smrd op, string opName,
1189                     SDPatternOperator node> {
1190  let mayStore = 1 in {
1191    defm : SMRD_Special<op, opName, (outs), 0, "", [(node)]>;
1192  }
1193}
1194
1195class SMEM_Inval <bits<8> op, string opName, SDPatternOperator node> :
1196  SMRD_SOFF_Real_vi<op, opName, (outs), (ins), opName, [(node)]> {
1197  let hasSideEffects = 1;
1198  let mayStore = 1;
1199  let sbase = 0;
1200  let sdst = 0;
1201  let glc = 0;
1202  let soff = 0;
1203}
1204
1205class SMEM_Ret <bits<8> op, string opName, SDPatternOperator node> :
1206  SMRD_SOFF_Real_vi<op, opName, (outs SReg_64:$sdst), (ins),
1207  opName#" $sdst", [(set i64:$sdst, (node))]> {
1208  let hasSideEffects = 1;
1209  let mayStore = ?;
1210  let mayLoad = ?;
1211  let sbase = 0;
1212  let glc = 0;
1213  let soff = 0;
1214}
1215
1216multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass,
1217                        RegisterClass dstClass> {
1218  defm _IMM : SMRD_IMM_m <
1219    op, opName#"_IMM", (outs dstClass:$sdst),
1220    (ins baseClass:$sbase, smrd_offset:$offset),
1221    opName#" $sdst, $sbase, $offset", []
1222  >;
1223
1224  def _IMM_ci : SMRD <
1225    (outs dstClass:$sdst), (ins baseClass:$sbase, smrd_literal_offset:$offset),
1226    opName#" $sdst, $sbase, $offset", []>, SMRD_IMMe_ci <op.SI> {
1227    let AssemblerPredicates = [isCIOnly];
1228    let DecoderNamespace = "CI";
1229  }
1230
1231  defm _SGPR : SMRD_SOFF_m <
1232    op, opName#"_SGPR", (outs dstClass:$sdst),
1233    (ins baseClass:$sbase, SReg_32:$soff),
1234    opName#" $sdst, $sbase, $soff", []
1235  >;
1236}
1237
1238//===----------------------------------------------------------------------===//
1239// Vector ALU classes
1240//===----------------------------------------------------------------------===//
1241
1242// This must always be right before the operand being input modified.
1243def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
1244  let PrintMethod = "printOperandAndMods";
1245}
1246
1247def InputModsMatchClass : AsmOperandClass {
1248  let Name = "RegOrImmWithInputMods";
1249}
1250
1251def InputModsNoDefault : Operand <i32> {
1252  let PrintMethod = "printOperandAndMods";
1253  let ParserMatchClass = InputModsMatchClass;
1254}
1255
1256class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
1257  int ret =
1258    !if (!eq(Src0.Value, untyped.Value),      0,
1259      !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
1260         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
1261                                              3))); // VOP3
1262}
1263
1264// Returns the register class to use for the destination of VOP[123C]
1265// instructions for the given VT.
1266class getVALUDstForVT<ValueType VT> {
1267  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
1268                          !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
1269                            !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
1270                            VOPDstOperand<SReg_64>))); // else VT == i1
1271}
1272
1273// Returns the register class to use for source 0 of VOP[12C]
1274// instructions for the given VT.
1275class getVOPSrc0ForVT<ValueType VT> {
1276  RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32);
1277}
1278
1279// Returns the register class to use for source 1 of VOP[12C] for the
1280// given VT.
1281class getVOPSrc1ForVT<ValueType VT> {
1282  RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
1283}
1284
1285// Returns the register class to use for DPP source operands.
1286class getDPPSrcForVT<ValueType VT> {
1287  RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
1288}
1289
1290// Returns the register class to use for sources of VOP3 instructions for the
1291// given VT.
1292class getVOP3SrcForVT<ValueType VT> {
1293  RegisterOperand ret =
1294  !if(!eq(VT.Size, 64),
1295      VCSrc_64,
1296      !if(!eq(VT.Value, i1.Value),
1297          SCSrc_64,
1298          VCSrc_32
1299       )
1300    );
1301}
1302
1303// Returns 1 if the source arguments have modifiers, 0 if they do not.
1304// XXX - do f16 instructions?
1305class hasModifiers<ValueType SrcVT> {
1306  bit ret =
1307    !if(!eq(SrcVT.Value, f32.Value), 1,
1308    !if(!eq(SrcVT.Value, f64.Value), 1,
1309    0));
1310}
1311
1312// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1313class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1314  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1315            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1316                                    (ins)));
1317}
1318
1319// Returns the input arguments for VOP3 instructions for the given SrcVT.
1320class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1321                RegisterOperand Src2RC, int NumSrcArgs,
1322                bit HasModifiers> {
1323
1324  dag ret =
1325    !if (!eq(NumSrcArgs, 0),
1326      // VOP1 without input operands (V_NOP, V_CLREXCP)
1327      (ins),
1328      /* else */
1329    !if (!eq(NumSrcArgs, 1),
1330      !if (!eq(HasModifiers, 1),
1331        // VOP1 with modifiers
1332        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1333             ClampMod:$clamp, omod:$omod)
1334      /* else */,
1335        // VOP1 without modifiers
1336        (ins Src0RC:$src0)
1337      /* endif */ ),
1338    !if (!eq(NumSrcArgs, 2),
1339      !if (!eq(HasModifiers, 1),
1340        // VOP 2 with modifiers
1341        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1342             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1343             ClampMod:$clamp, omod:$omod)
1344      /* else */,
1345        // VOP2 without modifiers
1346        (ins Src0RC:$src0, Src1RC:$src1)
1347      /* endif */ )
1348    /* NumSrcArgs == 3 */,
1349      !if (!eq(HasModifiers, 1),
1350        // VOP3 with modifiers
1351        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1352             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1353             InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
1354             ClampMod:$clamp, omod:$omod)
1355      /* else */,
1356        // VOP3 without modifiers
1357        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1358      /* endif */ ))));
1359}
1360
1361class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1362                                                             bit HasModifiers> {
1363
1364  dag ret = !if (!eq(NumSrcArgs, 1),
1365              !if (!eq(HasModifiers, 1),
1366                // VOP1_DPP with modifiers
1367                (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1368                     dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1369                     bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1370              /* else */,
1371                // VOP1_DPP without modifiers
1372                (ins Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1373                bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1374              /* endif */)
1375              /* NumSrcArgs == 2 */,
1376              !if (!eq(HasModifiers, 1),
1377                // VOP2_DPP with modifiers
1378                (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1379                      InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1380                      dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1381                      bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1382              /* else */,
1383                // VOP2_DPP without modifiers
1384                (ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
1385                row_mask:$row_mask, bank_mask:$bank_mask,
1386                bound_ctrl:$bound_ctrl)
1387             /* endif */));
1388}
1389
1390// Returns the assembly string for the inputs and outputs of a VOP[12C]
1391// instruction.  This does not add the _e32 suffix, so it can be reused
1392// by getAsm64.
1393class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1394  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1395  string src0 = ", $src0";
1396  string src1 = ", $src1";
1397  string src2 = ", $src2";
1398  string ret = !if(HasDst, dst, "") #
1399               !if(!eq(NumSrcArgs, 1), src0, "") #
1400               !if(!eq(NumSrcArgs, 2), src0#src1, "") #
1401               !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
1402}
1403
1404// Returns the assembly string for the inputs and outputs of a VOP3
1405// instruction.
1406class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1407  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1408  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1409  string src1 = !if(!eq(NumSrcArgs, 1), "",
1410                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1411                                           " $src1_modifiers,"));
1412  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1413  string ret =
1414  !if(!eq(HasModifiers, 0),
1415      getAsm32<HasDst, NumSrcArgs, DstVT>.ret,
1416      dst#", "#src0#src1#src2#"$clamp"#"$omod");
1417}
1418
1419class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1420  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1421  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1422  string src1 = !if(!eq(NumSrcArgs, 1), "",
1423                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1424                                           " $src1_modifiers,"));
1425  string args = !if(!eq(HasModifiers, 0),
1426                     getAsm32<0, NumSrcArgs, DstVT>.ret,
1427                     ", "#src0#src1);
1428  string ret = dst#args#" $dpp_ctrl $row_mask $bank_mask $bound_ctrl";
1429}
1430
1431class VOPProfile <list<ValueType> _ArgVT> {
1432
1433  field list<ValueType> ArgVT = _ArgVT;
1434
1435  field ValueType DstVT = ArgVT[0];
1436  field ValueType Src0VT = ArgVT[1];
1437  field ValueType Src1VT = ArgVT[2];
1438  field ValueType Src2VT = ArgVT[3];
1439  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1440  field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
1441  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1442  field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
1443  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1444  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1445  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1446  field RegisterClass Src0DPP = getDPPSrcForVT<Src0VT>.ret;
1447  field RegisterClass Src1DPP = getDPPSrcForVT<Src1VT>.ret;
1448
1449  field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
1450  field bit HasDst32 = HasDst;
1451  field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
1452  field bit HasModifiers = hasModifiers<Src0VT>.ret;
1453
1454  field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
1455
1456  // VOP3b instructions are a special case with a second explicit
1457  // output. This is manually overridden for them.
1458  field dag Outs32 = Outs;
1459  field dag Outs64 = Outs;
1460  field dag OutsDPP = !if(!eq(DstVT.Size, 1), (outs DstRCDPP:$sdst), // sdst for VOPC
1461                                              (outs DstRCDPP:$vdst));
1462
1463  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1464  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1465                             HasModifiers>.ret;
1466  field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs, HasModifiers>.ret;
1467
1468  field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
1469  field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1470  field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1471}
1472
1473// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1474//        for the instruction patterns to work.
1475def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1476def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1477def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1478
1479def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1480def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1481def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1482
1483def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
1484
1485def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1486def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1487def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1488def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1489def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1490def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1491def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1492def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1493def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1494
1495def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1496def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1497def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1498def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1499def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1500def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1501def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1502
1503// Write out to vcc or arbitrary SGPR.
1504def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> {
1505  let Asm32 = "$vdst, vcc, $src0, $src1";
1506  let Asm64 = "$vdst, $sdst, $src0, $src1";
1507  let Outs32 = (outs DstRC:$vdst);
1508  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1509}
1510
1511// Write out to vcc or arbitrary SGPR and read in from vcc or
1512// arbitrary SGPR.
1513def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> {
1514  // We use VCSrc_32 to exclude literal constants, even though the
1515  // encoding normally allows them since the implicit VCC use means
1516  // using one would always violate the constant bus
1517  // restriction. SGPRs are still allowed because it should
1518  // technically be possible to use VCC again as src0.
1519  let Src0RC32 = VCSrc_32;
1520  let Asm32 = "$vdst, vcc, $src0, $src1, vcc";
1521  let Asm64 = "$vdst, $sdst, $src0, $src1, $src2";
1522  let Outs32 = (outs DstRC:$vdst);
1523  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1524
1525  // Suppress src2 implied by type since the 32-bit encoding uses an
1526  // implicit VCC use.
1527  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1528}
1529
1530class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> {
1531  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1532  let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod";
1533}
1534
1535def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> {
1536  // FIXME: Hack to stop printing _e64
1537  let DstRC = RegisterOperand<VGPR_32>;
1538}
1539
1540def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64> {
1541  // FIXME: Hack to stop printing _e64
1542  let DstRC = RegisterOperand<VReg_64>;
1543}
1544
1545// VOPC instructions are a special case because for the 32-bit
1546// encoding, we want to display the implicit vcc write as if it were
1547// an explicit $dst.
1548class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> {
1549  let Asm32 = "vcc, $src0, $src1";
1550  // The destination for 32-bit encoding is implicit.
1551  let HasDst32 = 0;
1552  let Outs64 = (outs DstRC:$sdst);
1553}
1554
1555class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
1556  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1557  let Asm64 = "$sdst, $src0_modifiers, $src1";
1558}
1559
1560def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1561def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1562def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1563def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1564
1565def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1566def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1567
1568def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1569def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1570def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1571def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> {
1572  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1573  let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2);
1574  let Asm64 = "$vdst, $src0, $src1, $src2";
1575}
1576
1577def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1578def VOP_MADAK : VOPProfile <[f32, f32, f32, f32]> {
1579  field dag Ins32 = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$k);
1580  field string Asm32 = "$vdst, $src0, $vsrc1, $k";
1581}
1582def VOP_MADMK : VOPProfile <[f32, f32, f32, f32]> {
1583  field dag Ins32 = (ins VCSrc_32:$src0, u32imm:$k, VGPR_32:$vsrc1);
1584  field string Asm32 = "$vdst, $src0, $k, $vsrc1";
1585}
1586def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
1587  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
1588  let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
1589                             HasModifiers>.ret;
1590  let InsDPP = (ins InputModsNoDefault:$src0_modifiers, Src0RC32:$src0,
1591                    InputModsNoDefault:$src1_modifiers, Src1RC32:$src1,
1592                    VGPR_32:$src2, // stub argument
1593                    dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1594                    bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
1595  let Asm32 = getAsm32<1, 2, f32>.ret;
1596  let Asm64 = getAsm64<1, 2, HasModifiers, f32>.ret;
1597  let AsmDPP = getAsmDPP<1, 2, HasModifiers, f32>.ret;
1598}
1599def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1600def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1601def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1602
1603// This class is used only with VOPC instructions. Use $sdst for out operand
1604class SIInstAlias <string asm, Instruction inst, VOPProfile p> :
1605    InstAlias <asm, (inst)>, PredicateControl {
1606
1607  field bit isCompare;
1608  field bit isCommutable;
1609
1610  let ResultInst =
1611    !if (p.HasDst32,
1612      !if (!eq(p.NumSrcArgs, 0),
1613        // 1 dst, 0 src
1614        (inst p.DstRC:$sdst),
1615      !if (!eq(p.NumSrcArgs, 1),
1616        // 1 dst, 1 src
1617        (inst p.DstRC:$sdst, p.Src0RC32:$src0),
1618      !if (!eq(p.NumSrcArgs, 2),
1619        // 1 dst, 2 src
1620        (inst p.DstRC:$sdst, p.Src0RC32:$src0, p.Src1RC32:$src1),
1621      // else - unreachable
1622        (inst)))),
1623    // else
1624      !if (!eq(p.NumSrcArgs, 2),
1625        // 0 dst, 2 src
1626        (inst p.Src0RC32:$src0, p.Src1RC32:$src1),
1627      !if (!eq(p.NumSrcArgs, 1),
1628        // 0 dst, 1 src
1629        (inst p.Src0RC32:$src1),
1630      // else
1631        // 0 dst, 0 src
1632        (inst))));
1633}
1634
1635class SIInstAliasSI <string asm, string op_name, VOPProfile p> :
1636  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_si"), p> {
1637  let AssemblerPredicate = SIAssemblerPredicate;
1638}
1639
1640class SIInstAliasVI <string asm, string op_name, VOPProfile p> :
1641  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_vi"), p> {
1642  let AssemblerPredicates = [isVI];
1643}
1644
1645multiclass SIInstAliasBuilder <string asm, VOPProfile p> {
1646
1647  def : SIInstAliasSI <asm, NAME, p>;
1648
1649  def : SIInstAliasVI <asm, NAME, p>;
1650}
1651
1652class VOP <string opName> {
1653  string OpName = opName;
1654}
1655
1656class VOP2_REV <string revOp, bit isOrig> {
1657  string RevOp = revOp;
1658  bit IsOrig = isOrig;
1659}
1660
1661class AtomicNoRet <string noRetOp, bit isRet> {
1662  string NoRetOp = noRetOp;
1663  bit IsRet = isRet;
1664}
1665
1666class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1667  VOP1Common <outs, ins, "", pattern>,
1668  VOP <opName>,
1669  SIMCInstr <opName#"_e32", SISubtarget.NONE>,
1670  MnemonicAlias<opName#"_e32", opName> {
1671  let isPseudo = 1;
1672  let isCodeGenOnly = 1;
1673
1674  field bits<8> vdst;
1675  field bits<9> src0;
1676}
1677
1678class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1679  VOP1<op.SI, outs, ins, asm, []>,
1680  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1681  let AssemblerPredicate = SIAssemblerPredicate;
1682  let DecoderNamespace = "SICI";
1683  let DisableDecoder = DisableSIDecoder;
1684}
1685
1686class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1687  VOP1<op.VI, outs, ins, asm, []>,
1688  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1689  let AssemblerPredicates = [isVI];
1690  let DecoderNamespace = "VI";
1691  let DisableDecoder = DisableVIDecoder;
1692}
1693
1694multiclass VOP1_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1695                   string asm = opName#p.Asm32> {
1696  def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1697
1698  def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1699
1700  def _vi : VOP1_Real_vi <opName, op, p.Outs, p.Ins32, asm>;
1701
1702}
1703
1704class VOP1_DPP <vop1 op, string opName, VOPProfile p> :
1705  VOP1_DPPe <op.VI>,
1706  VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
1707  let AssemblerPredicates = [isVI];
1708  let src0_modifiers = !if(p.HasModifiers, ?, 0);
1709  let src1_modifiers = 0;
1710}
1711
1712multiclass VOP1SI_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1713                     string asm = opName#p.Asm32> {
1714
1715  def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1716
1717  def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1718}
1719
1720class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1721  VOP2Common <outs, ins, "", pattern>,
1722  VOP <opName>,
1723  SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1724  MnemonicAlias<opName#"_e32", opName> {
1725  let isPseudo = 1;
1726  let isCodeGenOnly = 1;
1727}
1728
1729class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1730  VOP2 <op.SI, outs, ins, opName#asm, []>,
1731  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1732  let AssemblerPredicates = [isSICI];
1733  let DecoderNamespace = "SICI";
1734  let DisableDecoder = DisableSIDecoder;
1735}
1736
1737class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1738  VOP2 <op.VI, outs, ins, opName#asm, []>,
1739  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1740  let AssemblerPredicates = [isVI];
1741  let DecoderNamespace = "VI";
1742  let DisableDecoder = DisableVIDecoder;
1743}
1744
1745multiclass VOP2SI_m <vop2 op, string opName, VOPProfile p, list<dag> pattern,
1746                     string revOp> {
1747
1748  def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1749           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1750
1751  def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1752}
1753
1754multiclass VOP2_m <vop2 op, string opName, VOPProfile p, list <dag> pattern,
1755                   string revOp> {
1756
1757  def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1758           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1759
1760  def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1761
1762  def _vi : VOP2_Real_vi <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1763
1764}
1765
1766class VOP2_DPP <vop2 op, string opName, VOPProfile p> :
1767  VOP2_DPPe <op.VI>,
1768  VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, [], p.HasModifiers> {
1769  let AssemblerPredicates = [isVI];
1770  let src0_modifiers = !if(p.HasModifiers, ?, 0);
1771  let src1_modifiers = !if(p.HasModifiers, ?, 0);
1772}
1773
1774class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1775
1776  bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1777  bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1778  bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1779  bits<2> omod = !if(HasModifiers, ?, 0);
1780  bits<1> clamp = !if(HasModifiers, ?, 0);
1781  bits<9> src1 = !if(HasSrc1, ?, 0);
1782  bits<9> src2 = !if(HasSrc2, ?, 0);
1783}
1784
1785class VOP3DisableModFields <bit HasSrc0Mods,
1786                            bit HasSrc1Mods = 0,
1787                            bit HasSrc2Mods = 0,
1788                            bit HasOutputMods = 0> {
1789  bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1790  bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1791  bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1792  bits<2> omod = !if(HasOutputMods, ?, 0);
1793  bits<1> clamp = !if(HasOutputMods, ?, 0);
1794}
1795
1796class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName,
1797                   bit HasMods = 0, bit VOP3Only = 0> :
1798  VOP3Common <outs, ins, "", pattern, HasMods, VOP3Only>,
1799  VOP <opName>,
1800  SIMCInstr<opName#"_e64", SISubtarget.NONE>,
1801  MnemonicAlias<opName#"_e64", opName> {
1802  let isPseudo = 1;
1803  let isCodeGenOnly = 1;
1804
1805  field bit vdst;
1806  field bit src0;
1807}
1808
1809class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1810                    bit HasMods = 0, bit VOP3Only = 0> :
1811  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1812  VOP3e <op>,
1813  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1814  let AssemblerPredicates = [isSICI];
1815  let DecoderNamespace = "SICI";
1816  let DisableDecoder = DisableSIDecoder;
1817}
1818
1819class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1820                    bit HasMods = 0, bit VOP3Only = 0> :
1821  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1822  VOP3e_vi <op>,
1823  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1824  let AssemblerPredicates = [isVI];
1825  let DecoderNamespace = "VI";
1826  let DisableDecoder = DisableVIDecoder;
1827}
1828
1829class VOP3_C_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1830                     bit HasMods = 0, bit VOP3Only = 0> :
1831  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1832  VOP3ce <op>,
1833  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1834  let AssemblerPredicates = [isSICI];
1835  let DecoderNamespace = "SICI";
1836  let DisableDecoder = DisableSIDecoder;
1837}
1838
1839class VOP3_C_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1840                      bit HasMods = 0, bit VOP3Only = 0> :
1841  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1842  VOP3ce_vi <op>,
1843  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1844  let AssemblerPredicates = [isVI];
1845  let DecoderNamespace = "VI";
1846  let DisableDecoder = DisableVIDecoder;
1847}
1848
1849class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1850                     bit HasMods = 0, bit VOP3Only = 0> :
1851  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1852  VOP3be <op>,
1853  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1854  let AssemblerPredicates = [isSICI];
1855  let DecoderNamespace = "SICI";
1856  let DisableDecoder = DisableSIDecoder;
1857}
1858
1859class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1860                     bit HasMods = 0, bit VOP3Only = 0> :
1861  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1862  VOP3be_vi <op>,
1863  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1864  let AssemblerPredicates = [isVI];
1865  let DecoderNamespace = "VI";
1866  let DisableDecoder = DisableVIDecoder;
1867}
1868
1869multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1870                   string opName, int NumSrcArgs, bit HasMods = 1, bit VOP3Only = 0> {
1871
1872  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1873
1874  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1875            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1876                              !if(!eq(NumSrcArgs, 2), 0, 1),
1877                              HasMods>;
1878  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1879            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1880                              !if(!eq(NumSrcArgs, 2), 0, 1),
1881                              HasMods>;
1882}
1883
1884multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1885                     list<dag> pattern, string opName, bit HasMods = 1> {
1886
1887  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1888
1889  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1890            VOP3DisableFields<0, 0, HasMods>;
1891
1892  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1893            VOP3DisableFields<0, 0, HasMods>;
1894}
1895
1896multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1897                     list<dag> pattern, string opName, bit HasMods = 1> {
1898
1899  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1900
1901  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1902            VOP3DisableFields<0, 0, HasMods>;
1903  // No VI instruction. This class is for SI only.
1904}
1905
1906multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1907                     list<dag> pattern, string opName, string revOp,
1908                     bit HasMods = 1> {
1909
1910  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1911           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1912
1913  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1914            VOP3DisableFields<1, 0, HasMods>;
1915
1916  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1917            VOP3DisableFields<1, 0, HasMods>;
1918}
1919
1920multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
1921                     list<dag> pattern, string opName, string revOp,
1922                     bit HasMods = 1> {
1923
1924  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1925           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1926
1927  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1928            VOP3DisableFields<1, 0, HasMods>;
1929
1930  // No VI instruction. This class is for SI only.
1931}
1932
1933// Two operand VOP3b instruction that may have a 3rd SGPR bool operand
1934// instead of an implicit VCC as in the VOP2b format.
1935multiclass VOP3b_2_3_m <vop op, dag outs, dag ins, string asm,
1936                        list<dag> pattern, string opName, string revOp,
1937                        bit HasMods = 1, bit useSrc2Input = 0, bit VOP3Only = 0> {
1938  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods, VOP3Only>;
1939
1940  def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1941            VOP3DisableFields<1, useSrc2Input, HasMods>;
1942
1943  def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1944            VOP3DisableFields<1, useSrc2Input, HasMods>;
1945}
1946
1947multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1948                     list<dag> pattern, string opName,
1949                     bit HasMods, bit defExec,
1950                     string revOp, list<SchedReadWrite> sched> {
1951
1952  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1953           VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
1954    let Defs = !if(defExec, [EXEC], []);
1955    let SchedRW = sched;
1956  }
1957
1958  def _si : VOP3_C_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1959            VOP3DisableFields<1, 0, HasMods> {
1960    let Defs = !if(defExec, [EXEC], []);
1961    let SchedRW = sched;
1962  }
1963
1964  def _vi : VOP3_C_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1965            VOP3DisableFields<1, 0, HasMods> {
1966    let Defs = !if(defExec, [EXEC], []);
1967    let SchedRW = sched;
1968  }
1969}
1970
1971// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1972multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1973                         string asm, list<dag> pattern = []> {
1974  let isPseudo = 1, isCodeGenOnly = 1 in {
1975    def "" : VOPAnyCommon <outs, ins, "", pattern>,
1976             SIMCInstr<opName, SISubtarget.NONE>;
1977  }
1978
1979  def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1980            SIMCInstr <opName, SISubtarget.SI> {
1981            let AssemblerPredicates = [isSICI];
1982            let DecoderNamespace = "SICI";
1983            let DisableDecoder = DisableSIDecoder;
1984  }
1985
1986  def _vi : VOP3Common <outs, ins, asm, []>,
1987            VOP3e_vi <op.VI3>,
1988            VOP3DisableFields <1, 0, 0>,
1989            SIMCInstr <opName, SISubtarget.VI> {
1990            let AssemblerPredicates = [isVI];
1991            let DecoderNamespace = "VI";
1992            let DisableDecoder = DisableVIDecoder;
1993  }
1994}
1995
1996multiclass VOP1_Helper <vop1 op, string opName, VOPProfile p, list<dag> pat32,
1997                        list<dag> pat64> {
1998
1999  defm _e32 : VOP1_m <op, opName, p, pat32>;
2000
2001  defm _e64 : VOP3_1_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2002                        p.HasModifiers>;
2003
2004  def _dpp : VOP1_DPP <op, opName, p>;
2005}
2006
2007multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
2008                     SDPatternOperator node = null_frag> : VOP1_Helper <
2009  op, opName, P, [],
2010  !if(P.HasModifiers,
2011      [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
2012                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
2013      [(set P.DstVT:$vdst, (node P.Src0VT:$src0))])
2014>;
2015
2016multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
2017                       SDPatternOperator node = null_frag> {
2018
2019  defm _e32 : VOP1SI_m <op, opName, P, []>;
2020
2021  defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
2022    !if(P.HasModifiers,
2023      [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
2024                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
2025      [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]),
2026    opName, P.HasModifiers>;
2027}
2028
2029multiclass VOP2_Helper <vop2 op, string opName, VOPProfile p, list<dag> pat32,
2030                        list<dag> pat64, string revOp> {
2031
2032  defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
2033
2034  defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2035                        revOp, p.HasModifiers>;
2036
2037  def _dpp : VOP2_DPP <op, opName, p>;
2038}
2039
2040multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
2041                     SDPatternOperator node = null_frag,
2042                     string revOp = opName> : VOP2_Helper <
2043  op, opName, P, [],
2044  !if(P.HasModifiers,
2045      [(set P.DstVT:$vdst,
2046           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2047                                      i1:$clamp, i32:$omod)),
2048                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2049      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2050  revOp
2051>;
2052
2053multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
2054                       SDPatternOperator node = null_frag,
2055                       string revOp = opName> {
2056
2057  defm _e32 : VOP2SI_m <op, opName, P, [], revOp>;
2058
2059  defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
2060    !if(P.HasModifiers,
2061        [(set P.DstVT:$vdst,
2062             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2063                                        i1:$clamp, i32:$omod)),
2064                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2065        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2066    opName, revOp, P.HasModifiers>;
2067}
2068
2069multiclass VOP2b_Helper <vop2 op, string opName, VOPProfile p,
2070                         list<dag> pat32, list<dag> pat64,
2071                         string revOp, bit useSGPRInput> {
2072
2073  let SchedRW = [Write32Bit, WriteSALU] in {
2074    let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
2075      defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
2076    }
2077
2078    defm _e64 : VOP3b_2_3_m <op, p.Outs64, p.Ins64, opName#p.Asm64, pat64,
2079                             opName, revOp, p.HasModifiers, useSGPRInput>;
2080  }
2081}
2082
2083multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
2084                      SDPatternOperator node = null_frag,
2085                      string revOp = opName> : VOP2b_Helper <
2086  op, opName, P, [],
2087  !if(P.HasModifiers,
2088      [(set P.DstVT:$vdst,
2089           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2090                                      i1:$clamp, i32:$omod)),
2091                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2092      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2093  revOp, !eq(P.NumSrcArgs, 3)
2094>;
2095
2096// A VOP2 instruction that is VOP3-only on VI.
2097multiclass VOP2_VI3_Helper <vop23 op, string opName, VOPProfile p,
2098                            list<dag> pat32, list<dag> pat64, string revOp> {
2099
2100  defm _e32 : VOP2SI_m <op, opName, p, pat32, revOp>;
2101
2102  defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
2103                        revOp, p.HasModifiers>;
2104}
2105
2106multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
2107                          SDPatternOperator node = null_frag,
2108                          string revOp = opName>
2109                          : VOP2_VI3_Helper <
2110  op, opName, P, [],
2111  !if(P.HasModifiers,
2112      [(set P.DstVT:$vdst,
2113           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2114                                      i1:$clamp, i32:$omod)),
2115                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2116      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2117  revOp
2118>;
2119
2120multiclass VOP2MADK <vop2 op, string opName, VOPProfile P, list<dag> pattern = []> {
2121
2122  def "" : VOP2_Pseudo <P.Outs, P.Ins32, pattern, opName>;
2123
2124let isCodeGenOnly = 0 in {
2125  def _si : VOP2Common <P.Outs, P.Ins32,
2126                        !strconcat(opName, P.Asm32), []>,
2127            SIMCInstr <opName#"_e32", SISubtarget.SI>,
2128            VOP2_MADKe <op.SI> {
2129            let AssemblerPredicates = [isSICI];
2130            let DecoderNamespace = "SICI";
2131            let DisableDecoder = DisableSIDecoder;
2132            }
2133
2134  def _vi : VOP2Common <P.Outs, P.Ins32,
2135                        !strconcat(opName, P.Asm32), []>,
2136            SIMCInstr <opName#"_e32", SISubtarget.VI>,
2137            VOP2_MADKe <op.VI> {
2138            let AssemblerPredicates = [isVI];
2139            let DecoderNamespace = "VI";
2140            let DisableDecoder = DisableVIDecoder;
2141            }
2142} // End isCodeGenOnly = 0
2143}
2144
2145class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
2146  VOPCCommon <ins, "", pattern>,
2147  VOP <opName>,
2148  SIMCInstr<opName#"_e32", SISubtarget.NONE> {
2149  let isPseudo = 1;
2150  let isCodeGenOnly = 1;
2151}
2152
2153multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
2154                   string opName, bit DefExec, VOPProfile p,
2155                   list<SchedReadWrite> sched,
2156                   string revOpName = "", string asm = opName#"_e32 "#op_asm,
2157                   string alias_asm = opName#" "#op_asm> {
2158  def "" : VOPC_Pseudo <ins, pattern, opName>,
2159           VOP2_REV<revOpName#"_e32", !eq(revOpName, opName)> {
2160    let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2161    let SchedRW = sched;
2162  }
2163
2164  let AssemblerPredicates = [isSICI] in {
2165    def _si : VOPC<op.SI, ins, asm, []>,
2166              SIMCInstr <opName#"_e32", SISubtarget.SI> {
2167      let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2168      let hasSideEffects = DefExec;
2169      let SchedRW = sched;
2170      let DecoderNamespace = "SICI";
2171      let DisableDecoder = DisableSIDecoder;
2172    }
2173
2174  } // End AssemblerPredicates = [isSICI]
2175
2176  let AssemblerPredicates = [isVI] in {
2177    def _vi : VOPC<op.VI, ins, asm, []>,
2178              SIMCInstr <opName#"_e32", SISubtarget.VI> {
2179      let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2180      let hasSideEffects = DefExec;
2181      let SchedRW = sched;
2182      let DecoderNamespace = "VI";
2183      let DisableDecoder = DisableVIDecoder;
2184    }
2185
2186  } // End AssemblerPredicates = [isVI]
2187
2188  defm : SIInstAliasBuilder<alias_asm, p>;
2189}
2190
2191multiclass VOPC_Helper <vopc op, string opName, list<dag> pat32,
2192                        list<dag> pat64, bit DefExec, string revOp,
2193                        VOPProfile p, list<SchedReadWrite> sched> {
2194  defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched,
2195                      revOp>;
2196
2197  defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2198                        opName, p.HasModifiers, DefExec, revOp, sched>;
2199}
2200
2201// Special case for class instructions which only have modifiers on
2202// the 1st source operand.
2203multiclass VOPC_Class_Helper <vopc op, string opName, list<dag> pat32,
2204                              list<dag> pat64, bit DefExec, string revOp,
2205                              VOPProfile p, list<SchedReadWrite> sched> {
2206  defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched>;
2207
2208  defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2209                        opName, p.HasModifiers, DefExec, revOp, sched>,
2210                        VOP3DisableModFields<1, 0, 0>;
2211}
2212
2213multiclass VOPCInst <vopc op, string opName,
2214                     VOPProfile P, PatLeaf cond = COND_NULL,
2215                     string revOp = opName,
2216                     bit DefExec = 0,
2217                     list<SchedReadWrite> sched = [Write32Bit]> :
2218                     VOPC_Helper <
2219  op, opName, [],
2220  !if(P.HasModifiers,
2221      [(set i1:$sdst,
2222          (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2223                                      i1:$clamp, i32:$omod)),
2224                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2225                 cond))],
2226      [(set i1:$sdst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
2227  DefExec, revOp, P, sched
2228>;
2229
2230multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
2231                     bit DefExec = 0,
2232                     list<SchedReadWrite> sched> : VOPC_Class_Helper <
2233  op, opName, [],
2234  !if(P.HasModifiers,
2235      [(set i1:$sdst,
2236          (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
2237      [(set i1:$sdst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
2238  DefExec, opName, P, sched
2239>;
2240
2241
2242multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2243  VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
2244
2245multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2246  VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp, 0, [WriteDoubleAdd]>;
2247
2248multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2249  VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
2250
2251multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2252  VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp, 0, [Write64Bit]>;
2253
2254
2255multiclass VOPCX <vopc op, string opName, VOPProfile P,
2256                  PatLeaf cond = COND_NULL,
2257                  list<SchedReadWrite> sched,
2258                  string revOp = "">
2259  : VOPCInst <op, opName, P, cond, revOp, 1, sched>;
2260
2261multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
2262  VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, [Write32Bit], revOp>;
2263
2264multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
2265  VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, [WriteDoubleAdd], revOp>;
2266
2267multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
2268  VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, [Write32Bit], revOp>;
2269
2270multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
2271  VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>;
2272
2273multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
2274                        list<dag> pat, int NumSrcArgs, bit HasMods,
2275                        bit VOP3Only = 0> : VOP3_m <
2276    op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods, VOP3Only
2277>;
2278
2279multiclass VOPC_CLASS_F32 <vopc op, string opName> :
2280  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0, [Write32Bit]>;
2281
2282multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
2283  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1, [Write32Bit]>;
2284
2285multiclass VOPC_CLASS_F64 <vopc op, string opName> :
2286  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0, [WriteDoubleAdd]>;
2287
2288multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
2289  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>;
2290
2291multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
2292                     SDPatternOperator node = null_frag, bit VOP3Only = 0> :
2293  VOP3_Helper <
2294  op, opName, (outs P.DstRC.RegClass:$vdst), P.Ins64, P.Asm64,
2295  !if(!eq(P.NumSrcArgs, 3),
2296    !if(P.HasModifiers,
2297        [(set P.DstVT:$vdst,
2298            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2299                                       i1:$clamp, i32:$omod)),
2300                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2301                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
2302        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1,
2303                                  P.Src2VT:$src2))]),
2304  !if(!eq(P.NumSrcArgs, 2),
2305    !if(P.HasModifiers,
2306        [(set P.DstVT:$vdst,
2307            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2308                                       i1:$clamp, i32:$omod)),
2309                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2310        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
2311  /* P.NumSrcArgs == 1 */,
2312    !if(P.HasModifiers,
2313        [(set P.DstVT:$vdst,
2314            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2315                                       i1:$clamp, i32:$omod))))],
2316        [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]))),
2317  P.NumSrcArgs, P.HasModifiers, VOP3Only
2318>;
2319
2320// Special case for v_div_fmas_{f32|f64}, since it seems to be the
2321// only VOP instruction that implicitly reads VCC.
2322multiclass VOP3_VCC_Inst <vop3 op, string opName,
2323                          VOPProfile P,
2324                          SDPatternOperator node = null_frag> : VOP3_Helper <
2325  op, opName,
2326  (outs P.DstRC.RegClass:$vdst),
2327  (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
2328       InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
2329       InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
2330       ClampMod:$clamp,
2331       omod:$omod),
2332  "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
2333  [(set P.DstVT:$vdst,
2334            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2335                                       i1:$clamp, i32:$omod)),
2336                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2337                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
2338                  (i1 VCC)))],
2339  3, 1
2340>;
2341
2342multiclass VOP3bInst <vop op, string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> :
2343  VOP3b_2_3_m <
2344  op, P.Outs64, P.Ins64,
2345  opName#" "#P.Asm64, pattern,
2346  opName, "", 1, 1, VOP3Only
2347>;
2348
2349class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
2350  (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
2351        (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2352        (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
2353  (Inst i32:$src0_modifiers, P.Src0VT:$src0,
2354        i32:$src1_modifiers, P.Src1VT:$src1,
2355        i32:$src2_modifiers, P.Src2VT:$src2,
2356        i1:$clamp,
2357        i32:$omod)>;
2358
2359//===----------------------------------------------------------------------===//
2360// Interpolation opcodes
2361//===----------------------------------------------------------------------===//
2362
2363class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2364  VINTRPCommon <outs, ins, "", pattern>,
2365  SIMCInstr<opName, SISubtarget.NONE> {
2366  let isPseudo = 1;
2367  let isCodeGenOnly = 1;
2368}
2369
2370class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
2371                      string asm> :
2372  VINTRPCommon <outs, ins, asm, []>,
2373  VINTRPe <op>,
2374  SIMCInstr<opName, SISubtarget.SI> {
2375  let AssemblerPredicate = SIAssemblerPredicate;
2376  let DecoderNamespace = "SICI";
2377  let DisableDecoder = DisableSIDecoder;
2378}
2379
2380class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
2381                      string asm> :
2382  VINTRPCommon <outs, ins, asm, []>,
2383  VINTRPe_vi <op>,
2384  SIMCInstr<opName, SISubtarget.VI> {
2385  let AssemblerPredicate = VIAssemblerPredicate;
2386  let DecoderNamespace = "VI";
2387  let DisableDecoder = DisableVIDecoder;
2388}
2389
2390multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
2391                     list<dag> pattern = []> {
2392  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
2393
2394  def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
2395
2396  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
2397}
2398
2399//===----------------------------------------------------------------------===//
2400// Vector I/O classes
2401//===----------------------------------------------------------------------===//
2402
2403class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2404  DS <outs, ins, "", pattern>,
2405  SIMCInstr <opName, SISubtarget.NONE> {
2406  let isPseudo = 1;
2407  let isCodeGenOnly = 1;
2408}
2409
2410class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2411  DS <outs, ins, asm, []>,
2412  DSe <op>,
2413  SIMCInstr <opName, SISubtarget.SI> {
2414  let isCodeGenOnly = 0;
2415  let AssemblerPredicates = [isSICI];
2416  let DecoderNamespace="SICI";
2417  let DisableDecoder = DisableSIDecoder;
2418}
2419
2420class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2421  DS <outs, ins, asm, []>,
2422  DSe_vi <op>,
2423  SIMCInstr <opName, SISubtarget.VI> {
2424  let isCodeGenOnly = 0;
2425  let AssemblerPredicates = [isVI];
2426  let DecoderNamespace="VI";
2427  let DisableDecoder = DisableVIDecoder;
2428}
2429
2430class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2431  DS_Real_si <op,opName, outs, ins, asm> {
2432
2433  // Single load interpret the 2 i8imm operands as a single i16 offset.
2434  bits<16> offset;
2435  let offset0 = offset{7-0};
2436  let offset1 = offset{15-8};
2437}
2438
2439class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2440  DS_Real_vi <op, opName, outs, ins, asm> {
2441
2442  // Single load interpret the 2 i8imm operands as a single i16 offset.
2443  bits<16> offset;
2444  let offset0 = offset{7-0};
2445  let offset1 = offset{15-8};
2446}
2447
2448multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
2449  dag outs = (outs rc:$vdst),
2450  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2451  string asm = opName#" $vdst, $addr"#"$offset$gds"> {
2452
2453  def "" : DS_Pseudo <opName, outs, ins, []>;
2454
2455  let data0 = 0, data1 = 0 in {
2456    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2457    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2458  }
2459}
2460
2461multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
2462  dag outs = (outs rc:$vdst),
2463  dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
2464                 gds01:$gds),
2465  string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
2466
2467  def "" : DS_Pseudo <opName, outs, ins, []>;
2468
2469  let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
2470    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2471    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2472  }
2473}
2474
2475multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
2476  dag outs = (outs),
2477  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2478  string asm = opName#" $addr, $data0"#"$offset$gds"> {
2479
2480  def "" : DS_Pseudo <opName, outs, ins, []>,
2481           AtomicNoRet<opName, 0>;
2482
2483  let data1 = 0, vdst = 0 in {
2484    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2485    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2486  }
2487}
2488
2489multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
2490  dag outs = (outs),
2491  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2492              ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
2493  string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
2494
2495  def "" : DS_Pseudo <opName, outs, ins, []>;
2496
2497  let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2498    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2499    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2500  }
2501}
2502
2503multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2504                        string noRetOp = "",
2505  dag outs = (outs rc:$vdst),
2506  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2507  string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2508
2509  let hasPostISelHook = 1 in {
2510    def "" : DS_Pseudo <opName, outs, ins, []>,
2511             AtomicNoRet<noRetOp, 1>;
2512
2513    let data1 = 0 in {
2514      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2515      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2516    }
2517  }
2518}
2519
2520multiclass DS_1A1D_PERMUTE <bits<8> op, string opName, RegisterClass rc,
2521                            SDPatternOperator node = null_frag,
2522  dag outs = (outs rc:$vdst),
2523  dag ins = (ins VGPR_32:$addr, rc:$data0),
2524  string asm = opName#" $vdst, $addr, $data0"> {
2525
2526  let LGKM_CNT = 0, mayLoad = 0, mayStore = 0, isConvergent = 1 in {
2527    def "" : DS_Pseudo <opName, outs, ins,
2528     [(set (i32 rc:$vdst),
2529         (node (i32 VGPR_32:$addr), (i32 rc:$data0)))]>;
2530
2531    let data1 = 0, offset0 = 0, offset1 = 0, gds = 0  in {
2532      def "_vi" : DS_Real_vi <op, opName, outs, ins, asm>;
2533    }
2534  }
2535}
2536
2537multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2538                          string noRetOp = "", dag ins,
2539  dag outs = (outs rc:$vdst),
2540  string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2541
2542  let hasPostISelHook = 1 in {
2543    def "" : DS_Pseudo <opName, outs, ins, []>,
2544             AtomicNoRet<noRetOp, 1>;
2545
2546    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2547    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2548  }
2549}
2550
2551multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2552                        string noRetOp = "", RegisterClass src = rc> :
2553  DS_1A2D_RET_m <op, asm, rc, noRetOp,
2554                 (ins VGPR_32:$addr, src:$data0, src:$data1,
2555                      ds_offset:$offset, gds:$gds)
2556>;
2557
2558multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2559                          string noRetOp = opName,
2560  dag outs = (outs),
2561  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2562                 ds_offset:$offset, gds:$gds),
2563  string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2564
2565  def "" : DS_Pseudo <opName, outs, ins, []>,
2566           AtomicNoRet<noRetOp, 0>;
2567
2568  let vdst = 0 in {
2569    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2570    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2571  }
2572}
2573
2574multiclass DS_0A_RET <bits<8> op, string opName,
2575  dag outs = (outs VGPR_32:$vdst),
2576  dag ins = (ins ds_offset:$offset, gds:$gds),
2577  string asm = opName#" $vdst"#"$offset"#"$gds"> {
2578
2579  let mayLoad = 1, mayStore = 1 in {
2580    def "" : DS_Pseudo <opName, outs, ins, []>;
2581
2582    let addr = 0, data0 = 0, data1 = 0 in {
2583      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2584      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2585    } // end addr = 0, data0 = 0, data1 = 0
2586  } // end mayLoad = 1, mayStore = 1
2587}
2588
2589multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2590  dag outs = (outs VGPR_32:$vdst),
2591  dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
2592  string asm = opName#" $vdst, $addr"#"$offset gds"> {
2593
2594  def "" : DS_Pseudo <opName, outs, ins, []>;
2595
2596  let data0 = 0, data1 = 0, gds = 1 in {
2597    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2598    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2599  } // end data0 = 0, data1 = 0, gds = 1
2600}
2601
2602multiclass DS_1A_GDS <bits<8> op, string opName,
2603  dag outs = (outs),
2604  dag ins = (ins VGPR_32:$addr),
2605  string asm = opName#" $addr gds"> {
2606
2607  def "" : DS_Pseudo <opName, outs, ins, []>;
2608
2609  let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2610    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2611    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2612  } // end vdst = 0, data = 0, data1 = 0, gds = 1
2613}
2614
2615multiclass DS_1A <bits<8> op, string opName,
2616  dag outs = (outs),
2617  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2618  string asm = opName#" $addr"#"$offset"#"$gds"> {
2619
2620  let mayLoad = 1, mayStore = 1 in {
2621    def "" : DS_Pseudo <opName, outs, ins, []>;
2622
2623    let vdst = 0, data0 = 0, data1 = 0 in {
2624      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2625      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2626    } // let vdst = 0, data0 = 0, data1 = 0
2627  } // end mayLoad = 1, mayStore = 1
2628}
2629
2630//===----------------------------------------------------------------------===//
2631// MTBUF classes
2632//===----------------------------------------------------------------------===//
2633
2634class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2635  MTBUF <outs, ins, "", pattern>,
2636  SIMCInstr<opName, SISubtarget.NONE> {
2637  let isPseudo = 1;
2638  let isCodeGenOnly = 1;
2639}
2640
2641class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2642                    string asm> :
2643  MTBUF <outs, ins, asm, []>,
2644  MTBUFe <op>,
2645  SIMCInstr<opName, SISubtarget.SI> {
2646  let DecoderNamespace="SICI";
2647  let DisableDecoder = DisableSIDecoder;
2648}
2649
2650class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2651  MTBUF <outs, ins, asm, []>,
2652  MTBUFe_vi <op>,
2653  SIMCInstr <opName, SISubtarget.VI> {
2654  let DecoderNamespace="VI";
2655  let DisableDecoder = DisableVIDecoder;
2656}
2657
2658multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2659                    list<dag> pattern> {
2660
2661  def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2662
2663  def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2664
2665  def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2666
2667}
2668
2669let mayStore = 1, mayLoad = 0 in {
2670
2671multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2672                               RegisterClass regClass> : MTBUF_m <
2673  op, opName, (outs),
2674  (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2675   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2676   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2677  opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2678        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2679>;
2680
2681} // mayStore = 1, mayLoad = 0
2682
2683let mayLoad = 1, mayStore = 0 in {
2684
2685multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2686                              RegisterClass regClass> : MTBUF_m <
2687  op, opName, (outs regClass:$dst),
2688  (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2689       i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2690       i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2691  opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2692        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2693>;
2694
2695} // mayLoad = 1, mayStore = 0
2696
2697//===----------------------------------------------------------------------===//
2698// MUBUF classes
2699//===----------------------------------------------------------------------===//
2700
2701class mubuf <bits<7> si, bits<7> vi = si> {
2702  field bits<7> SI = si;
2703  field bits<7> VI = vi;
2704}
2705
2706let isCodeGenOnly = 0 in {
2707
2708class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2709  MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2710  let lds  = 0;
2711}
2712
2713} // End let isCodeGenOnly = 0
2714
2715class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2716  MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2717  let lds = 0;
2718}
2719
2720class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2721  bit IsAddr64 = is_addr64;
2722  string OpName = NAME # suffix;
2723}
2724
2725class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2726  MUBUF <outs, ins, "", pattern>,
2727  SIMCInstr<opName, SISubtarget.NONE> {
2728  let isPseudo = 1;
2729  let isCodeGenOnly = 1;
2730
2731  // dummy fields, so that we can use let statements around multiclasses
2732  bits<1> offen;
2733  bits<1> idxen;
2734  bits<8> vaddr;
2735  bits<1> glc;
2736  bits<1> slc;
2737  bits<1> tfe;
2738  bits<8> soffset;
2739}
2740
2741class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2742                     string asm> :
2743  MUBUF <outs, ins, asm, []>,
2744  MUBUFe <op.SI>,
2745  SIMCInstr<opName, SISubtarget.SI> {
2746  let lds = 0;
2747  let AssemblerPredicate = SIAssemblerPredicate;
2748  let DecoderNamespace="SICI";
2749  let DisableDecoder = DisableSIDecoder;
2750}
2751
2752class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2753                     string asm> :
2754  MUBUF <outs, ins, asm, []>,
2755  MUBUFe_vi <op.VI>,
2756  SIMCInstr<opName, SISubtarget.VI> {
2757  let lds = 0;
2758  let AssemblerPredicate = VIAssemblerPredicate;
2759  let DecoderNamespace="VI";
2760  let DisableDecoder = DisableVIDecoder;
2761}
2762
2763multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2764                    list<dag> pattern> {
2765
2766  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2767           MUBUFAddr64Table <0>;
2768
2769  let addr64 = 0, isCodeGenOnly = 0 in {
2770    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2771  }
2772
2773  def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2774}
2775
2776multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2777                          dag ins, string asm, list<dag> pattern> {
2778
2779  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2780           MUBUFAddr64Table <1>;
2781
2782  let addr64 = 1, isCodeGenOnly = 0 in {
2783    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2784  }
2785
2786  // There is no VI version. If the pseudo is selected, it should be lowered
2787  // for VI appropriately.
2788}
2789
2790multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2791                                string asm, list<dag> pattern, bit is_return> {
2792
2793  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2794           MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2795           AtomicNoRet<NAME#"_OFFSET", is_return>;
2796
2797  let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2798    let addr64 = 0 in {
2799      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2800    }
2801
2802    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2803  }
2804}
2805
2806multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2807                                string asm, list<dag> pattern, bit is_return> {
2808
2809  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2810           MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2811           AtomicNoRet<NAME#"_ADDR64", is_return>;
2812
2813  let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2814    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2815  }
2816
2817  // There is no VI version. If the pseudo is selected, it should be lowered
2818  // for VI appropriately.
2819}
2820
2821multiclass MUBUFAtomicOther_m <mubuf op, string opName, dag outs, dag ins,
2822                               string asm, list<dag> pattern, bit is_return> {
2823
2824  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2825           AtomicNoRet<opName, is_return>;
2826
2827  let tfe = 0 in {
2828    let addr64 = 0 in {
2829      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2830    }
2831
2832    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2833  }
2834}
2835
2836multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2837                         ValueType vt, SDPatternOperator atomic> {
2838
2839  let mayStore = 1, mayLoad = 1, hasPostISelHook = 1, hasSideEffects = 1 in {
2840
2841    // No return variants
2842    let glc = 0 in {
2843
2844      defm _ADDR64 : MUBUFAtomicAddr64_m <
2845        op, name#"_addr64", (outs),
2846        (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2847             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2848        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2849      >;
2850
2851      defm _OFFSET : MUBUFAtomicOffset_m <
2852        op, name#"_offset", (outs),
2853        (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2854             slc:$slc),
2855        name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2856      >;
2857
2858      let offen = 1, idxen = 0 in {
2859        defm _OFFEN : MUBUFAtomicOther_m <
2860          op, name#"_offen", (outs),
2861          (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2862                mbuf_offset:$offset, slc:$slc),
2863          name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$slc", [], 0
2864        >;
2865      }
2866
2867      let offen = 0, idxen = 1 in {
2868        defm _IDXEN : MUBUFAtomicOther_m <
2869          op, name#"_idxen", (outs),
2870          (ins rc:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2871                mbuf_offset:$offset, slc:$slc),
2872          name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$slc", [], 0
2873        >;
2874      }
2875
2876      let offen = 1, idxen = 1 in {
2877        defm _BOTHEN : MUBUFAtomicOther_m <
2878          op, name#"_bothen", (outs),
2879          (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2880                mbuf_offset:$offset, slc:$slc),
2881          name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$slc",
2882          [], 0
2883        >;
2884      }
2885    } // glc = 0
2886
2887    // Variant that return values
2888    let glc = 1, Constraints = "$vdata = $vdata_in",
2889        DisableEncoding = "$vdata_in"  in {
2890
2891      defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2892        op, name#"_rtn_addr64", (outs rc:$vdata),
2893        (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc,
2894             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2895        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2896        [(set vt:$vdata,
2897         (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2898	                            i16:$offset, i1:$slc), vt:$vdata_in))], 1
2899      >;
2900
2901      defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2902        op, name#"_rtn_offset", (outs rc:$vdata),
2903        (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2904             mbuf_offset:$offset, slc:$slc),
2905        name#" $vdata, $srsrc, $soffset"#"$offset"#" glc$slc",
2906        [(set vt:$vdata,
2907         (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2908                                    i1:$slc), vt:$vdata_in))], 1
2909      >;
2910
2911      let offen = 1, idxen = 0 in {
2912        defm _RTN_OFFEN : MUBUFAtomicOther_m <
2913          op, name#"_rtn_offen", (outs rc:$vdata),
2914          (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2915                mbuf_offset:$offset, slc:$slc),
2916          name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#" glc"#"$slc",
2917          [], 1
2918        >;
2919      }
2920
2921      let offen = 0, idxen = 1 in {
2922        defm _RTN_IDXEN : MUBUFAtomicOther_m <
2923          op, name#"_rtn_idxen", (outs rc:$vdata),
2924          (ins rc:$vdata_in, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2925                mbuf_offset:$offset, slc:$slc),
2926          name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#" glc"#"$slc",
2927          [], 1
2928        >;
2929      }
2930
2931      let offen = 1, idxen = 1 in {
2932        defm _RTN_BOTHEN : MUBUFAtomicOther_m <
2933          op, name#"_rtn_bothen", (outs rc:$vdata),
2934          (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2935                mbuf_offset:$offset, slc:$slc),
2936          name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#" glc"#"$slc",
2937          [], 1
2938        >;
2939      }
2940    } // glc = 1
2941
2942  } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2943}
2944
2945// FIXME: tfe can't be an operand because it requires a separate
2946// opcode because it needs an N+1 register class dest register.
2947multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2948                              ValueType load_vt = i32,
2949                              SDPatternOperator ld = null_frag> {
2950
2951  let mayLoad = 1, mayStore = 0 in {
2952    let offen = 0, idxen = 0, vaddr = 0 in {
2953      defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2954                           (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2955                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2956                           name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2957                           [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2958                                                     i32:$soffset, i16:$offset,
2959                                                     i1:$glc, i1:$slc, i1:$tfe)))]>;
2960    }
2961
2962    let offen = 1, idxen = 0  in {
2963      defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2964                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2965                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2966                           tfe:$tfe),
2967                           name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2968    }
2969
2970    let offen = 0, idxen = 1 in {
2971      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2972                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2973                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2974                           slc:$slc, tfe:$tfe),
2975                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2976    }
2977
2978    let offen = 1, idxen = 1 in {
2979      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2980                           (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2981                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2982                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2983    }
2984
2985    let offen = 0, idxen = 0 in {
2986      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2987                           (ins VReg_64:$vaddr, SReg_128:$srsrc,
2988                                SCSrc_32:$soffset, mbuf_offset:$offset,
2989				glc:$glc, slc:$slc, tfe:$tfe),
2990                           name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2991                                "$glc"#"$slc"#"$tfe",
2992                           [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2993                                                  i64:$vaddr, i32:$soffset,
2994                                                  i16:$offset, i1:$glc, i1:$slc,
2995						  i1:$tfe)))]>;
2996    }
2997  }
2998}
2999
3000multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
3001                          ValueType store_vt = i32, SDPatternOperator st = null_frag> {
3002  let mayLoad = 0, mayStore = 1 in {
3003    defm : MUBUF_m <op, name, (outs),
3004                    (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3005                    mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
3006                    tfe:$tfe),
3007                    name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
3008                         "$glc"#"$slc"#"$tfe", []>;
3009
3010    let offen = 0, idxen = 0, vaddr = 0 in {
3011      defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
3012                              (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
3013                              mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3014                              name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
3015                              [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
3016                                   i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
3017    } // offen = 0, idxen = 0, vaddr = 0
3018
3019    let offen = 1, idxen = 0  in {
3020      defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
3021                             (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3022                              SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
3023                              slc:$slc, tfe:$tfe),
3024                             name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
3025                             "$glc"#"$slc"#"$tfe", []>;
3026    } // end offen = 1, idxen = 0
3027
3028    let offen = 0, idxen = 1 in {
3029      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
3030                           (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
3031                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
3032                           slc:$slc, tfe:$tfe),
3033                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
3034    }
3035
3036    let offen = 1, idxen = 1 in {
3037      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
3038                           (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
3039                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
3040                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
3041    }
3042
3043    let offen = 0, idxen = 0 in {
3044      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
3045                                    (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
3046                                         SCSrc_32:$soffset,
3047                                         mbuf_offset:$offset, glc:$glc, slc:$slc,
3048                                         tfe:$tfe),
3049                                    name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
3050                                         "$offset"#"$glc"#"$slc"#"$tfe",
3051                                    [(st store_vt:$vdata,
3052                                      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
3053                                                   i32:$soffset, i16:$offset,
3054                                                   i1:$glc, i1:$slc, i1:$tfe))]>;
3055    }
3056  } // End mayLoad = 0, mayStore = 1
3057}
3058
3059// For cache invalidation instructions.
3060multiclass MUBUF_Invalidate <mubuf op, string opName, SDPatternOperator node> {
3061  let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in {
3062    def "" : MUBUF_Pseudo <opName, (outs), (ins), [(node)]>;
3063
3064    // Set everything to 0.
3065    let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0,
3066        vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in {
3067      let addr64 = 0 in {
3068        def _si : MUBUF_Real_si <op, opName, (outs), (ins), opName>;
3069      }
3070
3071      def _vi : MUBUF_Real_vi <op, opName, (outs), (ins), opName>;
3072    }
3073  } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = ""
3074}
3075
3076//===----------------------------------------------------------------------===//
3077// FLAT classes
3078//===----------------------------------------------------------------------===//
3079
3080class flat <bits<7> ci, bits<7> vi = ci> {
3081  field bits<7> CI = ci;
3082  field bits<7> VI = vi;
3083}
3084
3085class FLAT_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
3086     FLAT <0, outs, ins, "", pattern>,
3087      SIMCInstr<opName, SISubtarget.NONE> {
3088  let isPseudo = 1;
3089  let isCodeGenOnly = 1;
3090}
3091
3092class FLAT_Real_ci <bits<7> op, string opName, dag outs, dag ins, string asm> :
3093    FLAT <op, outs, ins, asm, []>,
3094    SIMCInstr<opName, SISubtarget.SI> {
3095  let AssemblerPredicate = isCIOnly;
3096  let DecoderNamespace="CI";
3097}
3098
3099class FLAT_Real_vi <bits<7> op, string opName, dag outs, dag ins, string asm> :
3100    FLAT <op, outs, ins, asm, []>,
3101    SIMCInstr<opName, SISubtarget.VI> {
3102  let AssemblerPredicate = VIAssemblerPredicate;
3103  let DecoderNamespace="VI";
3104  let DisableDecoder = DisableVIDecoder;
3105}
3106
3107multiclass FLAT_AtomicRet_m <flat op, dag outs, dag ins, string asm,
3108                   list<dag> pattern> {
3109  def "" : FLAT_Pseudo <NAME#"_RTN", outs, ins, pattern>,
3110               AtomicNoRet <NAME, 1>;
3111
3112  def _ci : FLAT_Real_ci <op.CI, NAME#"_RTN", outs, ins, asm>;
3113
3114  def _vi : FLAT_Real_vi <op.VI, NAME#"_RTN", outs, ins, asm>;
3115}
3116
3117multiclass FLAT_Load_Helper <flat op, string asm_name,
3118    RegisterClass regClass,
3119    dag outs = (outs regClass:$vdst),
3120    dag ins = (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
3121    string asm = asm_name#" $vdst, $addr"#"$glc"#"$slc"#"$tfe"> {
3122
3123  let data = 0, mayLoad = 1 in {
3124
3125    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3126
3127    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3128
3129    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3130  }
3131}
3132
3133multiclass FLAT_Store_Helper <flat op, string asm_name,
3134    RegisterClass vdataClass,
3135    dag outs = (outs),
3136    dag ins = (ins VReg_64:$addr, vdataClass:$data, glc_flat:$glc,
3137                   slc_flat:$slc, tfe_flat:$tfe),
3138    string asm = asm_name#" $addr, $data"#"$glc"#"$slc"#"$tfe"> {
3139
3140  let mayLoad = 0, mayStore = 1, vdst = 0 in {
3141
3142    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
3143
3144    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
3145
3146    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
3147  }
3148}
3149
3150multiclass FLAT_ATOMIC <flat op, string asm_name, RegisterClass vdst_rc,
3151    RegisterClass data_rc = vdst_rc,
3152    dag outs_noret = (outs),
3153    string asm_noret = asm_name#" $addr, $data"#"$slc"#"$tfe"> {
3154
3155  let mayLoad = 1, mayStore = 1, glc = 0, vdst = 0, AsmMatchConverter = "cvtFlatAtomic" in {
3156    def "" : FLAT_Pseudo <NAME, outs_noret,
3157                          (ins VReg_64:$addr, data_rc:$data,
3158                               slc_flat_atomic:$slc, tfe_flat_atomic:$tfe), []>,
3159             AtomicNoRet <NAME, 0>;
3160
3161    def _ci : FLAT_Real_ci <op.CI, NAME, outs_noret,
3162                            (ins VReg_64:$addr, data_rc:$data,
3163                                 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe),
3164                            asm_noret>;
3165
3166    def _vi : FLAT_Real_vi <op.VI, NAME, outs_noret,
3167                            (ins VReg_64:$addr, data_rc:$data,
3168                                 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe),
3169                            asm_noret>;
3170  }
3171
3172  let glc = 1, hasPostISelHook = 1, AsmMatchConverter = "cvtFlatAtomic" in {
3173    defm _RTN : FLAT_AtomicRet_m <op, (outs vdst_rc:$vdst),
3174                        (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
3175                             tfe_flat_atomic:$tfe),
3176                        asm_name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>;
3177  }
3178}
3179
3180class MIMG_Mask <string op, int channels> {
3181  string Op = op;
3182  int Channels = channels;
3183}
3184
3185class mimg <bits<7> si, bits<7> vi = si> {
3186  field bits<7> SI = si;
3187  field bits<7> VI = vi;
3188}
3189
3190class MIMG_Helper <dag outs, dag ins, string asm,
3191                   string dns=""> : MIMG<outs, ins, asm,[]> {
3192  let mayLoad = 1;
3193  let mayStore = 0;
3194  let hasPostISelHook = 1;
3195  let DecoderNamespace = dns;
3196  let isAsmParserOnly = !if(!eq(dns,""), 1, 0);
3197  let AsmMatchConverter = "cvtMIMG";
3198}
3199
3200class MIMG_NoSampler_Helper <bits<7> op, string asm,
3201                             RegisterClass dst_rc,
3202                             RegisterClass addr_rc,
3203                             string dns=""> : MIMG_Helper <
3204  (outs dst_rc:$vdata),
3205  (ins addr_rc:$vaddr, SReg_256:$srsrc,
3206       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3207       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3208  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3209  dns>, MIMGe<op> {
3210  let ssamp = 0;
3211}
3212
3213multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
3214                                      RegisterClass dst_rc,
3215                                      int channels> {
3216  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32,
3217                                   !if(!eq(channels, 1), "AMDGPU", "")>,
3218            MIMG_Mask<asm#"_V1", channels>;
3219  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
3220            MIMG_Mask<asm#"_V2", channels>;
3221  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
3222            MIMG_Mask<asm#"_V4", channels>;
3223}
3224
3225multiclass MIMG_NoSampler <bits<7> op, string asm> {
3226  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
3227  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
3228  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
3229  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
3230}
3231
3232class MIMG_Store_Helper <bits<7> op, string asm,
3233                         RegisterClass data_rc,
3234                         RegisterClass addr_rc> : MIMG_Helper <
3235  (outs),
3236  (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3237       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3238       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3239  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3240     >, MIMGe<op> {
3241  let ssamp = 0;
3242  let mayLoad = 1; // TableGen requires this for matching with the intrinsics
3243  let mayStore = 1;
3244  let hasSideEffects = 1;
3245  let hasPostISelHook = 0;
3246}
3247
3248multiclass MIMG_Store_Addr_Helper <bits<7> op, string asm,
3249                                  RegisterClass data_rc,
3250                                  int channels> {
3251  def _V1 : MIMG_Store_Helper <op, asm, data_rc, VGPR_32>,
3252            MIMG_Mask<asm#"_V1", channels>;
3253  def _V2 : MIMG_Store_Helper <op, asm, data_rc, VReg_64>,
3254            MIMG_Mask<asm#"_V2", channels>;
3255  def _V4 : MIMG_Store_Helper <op, asm, data_rc, VReg_128>,
3256            MIMG_Mask<asm#"_V4", channels>;
3257}
3258
3259multiclass MIMG_Store <bits<7> op, string asm> {
3260  defm _V1 : MIMG_Store_Addr_Helper <op, asm, VGPR_32, 1>;
3261  defm _V2 : MIMG_Store_Addr_Helper <op, asm, VReg_64, 2>;
3262  defm _V3 : MIMG_Store_Addr_Helper <op, asm, VReg_96, 3>;
3263  defm _V4 : MIMG_Store_Addr_Helper <op, asm, VReg_128, 4>;
3264}
3265
3266class MIMG_Atomic_Helper <string asm, RegisterClass data_rc,
3267                          RegisterClass addr_rc> : MIMG_Helper <
3268    (outs data_rc:$vdst),
3269    (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3270         dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3271         r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3272    asm#" $vdst, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3273  > {
3274  let mayStore = 1;
3275  let hasSideEffects = 1;
3276  let hasPostISelHook = 0;
3277  let Constraints = "$vdst = $vdata";
3278  let AsmMatchConverter = "cvtMIMGAtomic";
3279}
3280
3281class MIMG_Atomic_Real_si<mimg op, string name, string asm,
3282  RegisterClass data_rc, RegisterClass addr_rc> :
3283  MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3284  SIMCInstr<name, SISubtarget.SI>,
3285  MIMGe<op.SI> {
3286  let isCodeGenOnly = 0;
3287  let AssemblerPredicates = [isSICI];
3288  let DecoderNamespace = "SICI";
3289  let DisableDecoder = DisableSIDecoder;
3290}
3291
3292class MIMG_Atomic_Real_vi<mimg op, string name, string asm,
3293  RegisterClass data_rc, RegisterClass addr_rc> :
3294  MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3295  SIMCInstr<name, SISubtarget.VI>,
3296  MIMGe<op.VI> {
3297  let isCodeGenOnly = 0;
3298  let AssemblerPredicates = [isVI];
3299  let DecoderNamespace = "VI";
3300  let DisableDecoder = DisableVIDecoder;
3301}
3302
3303multiclass MIMG_Atomic_Helper_m <mimg op, string name, string asm,
3304                                 RegisterClass data_rc, RegisterClass addr_rc> {
3305  let isPseudo = 1, isCodeGenOnly = 1 in {
3306    def "" : MIMG_Atomic_Helper<asm, data_rc, addr_rc>,
3307             SIMCInstr<name, SISubtarget.NONE>;
3308  }
3309
3310  let ssamp = 0 in {
3311    def _si : MIMG_Atomic_Real_si<op, name, asm, data_rc, addr_rc>;
3312
3313    def _vi : MIMG_Atomic_Real_vi<op, name, asm, data_rc, addr_rc>;
3314  }
3315}
3316
3317multiclass MIMG_Atomic <mimg op, string asm, RegisterClass data_rc = VGPR_32> {
3318  defm _V1 : MIMG_Atomic_Helper_m <op, asm # "_V1", asm, data_rc, VGPR_32>;
3319  defm _V2 : MIMG_Atomic_Helper_m <op, asm # "_V2", asm, data_rc, VReg_64>;
3320  defm _V4 : MIMG_Atomic_Helper_m <op, asm # "_V3", asm, data_rc, VReg_128>;
3321}
3322
3323class MIMG_Sampler_Helper <bits<7> op, string asm,
3324                           RegisterClass dst_rc,
3325                           RegisterClass src_rc,
3326                           int wqm,
3327                           string dns=""> : MIMG_Helper <
3328  (outs dst_rc:$vdata),
3329  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3330       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3331       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3332  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3333  dns>, MIMGe<op> {
3334  let WQM = wqm;
3335}
3336
3337multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
3338                                    RegisterClass dst_rc,
3339                                    int channels, int wqm> {
3340  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm,
3341                                 !if(!eq(channels, 1), "AMDGPU", "")>,
3342            MIMG_Mask<asm#"_V1", channels>;
3343  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
3344            MIMG_Mask<asm#"_V2", channels>;
3345  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
3346            MIMG_Mask<asm#"_V4", channels>;
3347  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
3348            MIMG_Mask<asm#"_V8", channels>;
3349  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
3350            MIMG_Mask<asm#"_V16", channels>;
3351}
3352
3353multiclass MIMG_Sampler <bits<7> op, string asm, int wqm=0> {
3354  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3355  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, wqm>;
3356  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, wqm>;
3357  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, wqm>;
3358}
3359
3360multiclass MIMG_Sampler_WQM <bits<7> op, string asm> : MIMG_Sampler<op, asm, 1>;
3361
3362class MIMG_Gather_Helper <bits<7> op, string asm,
3363                          RegisterClass dst_rc,
3364                          RegisterClass src_rc, int wqm> : MIMG <
3365  (outs dst_rc:$vdata),
3366  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3367       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3368       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3369  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3370  []>, MIMGe<op> {
3371  let mayLoad = 1;
3372  let mayStore = 0;
3373
3374  // DMASK was repurposed for GATHER4. 4 components are always
3375  // returned and DMASK works like a swizzle - it selects
3376  // the component to fetch. The only useful DMASK values are
3377  // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
3378  // (red,red,red,red) etc.) The ISA document doesn't mention
3379  // this.
3380  // Therefore, disable all code which updates DMASK by setting these two:
3381  let MIMG = 0;
3382  let hasPostISelHook = 0;
3383  let WQM = wqm;
3384
3385  let isAsmParserOnly = 1; // TBD: fix it later
3386}
3387
3388multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
3389                                    RegisterClass dst_rc,
3390                                    int channels, int wqm> {
3391  def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
3392            MIMG_Mask<asm#"_V1", channels>;
3393  def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
3394            MIMG_Mask<asm#"_V2", channels>;
3395  def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
3396            MIMG_Mask<asm#"_V4", channels>;
3397  def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
3398            MIMG_Mask<asm#"_V8", channels>;
3399  def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
3400            MIMG_Mask<asm#"_V16", channels>;
3401}
3402
3403multiclass MIMG_Gather <bits<7> op, string asm, int wqm=0> {
3404  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3405  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, wqm>;
3406  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, wqm>;
3407  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, wqm>;
3408}
3409
3410multiclass MIMG_Gather_WQM <bits<7> op, string asm> : MIMG_Gather<op, asm, 1>;
3411
3412//===----------------------------------------------------------------------===//
3413// Vector instruction mappings
3414//===----------------------------------------------------------------------===//
3415
3416// Maps an opcode in e32 form to its e64 equivalent
3417def getVOPe64 : InstrMapping {
3418  let FilterClass = "VOP";
3419  let RowFields = ["OpName"];
3420  let ColFields = ["Size"];
3421  let KeyCol = ["4"];
3422  let ValueCols = [["8"]];
3423}
3424
3425// Maps an opcode in e64 form to its e32 equivalent
3426def getVOPe32 : InstrMapping {
3427  let FilterClass = "VOP";
3428  let RowFields = ["OpName"];
3429  let ColFields = ["Size"];
3430  let KeyCol = ["8"];
3431  let ValueCols = [["4"]];
3432}
3433
3434def getMaskedMIMGOp : InstrMapping {
3435  let FilterClass = "MIMG_Mask";
3436  let RowFields = ["Op"];
3437  let ColFields = ["Channels"];
3438  let KeyCol = ["4"];
3439  let ValueCols = [["1"], ["2"], ["3"] ];
3440}
3441
3442// Maps an commuted opcode to its original version
3443def getCommuteOrig : InstrMapping {
3444  let FilterClass = "VOP2_REV";
3445  let RowFields = ["RevOp"];
3446  let ColFields = ["IsOrig"];
3447  let KeyCol = ["0"];
3448  let ValueCols = [["1"]];
3449}
3450
3451// Maps an original opcode to its commuted version
3452def getCommuteRev : InstrMapping {
3453  let FilterClass = "VOP2_REV";
3454  let RowFields = ["RevOp"];
3455  let ColFields = ["IsOrig"];
3456  let KeyCol = ["1"];
3457  let ValueCols = [["0"]];
3458}
3459
3460def getCommuteCmpOrig : InstrMapping {
3461  let FilterClass = "VOP2_REV";
3462  let RowFields = ["RevOp"];
3463  let ColFields = ["IsOrig"];
3464  let KeyCol = ["0"];
3465  let ValueCols = [["1"]];
3466}
3467
3468// Maps an original opcode to its commuted version
3469def getCommuteCmpRev : InstrMapping {
3470  let FilterClass = "VOP2_REV";
3471  let RowFields = ["RevOp"];
3472  let ColFields = ["IsOrig"];
3473  let KeyCol = ["1"];
3474  let ValueCols = [["0"]];
3475}
3476
3477
3478def getMCOpcodeGen : InstrMapping {
3479  let FilterClass = "SIMCInstr";
3480  let RowFields = ["PseudoInstr"];
3481  let ColFields = ["Subtarget"];
3482  let KeyCol = [!cast<string>(SISubtarget.NONE)];
3483  let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
3484}
3485
3486def getAddr64Inst : InstrMapping {
3487  let FilterClass = "MUBUFAddr64Table";
3488  let RowFields = ["OpName"];
3489  let ColFields = ["IsAddr64"];
3490  let KeyCol = ["0"];
3491  let ValueCols = [["1"]];
3492}
3493
3494// Maps an atomic opcode to its version with a return value.
3495def getAtomicRetOp : InstrMapping {
3496  let FilterClass = "AtomicNoRet";
3497  let RowFields = ["NoRetOp"];
3498  let ColFields = ["IsRet"];
3499  let KeyCol = ["0"];
3500  let ValueCols = [["1"]];
3501}
3502
3503// Maps an atomic opcode to its returnless version.
3504def getAtomicNoRetOp : InstrMapping {
3505  let FilterClass = "AtomicNoRet";
3506  let RowFields = ["NoRetOp"];
3507  let ColFields = ["IsRet"];
3508  let KeyCol = ["1"];
3509  let ValueCols = [["0"]];
3510}
3511
3512include "SIInstructions.td"
3513include "CIInstructions.td"
3514include "VIInstructions.td"
3515