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 = "isImm";
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 = "isImm";
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 = "isImm";
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 = "isImm";
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 = "isImm";
513  let ParserMethod = "parseVOP3OptionalOps";
514  let RenderMethod = "addImmOperands";
515  let IsOptional = 1;
516}
517
518def ClampMatchClass : AsmOperandClass {
519  let Name = "Clamp";
520  let PredicateMethod = "isImm";
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
537class OptionalImmAsmOperand <string OpName> : AsmOperandClass {
538  let Name = "Imm"#OpName;
539  let PredicateMethod = "isImm";
540  let RenderMethod = "addImmOperands";
541  let IsOptional = 1;
542}
543
544def DMaskMatchClass : AsmOperandClass {
545  let Name = "DMask";
546  let PredicateMethod = "isDMask";
547  let ParserMethod = "parseDMask";
548  let RenderMethod = "addImmOperands";
549  let IsOptional = 1;
550}
551
552class NamedBitMatchClass<string BitName> : AsmOperandClass {
553  let Name = "Imm"#BitName;
554  let PredicateMethod = "is"#BitName;
555  let ParserMethod = "parse"#BitName;
556  let RenderMethod = "addImmOperands";
557  let IsOptional = 1;
558}
559
560class NamedBitOperand<string BitName> : Operand<i1> {
561  let PrintMethod = "print"#BitName;
562}
563
564let OperandType = "OPERAND_IMMEDIATE" in {
565
566def offen : Operand<i1> {
567  let PrintMethod = "printOffen";
568  let ParserMatchClass = OptionalImmAsmOperand<"offen">;
569}
570def idxen : Operand<i1> {
571  let PrintMethod = "printIdxen";
572  let ParserMatchClass = OptionalImmAsmOperand<"idxen">;
573}
574def addr64 : Operand<i1> {
575  let PrintMethod = "printAddr64";
576}
577def mbuf_offset : Operand<i16> {
578  let PrintMethod = "printMBUFOffset";
579  let ParserMatchClass = MubufOffsetMatchClass;
580}
581class ds_offset_base <AsmOperandClass mc> : Operand<i16> {
582  let PrintMethod = "printDSOffset";
583  let ParserMatchClass = mc;
584}
585def ds_offset : ds_offset_base <DSOffsetMatchClass>;
586def ds_offset_gds : ds_offset_base <DSOffsetGDSMatchClass>;
587
588def ds_offset0 : Operand<i8> {
589  let PrintMethod = "printDSOffset0";
590  let ParserMatchClass = DSOffset01MatchClass;
591}
592def ds_offset1 : Operand<i8> {
593  let PrintMethod = "printDSOffset1";
594  let ParserMatchClass = DSOffset01MatchClass;
595}
596class gds_base <AsmOperandClass mc> : Operand <i1> {
597  let PrintMethod = "printGDS";
598  let ParserMatchClass = mc;
599}
600def gds : gds_base <GDSMatchClass>;
601
602def gds01 : gds_base <GDS01MatchClass>;
603
604class glc_base <AsmOperandClass mc> : Operand <i1> {
605  let PrintMethod = "printGLC";
606  let ParserMatchClass = mc;
607}
608
609def glc : glc_base <GLCMubufMatchClass>;
610def glc_flat : glc_base <GLCFlatMatchClass>;
611
612class slc_base <AsmOperandClass mc> : Operand <i1> {
613  let PrintMethod = "printSLC";
614  let ParserMatchClass = mc;
615}
616
617def slc : slc_base <SLCMubufMatchClass>;
618def slc_flat : slc_base <SLCFlatMatchClass>;
619def slc_flat_atomic : slc_base <SLCFlatAtomicMatchClass>;
620
621class tfe_base <AsmOperandClass mc> : Operand <i1> {
622  let PrintMethod = "printTFE";
623  let ParserMatchClass = mc;
624}
625
626def tfe : tfe_base <TFEMubufMatchClass>;
627def tfe_flat : tfe_base <TFEFlatMatchClass>;
628def tfe_flat_atomic : tfe_base <TFEFlatAtomicMatchClass>;
629
630def omod : Operand <i32> {
631  let PrintMethod = "printOModSI";
632  let ParserMatchClass = OModMatchClass;
633}
634
635def ClampMod : Operand <i1> {
636  let PrintMethod = "printClampSI";
637  let ParserMatchClass = ClampMatchClass;
638}
639
640def smrd_offset : Operand <i32> {
641  let PrintMethod = "printU32ImmOperand";
642  let ParserMatchClass = SMRDOffsetMatchClass;
643}
644
645def smrd_literal_offset : Operand <i32> {
646  let PrintMethod = "printU32ImmOperand";
647  let ParserMatchClass = SMRDLiteralOffsetMatchClass;
648}
649
650def dmask : Operand <i32> {
651  let PrintMethod = "printDMask";
652  let ParserMatchClass = DMaskMatchClass;
653}
654
655def unorm : NamedBitOperand<"UNorm"> {
656  let ParserMatchClass = NamedBitMatchClass<"UNorm">;
657}
658
659def da : NamedBitOperand<"DA"> {
660  let ParserMatchClass = NamedBitMatchClass<"DA">;
661}
662
663def r128 : NamedBitOperand<"R128"> {
664  let ParserMatchClass = NamedBitMatchClass<"R128">;
665}
666
667def lwe : NamedBitOperand<"LWE"> {
668  let ParserMatchClass = NamedBitMatchClass<"LWE">;
669}
670
671} // End OperandType = "OPERAND_IMMEDIATE"
672
673
674def VOPDstS64 : VOPDstOperand <SReg_64>;
675
676//===----------------------------------------------------------------------===//
677// Complex patterns
678//===----------------------------------------------------------------------===//
679
680def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
681def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
682
683def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
684def MUBUFAddr64 : ComplexPattern<i64, 7, "SelectMUBUFAddr64">;
685def MUBUFAddr64Atomic : ComplexPattern<i64, 5, "SelectMUBUFAddr64">;
686def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
687def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
688def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
689
690def SMRDImm   : ComplexPattern<i64, 2, "SelectSMRDImm">;
691def SMRDImm32 : ComplexPattern<i64, 2, "SelectSMRDImm32">;
692def SMRDSgpr  : ComplexPattern<i64, 2, "SelectSMRDSgpr">;
693def SMRDBufferImm   : ComplexPattern<i32, 1, "SelectSMRDBufferImm">;
694def SMRDBufferImm32 : ComplexPattern<i32, 1, "SelectSMRDBufferImm32">;
695def SMRDBufferSgpr  : ComplexPattern<i32, 1, "SelectSMRDBufferSgpr">;
696
697def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
698def VOP3NoMods0 : ComplexPattern<untyped, 4, "SelectVOP3NoMods0">;
699def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
700def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
701def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
702def VOP3NoMods : ComplexPattern<untyped, 2, "SelectVOP3NoMods">;
703
704//===----------------------------------------------------------------------===//
705// SI assembler operands
706//===----------------------------------------------------------------------===//
707
708def SIOperand {
709  int ZERO = 0x80;
710  int VCC = 0x6A;
711  int FLAT_SCR = 0x68;
712}
713
714def SRCMODS {
715  int NONE = 0;
716  int NEG = 1;
717}
718
719def DSTCLAMP {
720  int NONE = 0;
721}
722
723def DSTOMOD {
724  int NONE = 0;
725}
726
727//===----------------------------------------------------------------------===//
728//
729// SI Instruction multiclass helpers.
730//
731// Instructions with _32 take 32-bit operands.
732// Instructions with _64 take 64-bit operands.
733//
734// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
735// encoding is the standard encoding, but instruction that make use of
736// any of the instruction modifiers must use the 64-bit encoding.
737//
738// Instructions with _e32 use the 32-bit encoding.
739// Instructions with _e64 use the 64-bit encoding.
740//
741//===----------------------------------------------------------------------===//
742
743class SIMCInstr <string pseudo, int subtarget> {
744  string PseudoInstr = pseudo;
745  int Subtarget = subtarget;
746}
747
748//===----------------------------------------------------------------------===//
749// EXP classes
750//===----------------------------------------------------------------------===//
751
752class EXPCommon : InstSI<
753  (outs),
754  (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
755       VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
756  "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
757  [] > {
758
759  let EXP_CNT = 1;
760  let Uses = [EXEC];
761}
762
763multiclass EXP_m {
764
765  let isPseudo = 1, isCodeGenOnly = 1 in {
766    def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
767  }
768
769  def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe {
770    let DecoderNamespace="SICI";
771    let DisableDecoder = DisableSIDecoder;
772  }
773
774  def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi {
775    let DecoderNamespace="VI";
776    let DisableDecoder = DisableVIDecoder;
777  }
778}
779
780//===----------------------------------------------------------------------===//
781// Scalar classes
782//===----------------------------------------------------------------------===//
783
784class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
785  SOP1 <outs, ins, "", pattern>,
786  SIMCInstr<opName, SISubtarget.NONE> {
787  let isPseudo = 1;
788  let isCodeGenOnly = 1;
789}
790
791class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
792  SOP1 <outs, ins, asm, []>,
793  SOP1e <op.SI>,
794  SIMCInstr<opName, SISubtarget.SI> {
795  let isCodeGenOnly = 0;
796  let AssemblerPredicates = [isSICI];
797  let DecoderNamespace = "SICI";
798  let DisableDecoder = DisableSIDecoder;
799}
800
801class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
802  SOP1 <outs, ins, asm, []>,
803  SOP1e <op.VI>,
804  SIMCInstr<opName, SISubtarget.VI> {
805  let isCodeGenOnly = 0;
806  let AssemblerPredicates = [isVI];
807  let DecoderNamespace = "VI";
808  let DisableDecoder = DisableVIDecoder;
809}
810
811multiclass SOP1_m <sop1 op, string opName, dag outs, dag ins, string asm,
812                   list<dag> pattern> {
813
814  def "" : SOP1_Pseudo <opName, outs, ins, pattern>;
815
816  def _si : SOP1_Real_si <op, opName, outs, ins, asm>;
817
818  def _vi : SOP1_Real_vi <op, opName, outs, ins, asm>;
819
820}
821
822multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
823    op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
824    opName#" $dst, $src0", pattern
825>;
826
827multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
828    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
829    opName#" $dst, $src0", pattern
830>;
831
832// no input, 64-bit output.
833multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
834  def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>;
835
836  def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins),
837    opName#" $dst"> {
838    let ssrc0 = 0;
839  }
840
841  def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins),
842    opName#" $dst"> {
843    let ssrc0 = 0;
844  }
845}
846
847// 64-bit input, no output
848multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
849  def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
850
851  def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
852    opName#" $src0"> {
853    let sdst = 0;
854  }
855
856  def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
857    opName#" $src0"> {
858    let sdst = 0;
859  }
860}
861
862// 64-bit input, 32-bit output.
863multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
864    op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
865    opName#" $dst, $src0", pattern
866>;
867
868class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
869  SOP2<outs, ins, "", pattern>,
870  SIMCInstr<opName, SISubtarget.NONE> {
871  let isPseudo = 1;
872  let isCodeGenOnly = 1;
873  let Size = 4;
874
875  // Pseudo instructions have no encodings, but adding this field here allows
876  // us to do:
877  // let sdst = xxx in {
878  // for multiclasses that include both real and pseudo instructions.
879  field bits<7> sdst = 0;
880}
881
882class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
883  SOP2<outs, ins, asm, []>,
884  SOP2e<op.SI>,
885  SIMCInstr<opName, SISubtarget.SI> {
886  let AssemblerPredicates = [isSICI];
887  let DecoderNamespace = "SICI";
888  let DisableDecoder = DisableSIDecoder;
889}
890
891class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
892  SOP2<outs, ins, asm, []>,
893  SOP2e<op.VI>,
894  SIMCInstr<opName, SISubtarget.VI> {
895  let AssemblerPredicates = [isVI];
896  let DecoderNamespace = "VI";
897  let DisableDecoder = DisableVIDecoder;
898}
899
900multiclass SOP2_m <sop2 op, string opName, dag outs, dag ins, string asm,
901                   list<dag> pattern> {
902
903  def "" : SOP2_Pseudo <opName, outs, ins, pattern>;
904
905  def _si : SOP2_Real_si <op, opName, outs, ins, asm>;
906
907  def _vi : SOP2_Real_vi <op, opName, outs, ins, asm>;
908
909}
910
911multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
912    op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
913    opName#" $dst, $src0, $src1", pattern
914>;
915
916multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
917    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
918    opName#" $dst, $src0, $src1", pattern
919>;
920
921multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
922    op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
923    opName#" $dst, $src0, $src1", pattern
924>;
925
926multiclass SOP2_64_32_32 <sop2 op, string opName, list<dag> pattern> : SOP2_m <
927    op, opName, (outs SReg_64:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
928    opName#" $dst, $src0, $src1", pattern
929>;
930
931class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
932                    string opName, PatLeaf cond> : SOPC <
933  op, (outs), (ins rc:$src0, rc:$src1),
934  opName#" $src0, $src1",
935  [(set SCC, (si_setcc_uniform vt:$src0, vt:$src1, cond))] > {
936  let Defs = [SCC];
937}
938
939class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
940  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
941
942class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
943  : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
944
945class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
946  SOPK <outs, ins, "", pattern>,
947  SIMCInstr<opName, SISubtarget.NONE> {
948  let isPseudo = 1;
949  let isCodeGenOnly = 1;
950}
951
952class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
953  SOPK <outs, ins, asm, []>,
954  SOPKe <op.SI>,
955  SIMCInstr<opName, SISubtarget.SI> {
956  let AssemblerPredicates = [isSICI];
957  let DecoderNamespace = "SICI";
958  let DisableDecoder = DisableSIDecoder;
959  let isCodeGenOnly = 0;
960}
961
962class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
963  SOPK <outs, ins, asm, []>,
964  SOPKe <op.VI>,
965  SIMCInstr<opName, SISubtarget.VI> {
966  let AssemblerPredicates = [isVI];
967  let DecoderNamespace = "VI";
968  let DisableDecoder = DisableVIDecoder;
969  let isCodeGenOnly = 0;
970}
971
972multiclass SOPK_m <sopk op, string opName, dag outs, dag ins, string opAsm,
973                   string asm = opName#opAsm> {
974  def "" : SOPK_Pseudo <opName, outs, ins, []>;
975
976  def _si : SOPK_Real_si <op, opName, outs, ins, asm>;
977
978  def _vi : SOPK_Real_vi <op, opName, outs, ins, asm>;
979
980}
981
982multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
983  def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0),
984    pattern>;
985
986  def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
987    opName#" $dst, $src0">;
988
989  def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
990    opName#" $dst, $src0">;
991}
992
993multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
994  def "" : SOPK_Pseudo <opName, (outs),
995    (ins SReg_32:$src0, u16imm:$src1), pattern> {
996    let Defs = [SCC];
997  }
998
999
1000  def _si : SOPK_Real_si <op, opName, (outs),
1001    (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
1002    let Defs = [SCC];
1003  }
1004
1005  def _vi : SOPK_Real_vi <op, opName, (outs),
1006    (ins SReg_32:$sdst, u16imm:$simm16), opName#" $sdst, $simm16"> {
1007    let Defs = [SCC];
1008  }
1009}
1010
1011multiclass SOPK_32TIE <sopk op, string opName, list<dag> pattern> : SOPK_m <
1012  op, opName, (outs SReg_32:$sdst), (ins SReg_32:$src0, u16imm:$simm16),
1013  " $sdst, $simm16"
1014>;
1015
1016multiclass SOPK_IMM32 <sopk op, string opName, dag outs, dag ins,
1017                       string argAsm, string asm = opName#argAsm> {
1018
1019  def "" : SOPK_Pseudo <opName, outs, ins, []>;
1020
1021  def _si : SOPK <outs, ins, asm, []>,
1022            SOPK64e <op.SI>,
1023            SIMCInstr<opName, SISubtarget.SI> {
1024              let AssemblerPredicates = [isSICI];
1025              let DecoderNamespace = "SICI";
1026              let DisableDecoder = DisableSIDecoder;
1027              let isCodeGenOnly = 0;
1028            }
1029
1030  def _vi : SOPK <outs, ins, asm, []>,
1031            SOPK64e <op.VI>,
1032            SIMCInstr<opName, SISubtarget.VI> {
1033              let AssemblerPredicates = [isVI];
1034              let DecoderNamespace = "VI";
1035              let DisableDecoder = DisableVIDecoder;
1036              let isCodeGenOnly = 0;
1037            }
1038}
1039//===----------------------------------------------------------------------===//
1040// SMRD classes
1041//===----------------------------------------------------------------------===//
1042
1043class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1044  SMRD <outs, ins, "", pattern>,
1045  SIMCInstr<opName, SISubtarget.NONE> {
1046  let isPseudo = 1;
1047  let isCodeGenOnly = 1;
1048}
1049
1050class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
1051                    string asm> :
1052  SMRD <outs, ins, asm, []>,
1053  SMRDe <op, imm>,
1054  SIMCInstr<opName, SISubtarget.SI> {
1055  let AssemblerPredicates = [isSICI];
1056  let DecoderNamespace = "SICI";
1057  let DisableDecoder = DisableSIDecoder;
1058}
1059
1060class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins,
1061                    string asm, list<dag> pattern = []> :
1062  SMRD <outs, ins, asm, pattern>,
1063  SMEMe_vi <op, imm>,
1064  SIMCInstr<opName, SISubtarget.VI> {
1065  let AssemblerPredicates = [isVI];
1066  let DecoderNamespace = "VI";
1067  let DisableDecoder = DisableVIDecoder;
1068}
1069
1070multiclass SMRD_m <smrd op, string opName, bit imm, dag outs, dag ins,
1071                   string asm, list<dag> pattern> {
1072
1073  def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
1074
1075  def _si : SMRD_Real_si <op.SI, opName, imm, outs, ins, asm>;
1076
1077  // glc is only applicable to scalar stores, which are not yet
1078  // implemented.
1079  let glc = 0 in {
1080    def _vi : SMRD_Real_vi <op.VI, opName, imm, outs, ins, asm>;
1081  }
1082}
1083
1084multiclass SMRD_Special <smrd op, string opName, dag outs,
1085                       string opStr = "",
1086                       list<dag> pattern = []> {
1087  let hasSideEffects = 1 in {
1088    def "" : SMRD_Pseudo <opName, outs, (ins), pattern>;
1089
1090    let sbase = 0, offset = 0 in {
1091      let sdst = 0 in {
1092        def _si : SMRD_Real_si <op.SI, opName, 0, outs, (ins), opName#opStr>;
1093      }
1094
1095      let glc = 0, sdata = 0 in {
1096        def _vi : SMRD_Real_vi <op.VI, opName, 0, outs, (ins), opName#opStr>;
1097      }
1098    }
1099  }
1100}
1101
1102multiclass SMRD_Inval <smrd op, string opName,
1103                     SDPatternOperator node> {
1104  let mayStore = 1 in {
1105    defm : SMRD_Special<op, opName, (outs), "", [(node)]>;
1106  }
1107}
1108
1109class SMEM_Inval <bits<8> op, string opName, SDPatternOperator node> :
1110  SMRD_Real_vi<op, opName, 0, (outs), (ins), opName, [(node)]> {
1111  let hasSideEffects = 1;
1112  let mayStore = 1;
1113  let sbase = 0;
1114  let sdata = 0;
1115  let glc = 0;
1116  let offset = 0;
1117}
1118
1119class SMEM_Ret <bits<8> op, string opName, SDPatternOperator node> :
1120  SMRD_Real_vi<op, opName, 0, (outs SReg_64:$dst), (ins),
1121  opName#" $dst", [(set i64:$dst, (node))]> {
1122  let hasSideEffects = 1;
1123  let mayStore = ?;
1124  let mayLoad = ?;
1125  let sbase = 0;
1126  let sdata = 0;
1127  let glc = 0;
1128  let offset = 0;
1129}
1130
1131multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass,
1132                        RegisterClass dstClass> {
1133  defm _IMM : SMRD_m <
1134    op, opName#"_IMM", 1, (outs dstClass:$dst),
1135    (ins baseClass:$sbase, smrd_offset:$offset),
1136    opName#" $dst, $sbase, $offset", []
1137  >;
1138
1139  def _IMM_ci : SMRD <
1140    (outs dstClass:$dst), (ins baseClass:$sbase, smrd_literal_offset:$offset),
1141    opName#" $dst, $sbase, $offset", []>, SMRD_IMMe_ci <op.SI> {
1142    let AssemblerPredicates = [isCIOnly];
1143    let DecoderNamespace = "CI";
1144  }
1145
1146  defm _SGPR : SMRD_m <
1147    op, opName#"_SGPR", 0, (outs dstClass:$dst),
1148    (ins baseClass:$sbase, SReg_32:$soff),
1149    opName#" $dst, $sbase, $soff", []
1150  >;
1151}
1152
1153//===----------------------------------------------------------------------===//
1154// Vector ALU classes
1155//===----------------------------------------------------------------------===//
1156
1157// This must always be right before the operand being input modified.
1158def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
1159  let PrintMethod = "printOperandAndMods";
1160}
1161
1162def InputModsMatchClass : AsmOperandClass {
1163  let Name = "RegOrImmWithInputMods";
1164}
1165
1166def InputModsNoDefault : Operand <i32> {
1167  let PrintMethod = "printOperandAndMods";
1168  let ParserMatchClass = InputModsMatchClass;
1169}
1170
1171class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
1172  int ret =
1173    !if (!eq(Src0.Value, untyped.Value),      0,
1174      !if (!eq(Src1.Value, untyped.Value),    1,   // VOP1
1175         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
1176                                              3))); // VOP3
1177}
1178
1179// Returns the register class to use for the destination of VOP[123C]
1180// instructions for the given VT.
1181class getVALUDstForVT<ValueType VT> {
1182  RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
1183                          !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
1184                            !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
1185                            VOPDstOperand<SReg_64>))); // else VT == i1
1186}
1187
1188// Returns the register class to use for source 0 of VOP[12C]
1189// instructions for the given VT.
1190class getVOPSrc0ForVT<ValueType VT> {
1191  RegisterOperand ret = !if(!eq(VT.Size, 64), VSrc_64, VSrc_32);
1192}
1193
1194// Returns the register class to use for source 1 of VOP[12C] for the
1195// given VT.
1196class getVOPSrc1ForVT<ValueType VT> {
1197  RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
1198}
1199
1200// Returns the register class to use for DPP source operands.
1201class getDPPSrcForVT<ValueType VT> {
1202  RegisterClass ret = !if(!eq(VT.Size, 64), VReg_64, VGPR_32);
1203}
1204
1205// Returns the register class to use for sources of VOP3 instructions for the
1206// given VT.
1207class getVOP3SrcForVT<ValueType VT> {
1208  RegisterOperand ret =
1209  !if(!eq(VT.Size, 64),
1210      VCSrc_64,
1211      !if(!eq(VT.Value, i1.Value),
1212          SCSrc_64,
1213          VCSrc_32
1214       )
1215    );
1216}
1217
1218// Returns 1 if the source arguments have modifiers, 0 if they do not.
1219// XXX - do f16 instructions?
1220class hasModifiers<ValueType SrcVT> {
1221  bit ret =
1222    !if(!eq(SrcVT.Value, f32.Value), 1,
1223    !if(!eq(SrcVT.Value, f64.Value), 1,
1224    0));
1225}
1226
1227// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
1228class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
1229  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
1230            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
1231                                    (ins)));
1232}
1233
1234// Returns the input arguments for VOP3 instructions for the given SrcVT.
1235class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1236                RegisterOperand Src2RC, int NumSrcArgs,
1237                bit HasModifiers> {
1238
1239  dag ret =
1240    !if (!eq(NumSrcArgs, 0),
1241      // VOP1 without input operands (V_NOP, V_CLREXCP)
1242      (ins),
1243      /* else */
1244    !if (!eq(NumSrcArgs, 1),
1245      !if (!eq(HasModifiers, 1),
1246        // VOP1 with modifiers
1247        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1248             ClampMod:$clamp, omod:$omod)
1249      /* else */,
1250        // VOP1 without modifiers
1251        (ins Src0RC:$src0)
1252      /* endif */ ),
1253    !if (!eq(NumSrcArgs, 2),
1254      !if (!eq(HasModifiers, 1),
1255        // VOP 2 with modifiers
1256        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1257             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1258             ClampMod:$clamp, omod:$omod)
1259      /* else */,
1260        // VOP2 without modifiers
1261        (ins Src0RC:$src0, Src1RC:$src1)
1262      /* endif */ )
1263    /* NumSrcArgs == 3 */,
1264      !if (!eq(HasModifiers, 1),
1265        // VOP3 with modifiers
1266        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1267             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1268             InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
1269             ClampMod:$clamp, omod:$omod)
1270      /* else */,
1271        // VOP3 without modifiers
1272        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1273      /* endif */ ))));
1274}
1275
1276class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1277                                                             bit HasModifiers> {
1278
1279  dag ret = !if (!eq(NumSrcArgs, 1),
1280              !if (!eq(HasModifiers, 1),
1281                // VOP1_DPP with modifiers
1282                (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1283                     i32imm:$dpp_ctrl, i1imm:$bound_ctrl,
1284                     i32imm:$bank_mask, i32imm:$row_mask)
1285              /* else */,
1286                // VOP1_DPP without modifiers
1287                (ins Src0RC:$src0, i32imm:$dpp_ctrl, i1imm:$bound_ctrl,
1288                     i32imm:$bank_mask, i32imm:$row_mask)
1289              /* endif */)
1290            /* NumSrcArgs == 2 */,
1291              !if (!eq(HasModifiers, 1),
1292                // VOP2_DPP with modifiers
1293                (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
1294                     InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
1295                     i32imm:$dpp_ctrl, i1imm:$bound_ctrl,
1296                     i32imm:$bank_mask, i32imm:$row_mask)
1297              /* else */,
1298                // VOP2_DPP without modifiers
1299                (ins Src0RC:$src0, Src1RC:$src1, i32imm:$dpp_ctrl, i1imm:$bound_ctrl,
1300                     i32imm:$bank_mask, i32imm:$row_mask)
1301             /* endif */));
1302}
1303
1304// Returns the assembly string for the inputs and outputs of a VOP[12C]
1305// instruction.  This does not add the _e32 suffix, so it can be reused
1306// by getAsm64.
1307class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1308  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1309  string src0 = ", $src0";
1310  string src1 = ", $src1";
1311  string src2 = ", $src2";
1312  string ret = !if(HasDst, dst, "") #
1313               !if(!eq(NumSrcArgs, 1), src0, "") #
1314               !if(!eq(NumSrcArgs, 2), src0#src1, "") #
1315               !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
1316}
1317
1318// Returns the assembly string for the inputs and outputs of a VOP3
1319// instruction.
1320class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1321  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1322  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1323  string src1 = !if(!eq(NumSrcArgs, 1), "",
1324                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1325                                           " $src1_modifiers,"));
1326  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1327  string ret =
1328  !if(!eq(HasModifiers, 0),
1329      getAsm32<HasDst, NumSrcArgs, DstVT>.ret,
1330      dst#", "#src0#src1#src2#"$clamp"#"$omod");
1331}
1332
1333class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1334  string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1335  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1336  string src1 = !if(!eq(NumSrcArgs, 1), "",
1337                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1338                                           " $src1_modifiers,"));
1339  string args = !if(!eq(HasModifiers, 0),
1340                     getAsm32<0, NumSrcArgs, DstVT>.ret,
1341                     src0#src1);
1342  string ret = " "#dst#args#", $dpp_ctrl, "#"$bound_ctrl, "#"$bank_mask, "#"$row_mask";
1343}
1344
1345class VOPProfile <list<ValueType> _ArgVT> {
1346
1347  field list<ValueType> ArgVT = _ArgVT;
1348
1349  field ValueType DstVT = ArgVT[0];
1350  field ValueType Src0VT = ArgVT[1];
1351  field ValueType Src1VT = ArgVT[2];
1352  field ValueType Src2VT = ArgVT[3];
1353  field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1354  field RegisterClass DstRCDPP = !if(!eq(DstVT.Size, 64), VReg_64, VGPR_32);
1355  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1356  field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
1357  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1358  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1359  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1360  field RegisterClass Src0DPP = getDPPSrcForVT<Src0VT>.ret;
1361  field RegisterClass Src1DPP = getDPPSrcForVT<Src1VT>.ret;
1362
1363  field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
1364  field bit HasDst32 = HasDst;
1365  field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
1366  field bit HasModifiers = hasModifiers<Src0VT>.ret;
1367
1368  field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
1369
1370  // VOP3b instructions are a special case with a second explicit
1371  // output. This is manually overridden for them.
1372  field dag Outs32 = Outs;
1373  field dag Outs64 = Outs;
1374  field dag OutsDPP = !if(!eq(DstVT.Size, 1), (outs DstRCDPP:$sdst), // sdst for VOPC
1375                                              (outs DstRCDPP:$vdst));
1376
1377  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1378  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1379                             HasModifiers>.ret;
1380  field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs, HasModifiers>.ret;
1381
1382  field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
1383  field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1384  field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1385}
1386
1387// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
1388//        for the instruction patterns to work.
1389def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1390def VOP_F16_I16 : VOPProfile <[f16, i32, untyped, untyped]>;
1391def VOP_I16_F16 : VOPProfile <[i32, f16, untyped, untyped]>;
1392
1393def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1394def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
1395def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
1396
1397def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
1398
1399def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1400def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1401def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1402def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1403def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1404def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1405def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1406def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1407def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1408
1409def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1410def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1411def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1412def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1413def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1414def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1415def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1416
1417// Write out to vcc or arbitrary SGPR.
1418def VOP2b_I32_I1_I32_I32 : VOPProfile<[i32, i32, i32, untyped]> {
1419  let Asm32 = "$vdst, vcc, $src0, $src1";
1420  let Asm64 = "$vdst, $sdst, $src0, $src1";
1421  let Outs32 = (outs DstRC:$vdst);
1422  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1423}
1424
1425// Write out to vcc or arbitrary SGPR and read in from vcc or
1426// arbitrary SGPR.
1427def VOP2b_I32_I1_I32_I32_I1 : VOPProfile<[i32, i32, i32, i1]> {
1428  // We use VCSrc_32 to exclude literal constants, even though the
1429  // encoding normally allows them since the implicit VCC use means
1430  // using one would always violate the constant bus
1431  // restriction. SGPRs are still allowed because it should
1432  // technically be possible to use VCC again as src0.
1433  let Src0RC32 = VCSrc_32;
1434  let Asm32 = "$vdst, vcc, $src0, $src1, vcc";
1435  let Asm64 = "$vdst, $sdst, $src0, $src1, $src2";
1436  let Outs32 = (outs DstRC:$vdst);
1437  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1438
1439  // Suppress src2 implied by type since the 32-bit encoding uses an
1440  // implicit VCC use.
1441  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1442}
1443
1444class VOP3b_Profile<ValueType vt> : VOPProfile<[vt, vt, vt, vt]> {
1445  let Outs64 = (outs DstRC:$vdst, SReg_64:$sdst);
1446  let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod";
1447}
1448
1449def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile<f32> {
1450  // FIXME: Hack to stop printing _e64
1451  let DstRC = RegisterOperand<VGPR_32>;
1452}
1453
1454def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile<f64> {
1455  // FIXME: Hack to stop printing _e64
1456  let DstRC = RegisterOperand<VReg_64>;
1457}
1458
1459// VOPC instructions are a special case because for the 32-bit
1460// encoding, we want to display the implicit vcc write as if it were
1461// an explicit $dst.
1462class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, vt1, untyped]> {
1463  let Asm32 = "vcc, $src0, $src1";
1464  // The destination for 32-bit encoding is implicit.
1465  let HasDst32 = 0;
1466  let Outs64 = (outs DstRC:$sdst);
1467}
1468
1469class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
1470  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
1471  let Asm64 = "$sdst, $src0_modifiers, $src1";
1472}
1473
1474def VOPC_I1_F32_F32 : VOPC_Profile<f32>;
1475def VOPC_I1_F64_F64 : VOPC_Profile<f64>;
1476def VOPC_I1_I32_I32 : VOPC_Profile<i32>;
1477def VOPC_I1_I64_I64 : VOPC_Profile<i64>;
1478
1479def VOPC_I1_F32_I32 : VOPC_Class_Profile<f32>;
1480def VOPC_I1_F64_I32 : VOPC_Class_Profile<f64>;
1481
1482def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1483def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1484def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1485def VOP_CNDMASK : VOPProfile <[i32, i32, i32, untyped]> {
1486  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1);
1487  let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, SSrc_64:$src2);
1488  let Asm64 = "$vdst, $src0, $src1, $src2";
1489}
1490
1491def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1492def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> {
1493  field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2);
1494  field string Asm = "$vdst, $src0, $vsrc1, $src2";
1495}
1496def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
1497  let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
1498  let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
1499                             HasModifiers>.ret;
1500  let Asm32 = getAsm32<1, 2, f32>.ret;
1501  let Asm64 = getAsm64<1, 2, HasModifiers, f32>.ret;
1502}
1503def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1504def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1505def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1506
1507// This class is used only with VOPC instructions. Use $sdst for out operand
1508class SIInstAlias <string asm, Instruction inst, VOPProfile p> :
1509    InstAlias <asm, (inst)>, PredicateControl {
1510
1511  field bit isCompare;
1512  field bit isCommutable;
1513
1514  let ResultInst =
1515    !if (p.HasDst32,
1516      !if (!eq(p.NumSrcArgs, 0),
1517        // 1 dst, 0 src
1518        (inst p.DstRC:$sdst),
1519      !if (!eq(p.NumSrcArgs, 1),
1520        // 1 dst, 1 src
1521        (inst p.DstRC:$sdst, p.Src0RC32:$src0),
1522      !if (!eq(p.NumSrcArgs, 2),
1523        // 1 dst, 2 src
1524        (inst p.DstRC:$sdst, p.Src0RC32:$src0, p.Src1RC32:$src1),
1525      // else - unreachable
1526        (inst)))),
1527    // else
1528      !if (!eq(p.NumSrcArgs, 2),
1529        // 0 dst, 2 src
1530        (inst p.Src0RC32:$src0, p.Src1RC32:$src1),
1531      !if (!eq(p.NumSrcArgs, 1),
1532        // 0 dst, 1 src
1533        (inst p.Src0RC32:$src1),
1534      // else
1535        // 0 dst, 0 src
1536        (inst))));
1537}
1538
1539class SIInstAliasSI <string asm, string op_name, VOPProfile p> :
1540  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_si"), p> {
1541  let AssemblerPredicate = SIAssemblerPredicate;
1542}
1543
1544class SIInstAliasVI <string asm, string op_name, VOPProfile p> :
1545  SIInstAlias <asm, !cast<Instruction>(op_name#"_e32_vi"), p> {
1546  let AssemblerPredicates = [isVI];
1547}
1548
1549multiclass SIInstAliasBuilder <string asm, VOPProfile p> {
1550
1551  def : SIInstAliasSI <asm, NAME, p>;
1552
1553  def : SIInstAliasVI <asm, NAME, p>;
1554}
1555
1556class VOP <string opName> {
1557  string OpName = opName;
1558}
1559
1560class VOP2_REV <string revOp, bit isOrig> {
1561  string RevOp = revOp;
1562  bit IsOrig = isOrig;
1563}
1564
1565class AtomicNoRet <string noRetOp, bit isRet> {
1566  string NoRetOp = noRetOp;
1567  bit IsRet = isRet;
1568}
1569
1570class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1571  VOP1Common <outs, ins, "", pattern>,
1572  VOP <opName>,
1573  SIMCInstr <opName#"_e32", SISubtarget.NONE>,
1574  MnemonicAlias<opName#"_e32", opName> {
1575  let isPseudo = 1;
1576  let isCodeGenOnly = 1;
1577
1578  field bits<8> vdst;
1579  field bits<9> src0;
1580}
1581
1582class VOP1_Real_si <string opName, vop1 op, dag outs, dag ins, string asm> :
1583  VOP1<op.SI, outs, ins, asm, []>,
1584  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1585  let AssemblerPredicate = SIAssemblerPredicate;
1586  let DecoderNamespace = "SICI";
1587  let DisableDecoder = DisableSIDecoder;
1588}
1589
1590class VOP1_Real_vi <string opName, vop1 op, dag outs, dag ins, string asm> :
1591  VOP1<op.VI, outs, ins, asm, []>,
1592  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1593  let AssemblerPredicates = [isVI];
1594  let DecoderNamespace = "VI";
1595  let DisableDecoder = DisableVIDecoder;
1596}
1597
1598multiclass VOP1_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1599                   string asm = opName#p.Asm32> {
1600  def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1601
1602  def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1603
1604  def _vi : VOP1_Real_vi <opName, op, p.Outs, p.Ins32, asm>;
1605
1606}
1607
1608class VOP1_DPP <vop1 op, string opName, VOPProfile p> :
1609  VOP1_DPPe <op.VI>,
1610  VOP_DPP <p.OutsDPP, p.InsDPP, opName#p.AsmDPP, []> {
1611  let AssemblerPredicates = [isVI];
1612  let src0_modifiers =  !if(p.HasModifiers, ?, 0);
1613  let src1_modifiers = 0;
1614}
1615
1616multiclass VOP1SI_m <vop1 op, string opName, VOPProfile p, list<dag> pattern,
1617                     string asm = opName#p.Asm32> {
1618
1619  def "" : VOP1_Pseudo <p.Outs, p.Ins32, pattern, opName>;
1620
1621  def _si : VOP1_Real_si <opName, op, p.Outs, p.Ins32, asm>;
1622}
1623
1624class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1625  VOP2Common <outs, ins, "", pattern>,
1626  VOP <opName>,
1627  SIMCInstr<opName#"_e32", SISubtarget.NONE>,
1628  MnemonicAlias<opName#"_e32", opName> {
1629  let isPseudo = 1;
1630  let isCodeGenOnly = 1;
1631}
1632
1633class VOP2_Real_si <string opName, vop2 op, dag outs, dag ins, string asm> :
1634  VOP2 <op.SI, outs, ins, opName#asm, []>,
1635  SIMCInstr <opName#"_e32", SISubtarget.SI> {
1636  let AssemblerPredicates = [isSICI];
1637  let DecoderNamespace = "SICI";
1638  let DisableDecoder = DisableSIDecoder;
1639}
1640
1641class VOP2_Real_vi <string opName, vop2 op, dag outs, dag ins, string asm> :
1642  VOP2 <op.VI, outs, ins, opName#asm, []>,
1643  SIMCInstr <opName#"_e32", SISubtarget.VI> {
1644  let AssemblerPredicates = [isVI];
1645  let DecoderNamespace = "VI";
1646  let DisableDecoder = DisableVIDecoder;
1647}
1648
1649multiclass VOP2SI_m <vop2 op, string opName, VOPProfile p, list<dag> pattern,
1650                     string revOp> {
1651
1652  def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1653           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1654
1655  def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1656}
1657
1658multiclass VOP2_m <vop2 op, string opName, VOPProfile p, list <dag> pattern,
1659                   string revOp> {
1660
1661  def "" : VOP2_Pseudo <p.Outs32, p.Ins32, pattern, opName>,
1662           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
1663
1664  def _si : VOP2_Real_si <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1665
1666  def _vi : VOP2_Real_vi <opName, op, p.Outs32, p.Ins32, p.Asm32>;
1667
1668}
1669
1670class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
1671
1672  bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
1673  bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
1674  bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ?, 0), 0);
1675  bits<2> omod = !if(HasModifiers, ?, 0);
1676  bits<1> clamp = !if(HasModifiers, ?, 0);
1677  bits<9> src1 = !if(HasSrc1, ?, 0);
1678  bits<9> src2 = !if(HasSrc2, ?, 0);
1679}
1680
1681class VOP3DisableModFields <bit HasSrc0Mods,
1682                            bit HasSrc1Mods = 0,
1683                            bit HasSrc2Mods = 0,
1684                            bit HasOutputMods = 0> {
1685  bits<2> src0_modifiers = !if(HasSrc0Mods, ?, 0);
1686  bits<2> src1_modifiers = !if(HasSrc1Mods, ?, 0);
1687  bits<2> src2_modifiers = !if(HasSrc2Mods, ?, 0);
1688  bits<2> omod = !if(HasOutputMods, ?, 0);
1689  bits<1> clamp = !if(HasOutputMods, ?, 0);
1690}
1691
1692class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName,
1693                   bit HasMods = 0, bit VOP3Only = 0> :
1694  VOP3Common <outs, ins, "", pattern, HasMods, VOP3Only>,
1695  VOP <opName>,
1696  SIMCInstr<opName#"_e64", SISubtarget.NONE>,
1697  MnemonicAlias<opName#"_e64", opName> {
1698  let isPseudo = 1;
1699  let isCodeGenOnly = 1;
1700
1701  field bit vdst;
1702  field bit src0;
1703}
1704
1705class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1706                    bit HasMods = 0, bit VOP3Only = 0> :
1707  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1708  VOP3e <op>,
1709  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1710  let AssemblerPredicates = [isSICI];
1711  let DecoderNamespace = "SICI";
1712  let DisableDecoder = DisableSIDecoder;
1713}
1714
1715class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1716                    bit HasMods = 0, bit VOP3Only = 0> :
1717  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1718  VOP3e_vi <op>,
1719  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1720  let AssemblerPredicates = [isVI];
1721  let DecoderNamespace = "VI";
1722  let DisableDecoder = DisableVIDecoder;
1723}
1724
1725class VOP3_C_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1726                     bit HasMods = 0, bit VOP3Only = 0> :
1727  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1728  VOP3ce <op>,
1729  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1730  let AssemblerPredicates = [isSICI];
1731  let DecoderNamespace = "SICI";
1732  let DisableDecoder = DisableSIDecoder;
1733}
1734
1735class VOP3_C_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1736                      bit HasMods = 0, bit VOP3Only = 0> :
1737  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1738  VOP3ce_vi <op>,
1739  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1740  let AssemblerPredicates = [isVI];
1741  let DecoderNamespace = "VI";
1742  let DisableDecoder = DisableVIDecoder;
1743}
1744
1745class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName,
1746                     bit HasMods = 0, bit VOP3Only = 0> :
1747  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1748  VOP3be <op>,
1749  SIMCInstr<opName#"_e64", SISubtarget.SI> {
1750  let AssemblerPredicates = [isSICI];
1751  let DecoderNamespace = "SICI";
1752  let DisableDecoder = DisableSIDecoder;
1753}
1754
1755class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName,
1756                     bit HasMods = 0, bit VOP3Only = 0> :
1757  VOP3Common <outs, ins, asm, [], HasMods, VOP3Only>,
1758  VOP3be_vi <op>,
1759  SIMCInstr <opName#"_e64", SISubtarget.VI> {
1760  let AssemblerPredicates = [isVI];
1761  let DecoderNamespace = "VI";
1762  let DisableDecoder = DisableVIDecoder;
1763}
1764
1765multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
1766                   string opName, int NumSrcArgs, bit HasMods = 1, bit VOP3Only = 0> {
1767
1768  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1769
1770  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1771            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1772                              !if(!eq(NumSrcArgs, 2), 0, 1),
1773                              HasMods>;
1774  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1775            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
1776                              !if(!eq(NumSrcArgs, 2), 0, 1),
1777                              HasMods>;
1778}
1779
1780multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
1781                     list<dag> pattern, string opName, bit HasMods = 1> {
1782
1783  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1784
1785  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1786            VOP3DisableFields<0, 0, HasMods>;
1787
1788  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1789            VOP3DisableFields<0, 0, HasMods>;
1790}
1791
1792multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
1793                     list<dag> pattern, string opName, bit HasMods = 1> {
1794
1795  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>;
1796
1797  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1798            VOP3DisableFields<0, 0, HasMods>;
1799  // No VI instruction. This class is for SI only.
1800}
1801
1802multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
1803                     list<dag> pattern, string opName, string revOp,
1804                     bit HasMods = 1> {
1805
1806  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1807           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1808
1809  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1810            VOP3DisableFields<1, 0, HasMods>;
1811
1812  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1813            VOP3DisableFields<1, 0, HasMods>;
1814}
1815
1816multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
1817                     list<dag> pattern, string opName, string revOp,
1818                     bit HasMods = 1> {
1819
1820  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1821           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1822
1823  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1824            VOP3DisableFields<1, 0, HasMods>;
1825
1826  // No VI instruction. This class is for SI only.
1827}
1828
1829// Two operand VOP3b instruction that may have a 3rd SGPR bool operand
1830// instead of an implicit VCC as in the VOP2b format.
1831multiclass VOP3b_2_3_m <vop op, dag outs, dag ins, string asm,
1832                        list<dag> pattern, string opName, string revOp,
1833                        bit HasMods = 1, bit useSrc2Input = 0, bit VOP3Only = 0> {
1834  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods, VOP3Only>;
1835
1836  def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1837            VOP3DisableFields<1, useSrc2Input, HasMods>;
1838
1839  def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName, HasMods, VOP3Only>,
1840            VOP3DisableFields<1, useSrc2Input, HasMods>;
1841}
1842
1843multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1844                     list<dag> pattern, string opName,
1845                     bit HasMods, bit defExec,
1846                     string revOp, list<SchedReadWrite> sched> {
1847
1848  def "" : VOP3_Pseudo <outs, ins, pattern, opName, HasMods>,
1849           VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
1850    let Defs = !if(defExec, [EXEC], []);
1851    let SchedRW = sched;
1852  }
1853
1854  def _si : VOP3_C_Real_si <op.SI3, outs, ins, asm, opName, HasMods>,
1855            VOP3DisableFields<1, 0, HasMods> {
1856    let Defs = !if(defExec, [EXEC], []);
1857    let SchedRW = sched;
1858  }
1859
1860  def _vi : VOP3_C_Real_vi <op.VI3, outs, ins, asm, opName, HasMods>,
1861            VOP3DisableFields<1, 0, HasMods> {
1862    let Defs = !if(defExec, [EXEC], []);
1863    let SchedRW = sched;
1864  }
1865}
1866
1867// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1868multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1869                         string asm, list<dag> pattern = []> {
1870  let isPseudo = 1, isCodeGenOnly = 1 in {
1871    def "" : VOPAnyCommon <outs, ins, "", pattern>,
1872             SIMCInstr<opName, SISubtarget.NONE>;
1873  }
1874
1875  def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1876            SIMCInstr <opName, SISubtarget.SI> {
1877            let AssemblerPredicates = [isSICI];
1878            let DecoderNamespace = "SICI";
1879            let DisableDecoder = DisableSIDecoder;
1880  }
1881
1882  def _vi : VOP3Common <outs, ins, asm, []>,
1883            VOP3e_vi <op.VI3>,
1884            VOP3DisableFields <1, 0, 0>,
1885            SIMCInstr <opName, SISubtarget.VI> {
1886            let AssemblerPredicates = [isVI];
1887            let DecoderNamespace = "VI";
1888            let DisableDecoder = DisableVIDecoder;
1889  }
1890}
1891
1892multiclass VOP1_Helper <vop1 op, string opName, VOPProfile p, list<dag> pat32,
1893                        list<dag> pat64> {
1894
1895  defm _e32 : VOP1_m <op, opName, p, pat32>;
1896
1897  defm _e64 : VOP3_1_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
1898                        p.HasModifiers>;
1899
1900  def _dpp : VOP1_DPP <op, opName, p>;
1901}
1902
1903multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1904                     SDPatternOperator node = null_frag> : VOP1_Helper <
1905  op, opName, P, [],
1906  !if(P.HasModifiers,
1907      [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1908                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1909      [(set P.DstVT:$vdst, (node P.Src0VT:$src0))])
1910>;
1911
1912multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1913                       SDPatternOperator node = null_frag> {
1914
1915  defm _e32 : VOP1SI_m <op, opName, P, []>;
1916
1917  defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1918    !if(P.HasModifiers,
1919      [(set P.DstVT:$vdst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1920                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1921      [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]),
1922    opName, P.HasModifiers>;
1923}
1924
1925multiclass VOP2_Helper <vop2 op, string opName, VOPProfile p, list<dag> pat32,
1926                        list<dag> pat64, string revOp> {
1927
1928  defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
1929
1930  defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
1931                        revOp, p.HasModifiers>;
1932}
1933
1934multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1935                     SDPatternOperator node = null_frag,
1936                     string revOp = opName> : VOP2_Helper <
1937  op, opName, P, [],
1938  !if(P.HasModifiers,
1939      [(set P.DstVT:$vdst,
1940           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1941                                      i1:$clamp, i32:$omod)),
1942                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1943      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1944  revOp
1945>;
1946
1947multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1948                       SDPatternOperator node = null_frag,
1949                       string revOp = opName> {
1950
1951  defm _e32 : VOP2SI_m <op, opName, P, [], revOp>;
1952
1953  defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1954    !if(P.HasModifiers,
1955        [(set P.DstVT:$vdst,
1956             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1957                                        i1:$clamp, i32:$omod)),
1958                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1959        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1960    opName, revOp, P.HasModifiers>;
1961}
1962
1963multiclass VOP2b_Helper <vop2 op, string opName, VOPProfile p,
1964                         list<dag> pat32, list<dag> pat64,
1965                         string revOp, bit useSGPRInput> {
1966
1967  let SchedRW = [Write32Bit, WriteSALU] in {
1968    let Uses = !if(useSGPRInput, [VCC, EXEC], [EXEC]), Defs = [VCC] in {
1969      defm _e32 : VOP2_m <op, opName, p, pat32, revOp>;
1970    }
1971
1972    defm _e64 : VOP3b_2_3_m <op, p.Outs64, p.Ins64, opName#p.Asm64, pat64,
1973                             opName, revOp, p.HasModifiers, useSGPRInput>;
1974  }
1975}
1976
1977multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1978                      SDPatternOperator node = null_frag,
1979                      string revOp = opName> : VOP2b_Helper <
1980  op, opName, P, [],
1981  !if(P.HasModifiers,
1982      [(set P.DstVT:$vdst,
1983           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1984                                      i1:$clamp, i32:$omod)),
1985                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1986      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1987  revOp, !eq(P.NumSrcArgs, 3)
1988>;
1989
1990// A VOP2 instruction that is VOP3-only on VI.
1991multiclass VOP2_VI3_Helper <vop23 op, string opName, VOPProfile p,
1992                            list<dag> pat32, list<dag> pat64, string revOp> {
1993
1994  defm _e32 : VOP2SI_m <op, opName, p, pat32, revOp>;
1995
1996  defm _e64 : VOP3_2_m <op, p.Outs, p.Ins64, opName#p.Asm64, pat64, opName,
1997                        revOp, p.HasModifiers>;
1998}
1999
2000multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
2001                          SDPatternOperator node = null_frag,
2002                          string revOp = opName>
2003                          : VOP2_VI3_Helper <
2004  op, opName, P, [],
2005  !if(P.HasModifiers,
2006      [(set P.DstVT:$vdst,
2007           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2008                                      i1:$clamp, i32:$omod)),
2009                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2010      [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
2011  revOp
2012>;
2013
2014multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
2015
2016  def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
2017
2018let isCodeGenOnly = 0 in {
2019  def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
2020                        !strconcat(opName, VOP_MADK.Asm), []>,
2021            SIMCInstr <opName#"_e32", SISubtarget.SI>,
2022            VOP2_MADKe <op.SI> {
2023            let AssemblerPredicates = [isSICI];
2024            let DecoderNamespace = "SICI";
2025            let DisableDecoder = DisableSIDecoder;
2026            }
2027
2028  def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
2029                        !strconcat(opName, VOP_MADK.Asm), []>,
2030            SIMCInstr <opName#"_e32", SISubtarget.VI>,
2031            VOP2_MADKe <op.VI> {
2032            let AssemblerPredicates = [isVI];
2033            let DecoderNamespace = "VI";
2034            let DisableDecoder = DisableVIDecoder;
2035            }
2036} // End isCodeGenOnly = 0
2037}
2038
2039class VOPC_Pseudo <dag ins, list<dag> pattern, string opName> :
2040  VOPCCommon <ins, "", pattern>,
2041  VOP <opName>,
2042  SIMCInstr<opName#"_e32", SISubtarget.NONE> {
2043  let isPseudo = 1;
2044  let isCodeGenOnly = 1;
2045}
2046
2047multiclass VOPC_m <vopc op, dag ins, string op_asm, list<dag> pattern,
2048                   string opName, bit DefExec, VOPProfile p,
2049                   list<SchedReadWrite> sched,
2050                   string revOpName = "", string asm = opName#"_e32 "#op_asm,
2051                   string alias_asm = opName#" "#op_asm> {
2052  def "" : VOPC_Pseudo <ins, pattern, opName>,
2053           VOP2_REV<revOpName#"_e32", !eq(revOpName, opName)> {
2054    let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2055    let SchedRW = sched;
2056  }
2057
2058  let AssemblerPredicates = [isSICI] in {
2059    def _si : VOPC<op.SI, ins, asm, []>,
2060              SIMCInstr <opName#"_e32", SISubtarget.SI> {
2061      let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2062      let hasSideEffects = DefExec;
2063      let SchedRW = sched;
2064      let DecoderNamespace = "SICI";
2065      let DisableDecoder = DisableSIDecoder;
2066    }
2067
2068  } // End AssemblerPredicates = [isSICI]
2069
2070  let AssemblerPredicates = [isVI] in {
2071    def _vi : VOPC<op.VI, ins, asm, []>,
2072              SIMCInstr <opName#"_e32", SISubtarget.VI> {
2073      let Defs = !if(DefExec, [VCC, EXEC], [VCC]);
2074      let hasSideEffects = DefExec;
2075      let SchedRW = sched;
2076      let DecoderNamespace = "VI";
2077      let DisableDecoder = DisableVIDecoder;
2078    }
2079
2080  } // End AssemblerPredicates = [isVI]
2081
2082  defm : SIInstAliasBuilder<alias_asm, p>;
2083}
2084
2085multiclass VOPC_Helper <vopc op, string opName, list<dag> pat32,
2086                        list<dag> pat64, bit DefExec, string revOp,
2087                        VOPProfile p, list<SchedReadWrite> sched> {
2088  defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched,
2089                      revOp>;
2090
2091  defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2092                        opName, p.HasModifiers, DefExec, revOp, sched>;
2093}
2094
2095// Special case for class instructions which only have modifiers on
2096// the 1st source operand.
2097multiclass VOPC_Class_Helper <vopc op, string opName, list<dag> pat32,
2098                              list<dag> pat64, bit DefExec, string revOp,
2099                              VOPProfile p, list<SchedReadWrite> sched> {
2100  defm _e32 : VOPC_m <op, p.Ins32, p.Asm32, pat32, opName, DefExec, p, sched>;
2101
2102  defm _e64 : VOP3_C_m <op, (outs VOPDstS64:$sdst), p.Ins64, opName#p.Asm64, pat64,
2103                        opName, p.HasModifiers, DefExec, revOp, sched>,
2104                        VOP3DisableModFields<1, 0, 0>;
2105}
2106
2107multiclass VOPCInst <vopc op, string opName,
2108                     VOPProfile P, PatLeaf cond = COND_NULL,
2109                     string revOp = opName,
2110                     bit DefExec = 0,
2111                     list<SchedReadWrite> sched = [Write32Bit]> :
2112                     VOPC_Helper <
2113  op, opName, [],
2114  !if(P.HasModifiers,
2115      [(set i1:$sdst,
2116          (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2117                                      i1:$clamp, i32:$omod)),
2118                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2119                 cond))],
2120      [(set i1:$sdst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
2121  DefExec, revOp, P, sched
2122>;
2123
2124multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
2125                     bit DefExec = 0,
2126                     list<SchedReadWrite> sched> : VOPC_Class_Helper <
2127  op, opName, [],
2128  !if(P.HasModifiers,
2129      [(set i1:$sdst,
2130          (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
2131      [(set i1:$sdst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
2132  DefExec, opName, P, sched
2133>;
2134
2135
2136multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2137  VOPCInst <op, opName, VOPC_I1_F32_F32, cond, revOp>;
2138
2139multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2140  VOPCInst <op, opName, VOPC_I1_F64_F64, cond, revOp, 0, [WriteDoubleAdd]>;
2141
2142multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2143  VOPCInst <op, opName, VOPC_I1_I32_I32, cond, revOp>;
2144
2145multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL, string revOp = opName> :
2146  VOPCInst <op, opName, VOPC_I1_I64_I64, cond, revOp, 0, [Write64Bit]>;
2147
2148
2149multiclass VOPCX <vopc op, string opName, VOPProfile P,
2150                  PatLeaf cond = COND_NULL,
2151                  list<SchedReadWrite> sched,
2152                  string revOp = "">
2153  : VOPCInst <op, opName, P, cond, revOp, 1, sched>;
2154
2155multiclass VOPCX_F32 <vopc op, string opName, string revOp = opName> :
2156  VOPCX <op, opName, VOPC_I1_F32_F32, COND_NULL, [Write32Bit], revOp>;
2157
2158multiclass VOPCX_F64 <vopc op, string opName, string revOp = opName> :
2159  VOPCX <op, opName, VOPC_I1_F64_F64, COND_NULL, [WriteDoubleAdd], revOp>;
2160
2161multiclass VOPCX_I32 <vopc op, string opName, string revOp = opName> :
2162  VOPCX <op, opName, VOPC_I1_I32_I32, COND_NULL, [Write32Bit], revOp>;
2163
2164multiclass VOPCX_I64 <vopc op, string opName, string revOp = opName> :
2165  VOPCX <op, opName, VOPC_I1_I64_I64, COND_NULL, [Write64Bit], revOp>;
2166
2167multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
2168                        list<dag> pat, int NumSrcArgs, bit HasMods,
2169                        bit VOP3Only = 0> : VOP3_m <
2170    op, outs, ins, opName#" "#asm, pat, opName, NumSrcArgs, HasMods, VOP3Only
2171>;
2172
2173multiclass VOPC_CLASS_F32 <vopc op, string opName> :
2174  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 0, [Write32Bit]>;
2175
2176multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
2177  VOPCClassInst <op, opName, VOPC_I1_F32_I32, 1, [Write32Bit]>;
2178
2179multiclass VOPC_CLASS_F64 <vopc op, string opName> :
2180  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 0, [WriteDoubleAdd]>;
2181
2182multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
2183  VOPCClassInst <op, opName, VOPC_I1_F64_I32, 1, [WriteDoubleAdd]>;
2184
2185multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
2186                     SDPatternOperator node = null_frag, bit VOP3Only = 0> :
2187  VOP3_Helper <
2188  op, opName, (outs P.DstRC.RegClass:$vdst), P.Ins64, P.Asm64,
2189  !if(!eq(P.NumSrcArgs, 3),
2190    !if(P.HasModifiers,
2191        [(set P.DstVT:$vdst,
2192            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2193                                       i1:$clamp, i32:$omod)),
2194                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2195                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
2196        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1,
2197                                  P.Src2VT:$src2))]),
2198  !if(!eq(P.NumSrcArgs, 2),
2199    !if(P.HasModifiers,
2200        [(set P.DstVT:$vdst,
2201            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2202                                       i1:$clamp, i32:$omod)),
2203                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
2204        [(set P.DstVT:$vdst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
2205  /* P.NumSrcArgs == 1 */,
2206    !if(P.HasModifiers,
2207        [(set P.DstVT:$vdst,
2208            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2209                                       i1:$clamp, i32:$omod))))],
2210        [(set P.DstVT:$vdst, (node P.Src0VT:$src0))]))),
2211  P.NumSrcArgs, P.HasModifiers, VOP3Only
2212>;
2213
2214// Special case for v_div_fmas_{f32|f64}, since it seems to be the
2215// only VOP instruction that implicitly reads VCC.
2216multiclass VOP3_VCC_Inst <vop3 op, string opName,
2217                          VOPProfile P,
2218                          SDPatternOperator node = null_frag> : VOP3_Helper <
2219  op, opName,
2220  (outs P.DstRC.RegClass:$vdst),
2221  (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
2222       InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
2223       InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
2224       ClampMod:$clamp,
2225       omod:$omod),
2226  "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
2227  [(set P.DstVT:$vdst,
2228            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
2229                                       i1:$clamp, i32:$omod)),
2230                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2231                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
2232                  (i1 VCC)))],
2233  3, 1
2234>;
2235
2236multiclass VOP3bInst <vop op, string opName, VOPProfile P, list<dag> pattern = [], bit VOP3Only = 0> :
2237  VOP3b_2_3_m <
2238  op, P.Outs64, P.Ins64,
2239  opName#" "#P.Asm64, pattern,
2240  opName, "", 1, 1, VOP3Only
2241>;
2242
2243class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
2244  (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
2245        (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
2246        (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
2247  (Inst i32:$src0_modifiers, P.Src0VT:$src0,
2248        i32:$src1_modifiers, P.Src1VT:$src1,
2249        i32:$src2_modifiers, P.Src2VT:$src2,
2250        i1:$clamp,
2251        i32:$omod)>;
2252
2253//===----------------------------------------------------------------------===//
2254// Interpolation opcodes
2255//===----------------------------------------------------------------------===//
2256
2257class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2258  VINTRPCommon <outs, ins, "", pattern>,
2259  SIMCInstr<opName, SISubtarget.NONE> {
2260  let isPseudo = 1;
2261  let isCodeGenOnly = 1;
2262}
2263
2264class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
2265                      string asm> :
2266  VINTRPCommon <outs, ins, asm, []>,
2267  VINTRPe <op>,
2268  SIMCInstr<opName, SISubtarget.SI> {
2269  let DecoderNamespace = "SICI";
2270  let DisableDecoder = DisableSIDecoder;
2271}
2272
2273class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
2274                      string asm> :
2275  VINTRPCommon <outs, ins, asm, []>,
2276  VINTRPe_vi <op>,
2277  SIMCInstr<opName, SISubtarget.VI> {
2278  let DecoderNamespace = "VI";
2279  let DisableDecoder = DisableVIDecoder;
2280}
2281
2282multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
2283                     list<dag> pattern = []> {
2284  def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
2285
2286  def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
2287
2288  def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
2289}
2290
2291//===----------------------------------------------------------------------===//
2292// Vector I/O classes
2293//===----------------------------------------------------------------------===//
2294
2295class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2296  DS <outs, ins, "", pattern>,
2297  SIMCInstr <opName, SISubtarget.NONE> {
2298  let isPseudo = 1;
2299  let isCodeGenOnly = 1;
2300}
2301
2302class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2303  DS <outs, ins, asm, []>,
2304  DSe <op>,
2305  SIMCInstr <opName, SISubtarget.SI> {
2306  let isCodeGenOnly = 0;
2307  let AssemblerPredicates = [isSICI];
2308  let DecoderNamespace="SICI";
2309  let DisableDecoder = DisableSIDecoder;
2310}
2311
2312class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2313  DS <outs, ins, asm, []>,
2314  DSe_vi <op>,
2315  SIMCInstr <opName, SISubtarget.VI> {
2316  let isCodeGenOnly = 0;
2317  let AssemblerPredicates = [isVI];
2318  let DecoderNamespace="VI";
2319  let DisableDecoder = DisableVIDecoder;
2320}
2321
2322class DS_Off16_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
2323  DS_Real_si <op,opName, outs, ins, asm> {
2324
2325  // Single load interpret the 2 i8imm operands as a single i16 offset.
2326  bits<16> offset;
2327  let offset0 = offset{7-0};
2328  let offset1 = offset{15-8};
2329}
2330
2331class DS_Off16_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
2332  DS_Real_vi <op, opName, outs, ins, asm> {
2333
2334  // Single load interpret the 2 i8imm operands as a single i16 offset.
2335  bits<16> offset;
2336  let offset0 = offset{7-0};
2337  let offset1 = offset{15-8};
2338}
2339
2340multiclass DS_1A_RET <bits<8> op, string opName, RegisterClass rc,
2341  dag outs = (outs rc:$vdst),
2342  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2343  string asm = opName#" $vdst, $addr"#"$offset$gds"> {
2344
2345  def "" : DS_Pseudo <opName, outs, ins, []>;
2346
2347  let data0 = 0, data1 = 0 in {
2348    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2349    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2350  }
2351}
2352
2353multiclass DS_1A_Off8_RET <bits<8> op, string opName, RegisterClass rc,
2354  dag outs = (outs rc:$vdst),
2355  dag ins = (ins VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
2356                 gds01:$gds),
2357  string asm = opName#" $vdst, $addr"#"$offset0"#"$offset1$gds"> {
2358
2359  def "" : DS_Pseudo <opName, outs, ins, []>;
2360
2361  let data0 = 0, data1 = 0, AsmMatchConverter = "cvtDSOffset01" in {
2362    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2363    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2364  }
2365}
2366
2367multiclass DS_1A1D_NORET <bits<8> op, string opName, RegisterClass rc,
2368  dag outs = (outs),
2369  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2370  string asm = opName#" $addr, $data0"#"$offset$gds"> {
2371
2372  def "" : DS_Pseudo <opName, outs, ins, []>,
2373           AtomicNoRet<opName, 0>;
2374
2375  let data1 = 0, vdst = 0 in {
2376    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2377    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2378  }
2379}
2380
2381multiclass DS_1A1D_Off8_NORET <bits<8> op, string opName, RegisterClass rc,
2382  dag outs = (outs),
2383  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2384              ds_offset0:$offset0, ds_offset1:$offset1, gds01:$gds),
2385  string asm = opName#" $addr, $data0, $data1"#"$offset0"#"$offset1"#"$gds"> {
2386
2387  def "" : DS_Pseudo <opName, outs, ins, []>;
2388
2389  let vdst = 0, AsmMatchConverter = "cvtDSOffset01" in {
2390    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2391    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2392  }
2393}
2394
2395multiclass DS_1A1D_RET <bits<8> op, string opName, RegisterClass rc,
2396                        string noRetOp = "",
2397  dag outs = (outs rc:$vdst),
2398  dag ins = (ins VGPR_32:$addr, rc:$data0, ds_offset:$offset, gds:$gds),
2399  string asm = opName#" $vdst, $addr, $data0"#"$offset$gds"> {
2400
2401  let hasPostISelHook = 1 in {
2402    def "" : DS_Pseudo <opName, outs, ins, []>,
2403             AtomicNoRet<noRetOp, 1>;
2404
2405    let data1 = 0 in {
2406      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2407      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2408    }
2409  }
2410}
2411
2412multiclass DS_1A2D_RET_m <bits<8> op, string opName, RegisterClass rc,
2413                          string noRetOp = "", dag ins,
2414  dag outs = (outs rc:$vdst),
2415  string asm = opName#" $vdst, $addr, $data0, $data1"#"$offset"#"$gds"> {
2416
2417  let hasPostISelHook = 1 in {
2418    def "" : DS_Pseudo <opName, outs, ins, []>,
2419             AtomicNoRet<noRetOp, 1>;
2420
2421    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2422    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2423  }
2424}
2425
2426multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
2427                        string noRetOp = "", RegisterClass src = rc> :
2428  DS_1A2D_RET_m <op, asm, rc, noRetOp,
2429                 (ins VGPR_32:$addr, src:$data0, src:$data1,
2430                      ds_offset:$offset, gds:$gds)
2431>;
2432
2433multiclass DS_1A2D_NORET <bits<8> op, string opName, RegisterClass rc,
2434                          string noRetOp = opName,
2435  dag outs = (outs),
2436  dag ins = (ins VGPR_32:$addr, rc:$data0, rc:$data1,
2437                 ds_offset:$offset, gds:$gds),
2438  string asm = opName#" $addr, $data0, $data1"#"$offset"#"$gds"> {
2439
2440  def "" : DS_Pseudo <opName, outs, ins, []>,
2441           AtomicNoRet<noRetOp, 0>;
2442
2443  let vdst = 0 in {
2444    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2445    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2446  }
2447}
2448
2449multiclass DS_0A_RET <bits<8> op, string opName,
2450  dag outs = (outs VGPR_32:$vdst),
2451  dag ins = (ins ds_offset:$offset, gds:$gds),
2452  string asm = opName#" $vdst"#"$offset"#"$gds"> {
2453
2454  let mayLoad = 1, mayStore = 1 in {
2455    def "" : DS_Pseudo <opName, outs, ins, []>;
2456
2457    let addr = 0, data0 = 0, data1 = 0 in {
2458      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2459      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2460    } // end addr = 0, data0 = 0, data1 = 0
2461  } // end mayLoad = 1, mayStore = 1
2462}
2463
2464multiclass DS_1A_RET_GDS <bits<8> op, string opName,
2465  dag outs = (outs VGPR_32:$vdst),
2466  dag ins = (ins VGPR_32:$addr, ds_offset_gds:$offset),
2467  string asm = opName#" $vdst, $addr"#"$offset gds"> {
2468
2469  def "" : DS_Pseudo <opName, outs, ins, []>;
2470
2471  let data0 = 0, data1 = 0, gds = 1 in {
2472    def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2473    def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2474  } // end data0 = 0, data1 = 0, gds = 1
2475}
2476
2477multiclass DS_1A_GDS <bits<8> op, string opName,
2478  dag outs = (outs),
2479  dag ins = (ins VGPR_32:$addr),
2480  string asm = opName#" $addr gds"> {
2481
2482  def "" : DS_Pseudo <opName, outs, ins, []>;
2483
2484  let vdst = 0, data0 = 0, data1 = 0, offset0 = 0, offset1 = 0, gds = 1 in {
2485    def _si : DS_Real_si <op, opName, outs, ins, asm>;
2486    def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
2487  } // end vdst = 0, data = 0, data1 = 0, gds = 1
2488}
2489
2490multiclass DS_1A <bits<8> op, string opName,
2491  dag outs = (outs),
2492  dag ins = (ins VGPR_32:$addr, ds_offset:$offset, gds:$gds),
2493  string asm = opName#" $addr"#"$offset"#"$gds"> {
2494
2495  let mayLoad = 1, mayStore = 1 in {
2496    def "" : DS_Pseudo <opName, outs, ins, []>;
2497
2498    let vdst = 0, data0 = 0, data1 = 0 in {
2499      def _si : DS_Off16_Real_si <op, opName, outs, ins, asm>;
2500      def _vi : DS_Off16_Real_vi <op, opName, outs, ins, asm>;
2501    } // let vdst = 0, data0 = 0, data1 = 0
2502  } // end mayLoad = 1, mayStore = 1
2503}
2504
2505//===----------------------------------------------------------------------===//
2506// MTBUF classes
2507//===----------------------------------------------------------------------===//
2508
2509class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2510  MTBUF <outs, ins, "", pattern>,
2511  SIMCInstr<opName, SISubtarget.NONE> {
2512  let isPseudo = 1;
2513  let isCodeGenOnly = 1;
2514}
2515
2516class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
2517                    string asm> :
2518  MTBUF <outs, ins, asm, []>,
2519  MTBUFe <op>,
2520  SIMCInstr<opName, SISubtarget.SI> {
2521  let DecoderNamespace="SICI";
2522  let DisableDecoder = DisableSIDecoder;
2523}
2524
2525class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
2526  MTBUF <outs, ins, asm, []>,
2527  MTBUFe_vi <op>,
2528  SIMCInstr <opName, SISubtarget.VI> {
2529  let DecoderNamespace="VI";
2530  let DisableDecoder = DisableVIDecoder;
2531}
2532
2533multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
2534                    list<dag> pattern> {
2535
2536  def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
2537
2538  def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
2539
2540  def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
2541
2542}
2543
2544let mayStore = 1, mayLoad = 0 in {
2545
2546multiclass MTBUF_Store_Helper <bits<3> op, string opName,
2547                               RegisterClass regClass> : MTBUF_m <
2548  op, opName, (outs),
2549  (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
2550   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
2551   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2552  opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2553        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2554>;
2555
2556} // mayStore = 1, mayLoad = 0
2557
2558let mayLoad = 1, mayStore = 0 in {
2559
2560multiclass MTBUF_Load_Helper <bits<3> op, string opName,
2561                              RegisterClass regClass> : MTBUF_m <
2562  op, opName, (outs regClass:$dst),
2563  (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
2564       i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
2565       i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
2566  opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
2567        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
2568>;
2569
2570} // mayLoad = 1, mayStore = 0
2571
2572//===----------------------------------------------------------------------===//
2573// MUBUF classes
2574//===----------------------------------------------------------------------===//
2575
2576class mubuf <bits<7> si, bits<7> vi = si> {
2577  field bits<7> SI = si;
2578  field bits<7> VI = vi;
2579}
2580
2581let isCodeGenOnly = 0 in {
2582
2583class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2584  MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
2585  let lds  = 0;
2586}
2587
2588} // End let isCodeGenOnly = 0
2589
2590class MUBUF_vi <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
2591  MUBUF <outs, ins, asm, pattern>, MUBUFe_vi <op> {
2592  let lds = 0;
2593}
2594
2595class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
2596  bit IsAddr64 = is_addr64;
2597  string OpName = NAME # suffix;
2598}
2599
2600class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2601  MUBUF <outs, ins, "", pattern>,
2602  SIMCInstr<opName, SISubtarget.NONE> {
2603  let isPseudo = 1;
2604  let isCodeGenOnly = 1;
2605
2606  // dummy fields, so that we can use let statements around multiclasses
2607  bits<1> offen;
2608  bits<1> idxen;
2609  bits<8> vaddr;
2610  bits<1> glc;
2611  bits<1> slc;
2612  bits<1> tfe;
2613  bits<8> soffset;
2614}
2615
2616class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
2617                     string asm> :
2618  MUBUF <outs, ins, asm, []>,
2619  MUBUFe <op.SI>,
2620  SIMCInstr<opName, SISubtarget.SI> {
2621  let lds = 0;
2622  let DecoderNamespace="SICI";
2623  let DisableDecoder = DisableSIDecoder;
2624}
2625
2626class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
2627                     string asm> :
2628  MUBUF <outs, ins, asm, []>,
2629  MUBUFe_vi <op.VI>,
2630  SIMCInstr<opName, SISubtarget.VI> {
2631  let lds = 0;
2632  let DecoderNamespace="VI";
2633  let DisableDecoder = DisableVIDecoder;
2634}
2635
2636multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
2637                    list<dag> pattern> {
2638
2639  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2640           MUBUFAddr64Table <0>;
2641
2642  let addr64 = 0, isCodeGenOnly = 0 in {
2643    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2644  }
2645
2646  def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2647}
2648
2649multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
2650                          dag ins, string asm, list<dag> pattern> {
2651
2652  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2653           MUBUFAddr64Table <1>;
2654
2655  let addr64 = 1, isCodeGenOnly = 0 in {
2656    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2657  }
2658
2659  // There is no VI version. If the pseudo is selected, it should be lowered
2660  // for VI appropriately.
2661}
2662
2663multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
2664                                string asm, list<dag> pattern, bit is_return> {
2665
2666  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2667           MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
2668           AtomicNoRet<NAME#"_OFFSET", is_return>;
2669
2670  let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
2671    let addr64 = 0 in {
2672      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2673    }
2674
2675    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
2676  }
2677}
2678
2679multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
2680                                string asm, list<dag> pattern, bit is_return> {
2681
2682  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
2683           MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
2684           AtomicNoRet<NAME#"_ADDR64", is_return>;
2685
2686  let offen = 0, idxen = 0, addr64 = 1, tfe = 0 in {
2687    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
2688  }
2689
2690  // There is no VI version. If the pseudo is selected, it should be lowered
2691  // for VI appropriately.
2692}
2693
2694multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
2695                         ValueType vt, SDPatternOperator atomic> {
2696
2697  let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
2698
2699    // No return variants
2700    let glc = 0 in {
2701
2702      defm _ADDR64 : MUBUFAtomicAddr64_m <
2703        op, name#"_addr64", (outs),
2704        (ins rc:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2705             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2706        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#"$slc", [], 0
2707      >;
2708
2709      defm _OFFSET : MUBUFAtomicOffset_m <
2710        op, name#"_offset", (outs),
2711        (ins rc:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset, mbuf_offset:$offset,
2712             slc:$slc),
2713        name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
2714      >;
2715    } // glc = 0
2716
2717    // Variant that return values
2718    let glc = 1, Constraints = "$vdata = $vdata_in",
2719        DisableEncoding = "$vdata_in"  in {
2720
2721      defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
2722        op, name#"_rtn_addr64", (outs rc:$vdata),
2723        (ins rc:$vdata_in, VReg_64:$vaddr, SReg_128:$srsrc,
2724             SCSrc_32:$soffset, mbuf_offset:$offset, slc:$slc),
2725        name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#" glc"#"$slc",
2726        [(set vt:$vdata,
2727         (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i32:$soffset,
2728	                            i16:$offset, i1:$slc), vt:$vdata_in))], 1
2729      >;
2730
2731      defm _RTN_OFFSET : MUBUFAtomicOffset_m <
2732        op, name#"_rtn_offset", (outs rc:$vdata),
2733        (ins rc:$vdata_in, SReg_128:$srsrc, SCSrc_32:$soffset,
2734             mbuf_offset:$offset, slc:$slc),
2735        name#" $vdata, $srsrc, $soffset"#"$offset"#" glc$slc",
2736        [(set vt:$vdata,
2737         (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
2738                                    i1:$slc), vt:$vdata_in))], 1
2739      >;
2740
2741    } // glc = 1
2742
2743  } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
2744}
2745
2746// FIXME: tfe can't be an operand because it requires a separate
2747// opcode because it needs an N+1 register class dest register.
2748multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
2749                              ValueType load_vt = i32,
2750                              SDPatternOperator ld = null_frag> {
2751
2752  let mayLoad = 1, mayStore = 0 in {
2753    let offen = 0, idxen = 0, vaddr = 0 in {
2754      defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
2755                           (ins SReg_128:$srsrc, SCSrc_32:$soffset,
2756                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2757                           name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2758                           [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
2759                                                     i32:$soffset, i16:$offset,
2760                                                     i1:$glc, i1:$slc, i1:$tfe)))]>;
2761    }
2762
2763    let offen = 1, idxen = 0  in {
2764      defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
2765                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2766                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
2767                           tfe:$tfe),
2768                           name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2769    }
2770
2771    let offen = 0, idxen = 1 in {
2772      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
2773                           (ins VGPR_32:$vaddr, SReg_128:$srsrc,
2774                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2775                           slc:$slc, tfe:$tfe),
2776                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2777    }
2778
2779    let offen = 1, idxen = 1 in {
2780      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
2781                           (ins VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2782                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2783                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2784    }
2785
2786    let offen = 0, idxen = 0 in {
2787      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
2788                           (ins VReg_64:$vaddr, SReg_128:$srsrc,
2789                                SCSrc_32:$soffset, mbuf_offset:$offset,
2790				glc:$glc, slc:$slc, tfe:$tfe),
2791                           name#" $vdata, $vaddr, $srsrc, $soffset addr64"#"$offset"#
2792                                "$glc"#"$slc"#"$tfe",
2793                           [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
2794                                                  i64:$vaddr, i32:$soffset,
2795                                                  i16:$offset, i1:$glc, i1:$slc,
2796						  i1:$tfe)))]>;
2797    }
2798  }
2799}
2800
2801multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
2802                          ValueType store_vt = i32, SDPatternOperator st = null_frag> {
2803  let mayLoad = 0, mayStore = 1 in {
2804    defm : MUBUF_m <op, name, (outs),
2805                    (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2806                    mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
2807                    tfe:$tfe),
2808                    name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
2809                         "$glc"#"$slc"#"$tfe", []>;
2810
2811    let offen = 0, idxen = 0, vaddr = 0 in {
2812      defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
2813                              (ins vdataClass:$vdata, SReg_128:$srsrc, SCSrc_32:$soffset,
2814                              mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2815                              name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
2816                              [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
2817                                   i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
2818    } // offen = 0, idxen = 0, vaddr = 0
2819
2820    let offen = 1, idxen = 0  in {
2821      defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
2822                             (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2823                              SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2824                              slc:$slc, tfe:$tfe),
2825                             name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
2826                             "$glc"#"$slc"#"$tfe", []>;
2827    } // end offen = 1, idxen = 0
2828
2829    let offen = 0, idxen = 1 in {
2830      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs),
2831                           (ins vdataClass:$vdata, VGPR_32:$vaddr, SReg_128:$srsrc,
2832                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc,
2833                           slc:$slc, tfe:$tfe),
2834                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2835    }
2836
2837    let offen = 1, idxen = 1 in {
2838      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs),
2839                           (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc, SCSrc_32:$soffset,
2840                           mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
2841                           name#" $vdata, $vaddr, $srsrc, $soffset idxen offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
2842    }
2843
2844    let offen = 0, idxen = 0 in {
2845      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
2846                                    (ins vdataClass:$vdata, VReg_64:$vaddr, SReg_128:$srsrc,
2847                                         SCSrc_32:$soffset,
2848                                         mbuf_offset:$offset, glc:$glc, slc:$slc,
2849                                         tfe:$tfe),
2850                                    name#" $vdata, $vaddr, $srsrc, $soffset addr64"#
2851                                         "$offset"#"$glc"#"$slc"#"$tfe",
2852                                    [(st store_vt:$vdata,
2853                                      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr,
2854                                                   i32:$soffset, i16:$offset,
2855                                                   i1:$glc, i1:$slc, i1:$tfe))]>;
2856    }
2857  } // End mayLoad = 0, mayStore = 1
2858}
2859
2860// For cache invalidation instructions.
2861multiclass MUBUF_Invalidate <mubuf op, string opName, SDPatternOperator node> {
2862  let hasSideEffects = 1, mayStore = 1, AsmMatchConverter = "" in {
2863    def "" : MUBUF_Pseudo <opName, (outs), (ins), [(node)]>;
2864
2865    // Set everything to 0.
2866    let offset = 0, offen = 0, idxen = 0, glc = 0, vaddr = 0,
2867        vdata = 0, srsrc = 0, slc = 0, tfe = 0, soffset = 0 in {
2868      let addr64 = 0 in {
2869        def _si : MUBUF_Real_si <op, opName, (outs), (ins), opName>;
2870      }
2871
2872      def _vi : MUBUF_Real_vi <op, opName, (outs), (ins), opName>;
2873    }
2874  } // End hasSideEffects = 1, mayStore = 1, AsmMatchConverter = ""
2875}
2876
2877//===----------------------------------------------------------------------===//
2878// FLAT classes
2879//===----------------------------------------------------------------------===//
2880
2881class flat <bits<7> ci, bits<7> vi = ci> {
2882  field bits<7> CI = ci;
2883  field bits<7> VI = vi;
2884}
2885
2886class FLAT_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
2887     FLAT <0, outs, ins, "", pattern>,
2888      SIMCInstr<opName, SISubtarget.NONE> {
2889  let isPseudo = 1;
2890  let isCodeGenOnly = 1;
2891}
2892
2893class FLAT_Real_ci <bits<7> op, string opName, dag outs, dag ins, string asm> :
2894    FLAT <op, outs, ins, asm, []>,
2895    SIMCInstr<opName, SISubtarget.SI> {
2896  let AssemblerPredicate = isCIOnly;
2897  let DecoderNamespace="CI";
2898}
2899
2900class FLAT_Real_vi <bits<7> op, string opName, dag outs, dag ins, string asm> :
2901    FLAT <op, outs, ins, asm, []>,
2902    SIMCInstr<opName, SISubtarget.VI> {
2903  let AssemblerPredicate = VIAssemblerPredicate;
2904  let DecoderNamespace="VI";
2905  let DisableDecoder = DisableVIDecoder;
2906}
2907
2908multiclass FLAT_AtomicRet_m <flat op, dag outs, dag ins, string asm,
2909                   list<dag> pattern> {
2910  def "" : FLAT_Pseudo <NAME#"_RTN", outs, ins, pattern>,
2911               AtomicNoRet <NAME, 1>;
2912
2913  def _ci : FLAT_Real_ci <op.CI, NAME#"_RTN", outs, ins, asm>;
2914
2915  def _vi : FLAT_Real_vi <op.VI, NAME#"_RTN", outs, ins, asm>;
2916}
2917
2918multiclass FLAT_Load_Helper <flat op, string asm_name,
2919    RegisterClass regClass,
2920    dag outs = (outs regClass:$vdst),
2921    dag ins = (ins VReg_64:$addr, glc_flat:$glc, slc_flat:$slc, tfe_flat:$tfe),
2922    string asm = asm_name#" $vdst, $addr"#"$glc"#"$slc"#"$tfe"> {
2923
2924  let data = 0, mayLoad = 1 in {
2925
2926    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
2927
2928    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
2929
2930    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
2931  }
2932}
2933
2934multiclass FLAT_Store_Helper <flat op, string asm_name,
2935    RegisterClass vdataClass,
2936    dag outs = (outs),
2937    dag ins = (ins VReg_64:$addr, vdataClass:$data, glc_flat:$glc,
2938                   slc_flat:$slc, tfe_flat:$tfe),
2939    string asm = asm_name#" $addr, $data"#"$glc"#"$slc"#"$tfe"> {
2940
2941  let mayLoad = 0, mayStore = 1, vdst = 0 in {
2942
2943    def "" : FLAT_Pseudo <NAME, outs, ins, []>;
2944
2945    def _ci : FLAT_Real_ci <op.CI, NAME, outs, ins, asm>;
2946
2947    def _vi : FLAT_Real_vi <op.VI, NAME, outs, ins, asm>;
2948  }
2949}
2950
2951multiclass FLAT_ATOMIC <flat op, string asm_name, RegisterClass vdst_rc,
2952    RegisterClass data_rc = vdst_rc,
2953    dag outs_noret = (outs),
2954    string asm_noret = asm_name#" $addr, $data"#"$slc"#"$tfe"> {
2955
2956  let mayLoad = 1, mayStore = 1, glc = 0, vdst = 0, AsmMatchConverter = "cvtFlatAtomic" in {
2957    def "" : FLAT_Pseudo <NAME, outs_noret,
2958                          (ins VReg_64:$addr, data_rc:$data,
2959                               slc_flat_atomic:$slc, tfe_flat_atomic:$tfe), []>,
2960             AtomicNoRet <NAME, 0>;
2961
2962    def _ci : FLAT_Real_ci <op.CI, NAME, outs_noret,
2963                            (ins VReg_64:$addr, data_rc:$data,
2964                                 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe),
2965                            asm_noret>;
2966
2967    def _vi : FLAT_Real_vi <op.VI, NAME, outs_noret,
2968                            (ins VReg_64:$addr, data_rc:$data,
2969                                 slc_flat_atomic:$slc, tfe_flat_atomic:$tfe),
2970                            asm_noret>;
2971  }
2972
2973  let glc = 1, hasPostISelHook = 1, AsmMatchConverter = "cvtFlatAtomic" in {
2974    defm _RTN : FLAT_AtomicRet_m <op, (outs vdst_rc:$vdst),
2975                        (ins VReg_64:$addr, data_rc:$data, slc_flat_atomic:$slc,
2976                             tfe_flat_atomic:$tfe),
2977                        asm_name#" $vdst, $addr, $data glc"#"$slc"#"$tfe", []>;
2978  }
2979}
2980
2981class MIMG_Mask <string op, int channels> {
2982  string Op = op;
2983  int Channels = channels;
2984}
2985
2986class MIMG_Helper <bits<7> op, dag outs, dag ins, string asm,
2987                   string dns=""> : MIMG<op, outs, ins, asm,[]> {
2988  let mayLoad = 1;
2989  let mayStore = 0;
2990  let hasPostISelHook = 1;
2991  let DecoderNamespace = dns;
2992  let isAsmParserOnly = !if(!eq(dns,""), 1, 0);
2993  let AsmMatchConverter = "cvtMIMG";
2994}
2995
2996class MIMG_NoSampler_Helper <bits<7> op, string asm,
2997                             RegisterClass dst_rc,
2998                             RegisterClass addr_rc,
2999                             string dns=""> : MIMG_Helper <
3000  op,
3001  (outs dst_rc:$vdata),
3002  (ins addr_rc:$vaddr, SReg_256:$srsrc,
3003       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3004       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3005  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3006  dns> {
3007  let ssamp = 0;
3008}
3009
3010multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
3011                                      RegisterClass dst_rc,
3012                                      int channels> {
3013  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32,
3014                                   !if(!eq(channels, 1), "AMDGPU", "")>,
3015            MIMG_Mask<asm#"_V1", channels>;
3016  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
3017            MIMG_Mask<asm#"_V2", channels>;
3018  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
3019            MIMG_Mask<asm#"_V4", channels>;
3020}
3021
3022multiclass MIMG_NoSampler <bits<7> op, string asm> {
3023  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
3024  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
3025  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
3026  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
3027}
3028
3029class MIMG_Store_Helper <bits<7> op, string asm,
3030                         RegisterClass data_rc,
3031                         RegisterClass addr_rc> : MIMG_Helper <
3032  op,
3033  (outs),
3034  (ins data_rc:$vdata, addr_rc:$vaddr, SReg_256:$srsrc,
3035       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3036       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3037  asm#" $vdata, $vaddr, $srsrc$dmask$unorm$glc$slc$r128$tfe$lwe$da"
3038     > {
3039  let ssamp = 0;
3040  let mayLoad = 1; // TableGen requires this for matching with the intrinsics
3041  let mayStore = 1;
3042  let hasSideEffects = 1;
3043  let hasPostISelHook = 0;
3044}
3045
3046multiclass MIMG_Store_Addr_Helper <bits<7> op, string asm,
3047                                  RegisterClass data_rc,
3048                                  int channels> {
3049  def _V1 : MIMG_Store_Helper <op, asm, data_rc, VGPR_32>,
3050            MIMG_Mask<asm#"_V1", channels>;
3051  def _V2 : MIMG_Store_Helper <op, asm, data_rc, VReg_64>,
3052            MIMG_Mask<asm#"_V2", channels>;
3053  def _V4 : MIMG_Store_Helper <op, asm, data_rc, VReg_128>,
3054            MIMG_Mask<asm#"_V4", channels>;
3055}
3056
3057multiclass MIMG_Store <bits<7> op, string asm> {
3058  defm _V1 : MIMG_Store_Addr_Helper <op, asm, VGPR_32, 1>;
3059  defm _V2 : MIMG_Store_Addr_Helper <op, asm, VReg_64, 2>;
3060  defm _V3 : MIMG_Store_Addr_Helper <op, asm, VReg_96, 3>;
3061  defm _V4 : MIMG_Store_Addr_Helper <op, asm, VReg_128, 4>;
3062}
3063
3064class MIMG_Sampler_Helper <bits<7> op, string asm,
3065                           RegisterClass dst_rc,
3066                           RegisterClass src_rc,
3067                           int wqm,
3068                           string dns=""> : MIMG_Helper <
3069  op,
3070  (outs dst_rc:$vdata),
3071  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3072       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3073       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3074  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3075  dns> {
3076  let WQM = wqm;
3077}
3078
3079multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
3080                                    RegisterClass dst_rc,
3081                                    int channels, int wqm> {
3082  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm,
3083                                 !if(!eq(channels, 1), "AMDGPU", "")>,
3084            MIMG_Mask<asm#"_V1", channels>;
3085  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
3086            MIMG_Mask<asm#"_V2", channels>;
3087  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
3088            MIMG_Mask<asm#"_V4", channels>;
3089  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
3090            MIMG_Mask<asm#"_V8", channels>;
3091  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
3092            MIMG_Mask<asm#"_V16", channels>;
3093}
3094
3095multiclass MIMG_Sampler <bits<7> op, string asm, int wqm=0> {
3096  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3097  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, wqm>;
3098  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, wqm>;
3099  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, wqm>;
3100}
3101
3102multiclass MIMG_Sampler_WQM <bits<7> op, string asm> : MIMG_Sampler<op, asm, 1>;
3103
3104class MIMG_Gather_Helper <bits<7> op, string asm,
3105                          RegisterClass dst_rc,
3106                          RegisterClass src_rc, int wqm> : MIMG <
3107  op,
3108  (outs dst_rc:$vdata),
3109  (ins src_rc:$vaddr, SReg_256:$srsrc, SReg_128:$ssamp,
3110       dmask:$dmask, unorm:$unorm, glc:$glc, slc:$slc,
3111       r128:$r128, tfe:$tfe, lwe:$lwe, da:$da),
3112  asm#" $vdata, $vaddr, $srsrc, $ssamp$dmask$unorm$glc$slc$r128$tfe$lwe$da",
3113  []> {
3114  let mayLoad = 1;
3115  let mayStore = 0;
3116
3117  // DMASK was repurposed for GATHER4. 4 components are always
3118  // returned and DMASK works like a swizzle - it selects
3119  // the component to fetch. The only useful DMASK values are
3120  // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
3121  // (red,red,red,red) etc.) The ISA document doesn't mention
3122  // this.
3123  // Therefore, disable all code which updates DMASK by setting these two:
3124  let MIMG = 0;
3125  let hasPostISelHook = 0;
3126  let WQM = wqm;
3127
3128  let isAsmParserOnly = 1; // TBD: fix it later
3129}
3130
3131multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
3132                                    RegisterClass dst_rc,
3133                                    int channels, int wqm> {
3134  def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
3135            MIMG_Mask<asm#"_V1", channels>;
3136  def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
3137            MIMG_Mask<asm#"_V2", channels>;
3138  def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
3139            MIMG_Mask<asm#"_V4", channels>;
3140  def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
3141            MIMG_Mask<asm#"_V8", channels>;
3142  def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
3143            MIMG_Mask<asm#"_V16", channels>;
3144}
3145
3146multiclass MIMG_Gather <bits<7> op, string asm, int wqm=0> {
3147  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, wqm>;
3148  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, wqm>;
3149  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, wqm>;
3150  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, wqm>;
3151}
3152
3153multiclass MIMG_Gather_WQM <bits<7> op, string asm> : MIMG_Gather<op, asm, 1>;
3154
3155//===----------------------------------------------------------------------===//
3156// Vector instruction mappings
3157//===----------------------------------------------------------------------===//
3158
3159// Maps an opcode in e32 form to its e64 equivalent
3160def getVOPe64 : InstrMapping {
3161  let FilterClass = "VOP";
3162  let RowFields = ["OpName"];
3163  let ColFields = ["Size"];
3164  let KeyCol = ["4"];
3165  let ValueCols = [["8"]];
3166}
3167
3168// Maps an opcode in e64 form to its e32 equivalent
3169def getVOPe32 : InstrMapping {
3170  let FilterClass = "VOP";
3171  let RowFields = ["OpName"];
3172  let ColFields = ["Size"];
3173  let KeyCol = ["8"];
3174  let ValueCols = [["4"]];
3175}
3176
3177def getMaskedMIMGOp : InstrMapping {
3178  let FilterClass = "MIMG_Mask";
3179  let RowFields = ["Op"];
3180  let ColFields = ["Channels"];
3181  let KeyCol = ["4"];
3182  let ValueCols = [["1"], ["2"], ["3"] ];
3183}
3184
3185// Maps an commuted opcode to its original version
3186def getCommuteOrig : InstrMapping {
3187  let FilterClass = "VOP2_REV";
3188  let RowFields = ["RevOp"];
3189  let ColFields = ["IsOrig"];
3190  let KeyCol = ["0"];
3191  let ValueCols = [["1"]];
3192}
3193
3194// Maps an original opcode to its commuted version
3195def getCommuteRev : InstrMapping {
3196  let FilterClass = "VOP2_REV";
3197  let RowFields = ["RevOp"];
3198  let ColFields = ["IsOrig"];
3199  let KeyCol = ["1"];
3200  let ValueCols = [["0"]];
3201}
3202
3203def getCommuteCmpOrig : InstrMapping {
3204  let FilterClass = "VOP2_REV";
3205  let RowFields = ["RevOp"];
3206  let ColFields = ["IsOrig"];
3207  let KeyCol = ["0"];
3208  let ValueCols = [["1"]];
3209}
3210
3211// Maps an original opcode to its commuted version
3212def getCommuteCmpRev : InstrMapping {
3213  let FilterClass = "VOP2_REV";
3214  let RowFields = ["RevOp"];
3215  let ColFields = ["IsOrig"];
3216  let KeyCol = ["1"];
3217  let ValueCols = [["0"]];
3218}
3219
3220
3221def getMCOpcodeGen : InstrMapping {
3222  let FilterClass = "SIMCInstr";
3223  let RowFields = ["PseudoInstr"];
3224  let ColFields = ["Subtarget"];
3225  let KeyCol = [!cast<string>(SISubtarget.NONE)];
3226  let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
3227}
3228
3229def getAddr64Inst : InstrMapping {
3230  let FilterClass = "MUBUFAddr64Table";
3231  let RowFields = ["OpName"];
3232  let ColFields = ["IsAddr64"];
3233  let KeyCol = ["0"];
3234  let ValueCols = [["1"]];
3235}
3236
3237// Maps an atomic opcode to its version with a return value.
3238def getAtomicRetOp : InstrMapping {
3239  let FilterClass = "AtomicNoRet";
3240  let RowFields = ["NoRetOp"];
3241  let ColFields = ["IsRet"];
3242  let KeyCol = ["0"];
3243  let ValueCols = [["1"]];
3244}
3245
3246// Maps an atomic opcode to its returnless version.
3247def getAtomicNoRetOp : InstrMapping {
3248  let FilterClass = "AtomicNoRet";
3249  let RowFields = ["NoRetOp"];
3250  let ColFields = ["IsRet"];
3251  let KeyCol = ["1"];
3252  let ValueCols = [["0"]];
3253}
3254
3255include "SIInstructions.td"
3256include "CIInstructions.td"
3257include "VIInstructions.td"
3258