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//===----------------------------------------------------------------------===//
9
10class vop {
11  field bits<9> SI3;
12  field bits<10> VI3;
13}
14
15class vopc <bits<8> si, bits<8> vi = !add(0x40, si)> : vop {
16  field bits<8> SI = si;
17  field bits<8> VI = vi;
18
19  field bits<9>  SI3 = {0, si{7-0}};
20  field bits<10> VI3 = {0, 0, vi{7-0}};
21}
22
23class vop1 <bits<8> si, bits<8> vi = si> : vop {
24  field bits<8> SI = si;
25  field bits<8> VI = vi;
26
27  field bits<9>  SI3 = {1, 1, si{6-0}};
28  field bits<10> VI3 = !add(0x140, vi);
29}
30
31class vop2 <bits<6> si, bits<6> vi = si> : vop {
32  field bits<6> SI = si;
33  field bits<6> VI = vi;
34
35  field bits<9>  SI3 = {1, 0, 0, si{5-0}};
36  field bits<10> VI3 = {0, 1, 0, 0, vi{5-0}};
37}
38
39// Specify a VOP2 opcode for SI and VOP3 opcode for VI
40// that doesn't have VOP2 encoding on VI
41class vop23 <bits<6> si, bits<10> vi> : vop2 <si> {
42  let VI3 = vi;
43}
44
45class vop3 <bits<9> si, bits<10> vi = {0, si}> : vop {
46  let SI3 = si;
47  let VI3 = vi;
48}
49
50class sop1 <bits<8> si, bits<8> vi = si> {
51  field bits<8> SI = si;
52  field bits<8> VI = vi;
53}
54
55class sop2 <bits<7> si, bits<7> vi = si> {
56  field bits<7> SI = si;
57  field bits<7> VI = vi;
58}
59
60class sopk <bits<5> si, bits<5> vi = si> {
61  field bits<5> SI = si;
62  field bits<5> VI = vi;
63}
64
65// Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
66// in AMDGPUInstrInfo.cpp
67def SISubtarget {
68  int NONE = -1;
69  int SI = 0;
70  int VI = 1;
71}
72
73//===----------------------------------------------------------------------===//
74// SI DAG Nodes
75//===----------------------------------------------------------------------===//
76
77def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
78  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
79                      [SDNPMayLoad, SDNPMemOperand]
80>;
81
82def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
83  SDTypeProfile<0, 13,
84    [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
85     SDTCisVT<1, iAny>,   // vdata(VGPR)
86     SDTCisVT<2, i32>,    // num_channels(imm)
87     SDTCisVT<3, i32>,    // vaddr(VGPR)
88     SDTCisVT<4, i32>,    // soffset(SGPR)
89     SDTCisVT<5, i32>,    // inst_offset(imm)
90     SDTCisVT<6, i32>,    // dfmt(imm)
91     SDTCisVT<7, i32>,    // nfmt(imm)
92     SDTCisVT<8, i32>,    // offen(imm)
93     SDTCisVT<9, i32>,    // idxen(imm)
94     SDTCisVT<10, i32>,   // glc(imm)
95     SDTCisVT<11, i32>,   // slc(imm)
96     SDTCisVT<12, i32>    // tfe(imm)
97    ]>,
98  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
99>;
100
101def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
102  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
103                       SDTCisVT<3, i32>]>
104>;
105
106class SDSample<string opcode> : SDNode <opcode,
107  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
108                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
109>;
110
111def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
112def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
113def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
114def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
115
116def SIconstdata_ptr : SDNode<
117  "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
118>;
119
120// Transformation function, extract the lower 32bit of a 64bit immediate
121def LO32 : SDNodeXForm<imm, [{
122  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
123}]>;
124
125def LO32f : SDNodeXForm<fpimm, [{
126  APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
127  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
128}]>;
129
130// Transformation function, extract the upper 32bit of a 64bit immediate
131def HI32 : SDNodeXForm<imm, [{
132  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
133}]>;
134
135def HI32f : SDNodeXForm<fpimm, [{
136  APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
137  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
138}]>;
139
140def IMM8bitDWORD : PatLeaf <(imm),
141  [{return (N->getZExtValue() & ~0x3FC) == 0;}]
142>;
143
144def as_dword_i32imm : SDNodeXForm<imm, [{
145  return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
146}]>;
147
148def as_i1imm : SDNodeXForm<imm, [{
149  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
150}]>;
151
152def as_i8imm : SDNodeXForm<imm, [{
153  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
154}]>;
155
156def as_i16imm : SDNodeXForm<imm, [{
157  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
158}]>;
159
160def as_i32imm: SDNodeXForm<imm, [{
161  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
162}]>;
163
164def as_i64imm: SDNodeXForm<imm, [{
165  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i64);
166}]>;
167
168// Copied from the AArch64 backend:
169def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
170return CurDAG->getTargetConstant(
171  N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i32);
172}]>;
173
174// Copied from the AArch64 backend:
175def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
176return CurDAG->getTargetConstant(
177  N->getValueAPF().bitcastToAPInt().getZExtValue(), MVT::i64);
178}]>;
179
180def IMM8bit : PatLeaf <(imm),
181  [{return isUInt<8>(N->getZExtValue());}]
182>;
183
184def IMM12bit : PatLeaf <(imm),
185  [{return isUInt<12>(N->getZExtValue());}]
186>;
187
188def IMM16bit : PatLeaf <(imm),
189  [{return isUInt<16>(N->getZExtValue());}]
190>;
191
192def IMM20bit : PatLeaf <(imm),
193  [{return isUInt<20>(N->getZExtValue());}]
194>;
195
196def IMM32bit : PatLeaf <(imm),
197  [{return isUInt<32>(N->getZExtValue());}]
198>;
199
200def mubuf_vaddr_offset : PatFrag<
201  (ops node:$ptr, node:$offset, node:$imm_offset),
202  (add (add node:$ptr, node:$offset), node:$imm_offset)
203>;
204
205class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
206  return isInlineImmediate(N);
207}]>;
208
209class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
210  return isInlineImmediate(N);
211}]>;
212
213class SGPRImm <dag frag> : PatLeaf<frag, [{
214  if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
215      AMDGPUSubtarget::SOUTHERN_ISLANDS) {
216    return false;
217  }
218  const SIRegisterInfo *SIRI =
219                       static_cast<const SIRegisterInfo*>(TM.getSubtargetImpl()->getRegisterInfo());
220  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
221                                                U != E; ++U) {
222    if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
223      return true;
224    }
225  }
226  return false;
227}]>;
228
229//===----------------------------------------------------------------------===//
230// Custom Operands
231//===----------------------------------------------------------------------===//
232
233def FRAMEri32 : Operand<iPTR> {
234  let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
235}
236
237def sopp_brtarget : Operand<OtherVT> {
238  let EncoderMethod = "getSOPPBrEncoding";
239  let OperandType = "OPERAND_PCREL";
240}
241
242include "SIInstrFormats.td"
243include "VIInstrFormats.td"
244
245let OperandType = "OPERAND_IMMEDIATE" in {
246
247def offen : Operand<i1> {
248  let PrintMethod = "printOffen";
249}
250def idxen : Operand<i1> {
251  let PrintMethod = "printIdxen";
252}
253def addr64 : Operand<i1> {
254  let PrintMethod = "printAddr64";
255}
256def mbuf_offset : Operand<i16> {
257  let PrintMethod = "printMBUFOffset";
258}
259def ds_offset : Operand<i16> {
260  let PrintMethod = "printDSOffset";
261}
262def ds_offset0 : Operand<i8> {
263  let PrintMethod = "printDSOffset0";
264}
265def ds_offset1 : Operand<i8> {
266  let PrintMethod = "printDSOffset1";
267}
268def glc : Operand <i1> {
269  let PrintMethod = "printGLC";
270}
271def slc : Operand <i1> {
272  let PrintMethod = "printSLC";
273}
274def tfe : Operand <i1> {
275  let PrintMethod = "printTFE";
276}
277
278def omod : Operand <i32> {
279  let PrintMethod = "printOModSI";
280}
281
282def ClampMod : Operand <i1> {
283  let PrintMethod = "printClampSI";
284}
285
286} // End OperandType = "OPERAND_IMMEDIATE"
287
288//===----------------------------------------------------------------------===//
289// Complex patterns
290//===----------------------------------------------------------------------===//
291
292def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
293def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
294
295def MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
296def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
297def MUBUFAddr64Atomic : ComplexPattern<i64, 4, "SelectMUBUFAddr64">;
298def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
299def MUBUFOffset : ComplexPattern<i64, 6, "SelectMUBUFOffset">;
300def MUBUFOffsetAtomic : ComplexPattern<i64, 4, "SelectMUBUFOffset">;
301
302def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
303def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
304def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
305def VOP3Mods  : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
306
307//===----------------------------------------------------------------------===//
308// SI assembler operands
309//===----------------------------------------------------------------------===//
310
311def SIOperand {
312  int ZERO = 0x80;
313  int VCC = 0x6A;
314  int FLAT_SCR = 0x68;
315}
316
317def SRCMODS {
318  int NONE = 0;
319}
320
321def DSTCLAMP {
322  int NONE = 0;
323}
324
325def DSTOMOD {
326  int NONE = 0;
327}
328
329//===----------------------------------------------------------------------===//
330//
331// SI Instruction multiclass helpers.
332//
333// Instructions with _32 take 32-bit operands.
334// Instructions with _64 take 64-bit operands.
335//
336// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
337// encoding is the standard encoding, but instruction that make use of
338// any of the instruction modifiers must use the 64-bit encoding.
339//
340// Instructions with _e32 use the 32-bit encoding.
341// Instructions with _e64 use the 64-bit encoding.
342//
343//===----------------------------------------------------------------------===//
344
345class SIMCInstr <string pseudo, int subtarget> {
346  string PseudoInstr = pseudo;
347  int Subtarget = subtarget;
348}
349
350//===----------------------------------------------------------------------===//
351// EXP classes
352//===----------------------------------------------------------------------===//
353
354class EXPCommon : InstSI<
355  (outs),
356  (ins i32imm:$en, i32imm:$tgt, i32imm:$compr, i32imm:$done, i32imm:$vm,
357       VGPR_32:$src0, VGPR_32:$src1, VGPR_32:$src2, VGPR_32:$src3),
358  "exp $en, $tgt, $compr, $done, $vm, $src0, $src1, $src2, $src3",
359  [] > {
360
361  let EXP_CNT = 1;
362  let Uses = [EXEC];
363}
364
365multiclass EXP_m {
366
367  let isPseudo = 1 in {
368    def "" : EXPCommon, SIMCInstr <"exp", SISubtarget.NONE> ;
369  }
370
371  def _si : EXPCommon, SIMCInstr <"exp", SISubtarget.SI>, EXPe;
372
373  def _vi : EXPCommon, SIMCInstr <"exp", SISubtarget.VI>, EXPe_vi;
374}
375
376//===----------------------------------------------------------------------===//
377// Scalar classes
378//===----------------------------------------------------------------------===//
379
380class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
381  SOP1 <outs, ins, "", pattern>,
382  SIMCInstr<opName, SISubtarget.NONE> {
383  let isPseudo = 1;
384}
385
386class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
387  SOP1 <outs, ins, asm, []>,
388  SOP1e <op.SI>,
389  SIMCInstr<opName, SISubtarget.SI>;
390
391class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
392  SOP1 <outs, ins, asm, []>,
393  SOP1e <op.VI>,
394  SIMCInstr<opName, SISubtarget.VI>;
395
396multiclass SOP1_32 <sop1 op, string opName, list<dag> pattern> {
397  def "" : SOP1_Pseudo <opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
398    pattern>;
399
400  def _si : SOP1_Real_si <op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
401    opName#" $dst, $src0">;
402
403  def _vi : SOP1_Real_vi <op, opName, (outs SReg_32:$dst), (ins SSrc_32:$src0),
404    opName#" $dst, $src0">;
405}
406
407multiclass SOP1_64 <sop1 op, string opName, list<dag> pattern> {
408  def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
409    pattern>;
410
411  def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
412    opName#" $dst, $src0">;
413
414  def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins SSrc_64:$src0),
415    opName#" $dst, $src0">;
416}
417
418// no input, 64-bit output.
419multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
420  def "" : SOP1_Pseudo <opName, (outs SReg_64:$dst), (ins), pattern>;
421
422  def _si : SOP1_Real_si <op, opName, (outs SReg_64:$dst), (ins),
423    opName#" $dst"> {
424    let SSRC0 = 0;
425  }
426
427  def _vi : SOP1_Real_vi <op, opName, (outs SReg_64:$dst), (ins),
428    opName#" $dst"> {
429    let SSRC0 = 0;
430  }
431}
432
433// 64-bit input, 32-bit output.
434multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> {
435  def "" : SOP1_Pseudo <opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
436    pattern>;
437
438  def _si : SOP1_Real_si <op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
439    opName#" $dst, $src0">;
440
441  def _vi : SOP1_Real_vi <op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
442    opName#" $dst, $src0">;
443}
444
445class SOP2_Pseudo<string opName, dag outs, dag ins, list<dag> pattern> :
446  SOP2<outs, ins, "", pattern>,
447  SIMCInstr<opName, SISubtarget.NONE> {
448  let isPseudo = 1;
449  let Size = 4;
450}
451
452class SOP2_Real_si<sop2 op, string opName, dag outs, dag ins, string asm> :
453  SOP2<outs, ins, asm, []>,
454  SOP2e<op.SI>,
455  SIMCInstr<opName, SISubtarget.SI>;
456
457class SOP2_Real_vi<sop2 op, string opName, dag outs, dag ins, string asm> :
458  SOP2<outs, ins, asm, []>,
459  SOP2e<op.VI>,
460  SIMCInstr<opName, SISubtarget.VI>;
461
462multiclass SOP2_SELECT_32 <sop2 op, string opName, list<dag> pattern> {
463  def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst),
464    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc), pattern>;
465
466  def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst),
467    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
468    opName#" $dst, $src0, $src1 [$scc]">;
469
470  def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst),
471    (ins SSrc_32:$src0, SSrc_32:$src1, SCCReg:$scc),
472    opName#" $dst, $src0, $src1 [$scc]">;
473}
474
475multiclass SOP2_32 <sop2 op, string opName, list<dag> pattern> {
476  def "" : SOP2_Pseudo <opName, (outs SReg_32:$dst),
477    (ins SSrc_32:$src0, SSrc_32:$src1), pattern>;
478
479  def _si : SOP2_Real_si <op, opName, (outs SReg_32:$dst),
480    (ins SSrc_32:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1">;
481
482  def _vi : SOP2_Real_vi <op, opName, (outs SReg_32:$dst),
483    (ins SSrc_32:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1">;
484}
485
486multiclass SOP2_64 <sop2 op, string opName, list<dag> pattern> {
487  def "" : SOP2_Pseudo <opName, (outs SReg_64:$dst),
488    (ins SSrc_64:$src0, SSrc_64:$src1), pattern>;
489
490  def _si : SOP2_Real_si <op, opName, (outs SReg_64:$dst),
491    (ins SSrc_64:$src0, SSrc_64:$src1), opName#" $dst, $src0, $src1">;
492
493  def _vi : SOP2_Real_vi <op, opName, (outs SReg_64:$dst),
494    (ins SSrc_64:$src0, SSrc_64:$src1), opName#" $dst, $src0, $src1">;
495}
496
497multiclass SOP2_64_32 <sop2 op, string opName, list<dag> pattern> {
498  def "" : SOP2_Pseudo <opName, (outs SReg_64:$dst),
499    (ins SSrc_64:$src0, SSrc_32:$src1), pattern>;
500
501  def _si : SOP2_Real_si <op, opName, (outs SReg_64:$dst),
502    (ins SSrc_64:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1">;
503
504  def _vi : SOP2_Real_vi <op, opName, (outs SReg_64:$dst),
505    (ins SSrc_64:$src0, SSrc_32:$src1), opName#" $dst, $src0, $src1">;
506}
507
508
509class SOPC_Helper <bits<7> op, RegisterOperand rc, ValueType vt,
510                    string opName, PatLeaf cond> : SOPC <
511  op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
512  opName#" $dst, $src0, $src1", []>;
513
514class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
515  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
516
517class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
518  : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
519
520class SOPK_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
521  SOPK <outs, ins, "", pattern>,
522  SIMCInstr<opName, SISubtarget.NONE> {
523  let isPseudo = 1;
524}
525
526class SOPK_Real_si <sopk op, string opName, dag outs, dag ins, string asm> :
527  SOPK <outs, ins, asm, []>,
528  SOPKe <op.SI>,
529  SIMCInstr<opName, SISubtarget.SI>;
530
531class SOPK_Real_vi <sopk op, string opName, dag outs, dag ins, string asm> :
532  SOPK <outs, ins, asm, []>,
533  SOPKe <op.VI>,
534  SIMCInstr<opName, SISubtarget.VI>;
535
536multiclass SOPK_32 <sopk op, string opName, list<dag> pattern> {
537  def "" : SOPK_Pseudo <opName, (outs SReg_32:$dst), (ins u16imm:$src0),
538    pattern>;
539
540  def _si : SOPK_Real_si <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
541    opName#" $dst, $src0">;
542
543  def _vi : SOPK_Real_vi <op, opName, (outs SReg_32:$dst), (ins u16imm:$src0),
544    opName#" $dst, $src0">;
545}
546
547multiclass SOPK_SCC <sopk op, string opName, list<dag> pattern> {
548  def "" : SOPK_Pseudo <opName, (outs SCCReg:$dst),
549    (ins SReg_32:$src0, u16imm:$src1), pattern>;
550
551  def _si : SOPK_Real_si <op, opName, (outs SCCReg:$dst),
552    (ins SReg_32:$src0, u16imm:$src1), opName#" $dst, $src0">;
553
554  def _vi : SOPK_Real_vi <op, opName, (outs SCCReg:$dst),
555    (ins SReg_32:$src0, u16imm:$src1), opName#" $dst, $src0">;
556}
557
558//===----------------------------------------------------------------------===//
559// SMRD classes
560//===----------------------------------------------------------------------===//
561
562class SMRD_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
563  SMRD <outs, ins, "", pattern>,
564  SIMCInstr<opName, SISubtarget.NONE> {
565  let isPseudo = 1;
566}
567
568class SMRD_Real_si <bits<5> op, string opName, bit imm, dag outs, dag ins,
569                    string asm> :
570  SMRD <outs, ins, asm, []>,
571  SMRDe <op, imm>,
572  SIMCInstr<opName, SISubtarget.SI>;
573
574class SMRD_Real_vi <bits<8> op, string opName, bit imm, dag outs, dag ins,
575                    string asm> :
576  SMRD <outs, ins, asm, []>,
577  SMEMe_vi <op, imm>,
578  SIMCInstr<opName, SISubtarget.VI>;
579
580multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins,
581                   string asm, list<dag> pattern> {
582
583  def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
584
585  def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
586
587  def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>;
588}
589
590multiclass SMRD_Helper <bits<5> op, string opName, RegisterClass baseClass,
591                        RegisterClass dstClass> {
592  defm _IMM : SMRD_m <
593    op, opName#"_IMM", 1, (outs dstClass:$dst),
594    (ins baseClass:$sbase, u32imm:$offset),
595    opName#" $dst, $sbase, $offset", []
596  >;
597
598  defm _SGPR : SMRD_m <
599    op, opName#"_SGPR", 0, (outs dstClass:$dst),
600    (ins baseClass:$sbase, SReg_32:$soff),
601    opName#" $dst, $sbase, $soff", []
602  >;
603}
604
605//===----------------------------------------------------------------------===//
606// Vector ALU classes
607//===----------------------------------------------------------------------===//
608
609// This must always be right before the operand being input modified.
610def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
611  let PrintMethod = "printOperandAndMods";
612}
613def InputModsNoDefault : Operand <i32> {
614  let PrintMethod = "printOperandAndMods";
615}
616
617class getNumSrcArgs<ValueType Src1, ValueType Src2> {
618  int ret =
619    !if (!eq(Src1.Value, untyped.Value),      1,   // VOP1
620         !if (!eq(Src2.Value, untyped.Value), 2,   // VOP2
621                                              3)); // VOP3
622}
623
624// Returns the register class to use for the destination of VOP[123C]
625// instructions for the given VT.
626class getVALUDstForVT<ValueType VT> {
627  RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32,
628                          !if(!eq(VT.Size, 64), VReg_64,
629                            SReg_64)); // else VT == i1
630}
631
632// Returns the register class to use for source 0 of VOP[12C]
633// instructions for the given VT.
634class getVOPSrc0ForVT<ValueType VT> {
635  RegisterOperand ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
636}
637
638// Returns the register class to use for source 1 of VOP[12C] for the
639// given VT.
640class getVOPSrc1ForVT<ValueType VT> {
641  RegisterClass ret = !if(!eq(VT.Size, 32), VGPR_32, VReg_64);
642}
643
644// Returns the register classes for the source arguments of a VOP[12C]
645// instruction for the given SrcVTs.
646class getInRC32 <list<ValueType> SrcVT> {
647  list<DAGOperand> ret = [
648    getVOPSrc0ForVT<SrcVT[0]>.ret,
649    getVOPSrc1ForVT<SrcVT[1]>.ret
650  ];
651}
652
653// Returns the register class to use for sources of VOP3 instructions for the
654// given VT.
655class getVOP3SrcForVT<ValueType VT> {
656  RegisterOperand ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
657}
658
659// Returns the register classes for the source arguments of a VOP3
660// instruction for the given SrcVTs.
661class getInRC64 <list<ValueType> SrcVT> {
662  list<DAGOperand> ret = [
663    getVOP3SrcForVT<SrcVT[0]>.ret,
664    getVOP3SrcForVT<SrcVT[1]>.ret,
665    getVOP3SrcForVT<SrcVT[2]>.ret
666  ];
667}
668
669// Returns 1 if the source arguments have modifiers, 0 if they do not.
670class hasModifiers<ValueType SrcVT> {
671  bit ret = !if(!eq(SrcVT.Value, f32.Value), 1,
672            !if(!eq(SrcVT.Value, f64.Value), 1, 0));
673}
674
675// Returns the input arguments for VOP[12C] instructions for the given SrcVT.
676class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
677  dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0),               // VOP1
678            !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
679                                    (ins)));
680}
681
682// Returns the input arguments for VOP3 instructions for the given SrcVT.
683class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
684                RegisterOperand Src2RC, int NumSrcArgs,
685                bit HasModifiers> {
686
687  dag ret =
688    !if (!eq(NumSrcArgs, 1),
689      !if (!eq(HasModifiers, 1),
690        // VOP1 with modifiers
691        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
692             ClampMod:$clamp, omod:$omod)
693      /* else */,
694        // VOP1 without modifiers
695        (ins Src0RC:$src0)
696      /* endif */ ),
697    !if (!eq(NumSrcArgs, 2),
698      !if (!eq(HasModifiers, 1),
699        // VOP 2 with modifiers
700        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
701             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
702             ClampMod:$clamp, omod:$omod)
703      /* else */,
704        // VOP2 without modifiers
705        (ins Src0RC:$src0, Src1RC:$src1)
706      /* endif */ )
707    /* NumSrcArgs == 3 */,
708      !if (!eq(HasModifiers, 1),
709        // VOP3 with modifiers
710        (ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
711             InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
712             InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
713             ClampMod:$clamp, omod:$omod)
714      /* else */,
715        // VOP3 without modifiers
716        (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
717      /* endif */ )));
718}
719
720// Returns the assembly string for the inputs and outputs of a VOP[12C]
721// instruction.  This does not add the _e32 suffix, so it can be reused
722// by getAsm64.
723class getAsm32 <int NumSrcArgs> {
724  string src1 = ", $src1";
725  string src2 = ", $src2";
726  string ret = " $dst, $src0"#
727               !if(!eq(NumSrcArgs, 1), "", src1)#
728               !if(!eq(NumSrcArgs, 3), src2, "");
729}
730
731// Returns the assembly string for the inputs and outputs of a VOP3
732// instruction.
733class getAsm64 <int NumSrcArgs, bit HasModifiers> {
734  string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
735  string src1 = !if(!eq(NumSrcArgs, 1), "",
736                   !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
737                                           " $src1_modifiers,"));
738  string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
739  string ret =
740  !if(!eq(HasModifiers, 0),
741      getAsm32<NumSrcArgs>.ret,
742      " $dst, "#src0#src1#src2#"$clamp"#"$omod");
743}
744
745
746class VOPProfile <list<ValueType> _ArgVT> {
747
748  field list<ValueType> ArgVT = _ArgVT;
749
750  field ValueType DstVT = ArgVT[0];
751  field ValueType Src0VT = ArgVT[1];
752  field ValueType Src1VT = ArgVT[2];
753  field ValueType Src2VT = ArgVT[3];
754  field RegisterClass DstRC = getVALUDstForVT<DstVT>.ret;
755  field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
756  field RegisterClass Src1RC32 = getVOPSrc1ForVT<Src1VT>.ret;
757  field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
758  field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
759  field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
760
761  field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
762  field bit HasModifiers = hasModifiers<Src0VT>.ret;
763
764  field dag Outs = (outs DstRC:$dst);
765
766  field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
767  field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
768                             HasModifiers>.ret;
769
770  field string Asm32 = "_e32"#getAsm32<NumSrcArgs>.ret;
771  field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
772}
773
774def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
775def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
776def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
777def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
778def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
779def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
780def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
781def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
782def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
783
784def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
785def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
786def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
787def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
788def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
789def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
790def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
791def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
792  let Src0RC32 = VCSrc_32;
793}
794
795def VOP_I1_F32_I32 : VOPProfile <[i1, f32, i32, untyped]> {
796  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
797  let Asm64 = " $dst, $src0_modifiers, $src1";
798}
799
800def VOP_I1_F64_I32 : VOPProfile <[i1, f64, i32, untyped]> {
801  let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
802  let Asm64 = " $dst, $src0_modifiers, $src1";
803}
804
805def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
806def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
807def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
808
809def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
810def VOP_MADK : VOPProfile <[f32, f32, f32, f32]> {
811  field dag Ins = (ins VCSrc_32:$src0, VGPR_32:$vsrc1, u32imm:$src2);
812  field string Asm = " $dst, $src0, $vsrc1, $src2";
813}
814def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
815def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
816def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
817
818
819class VOP <string opName> {
820  string OpName = opName;
821}
822
823class VOP2_REV <string revOp, bit isOrig> {
824  string RevOp = revOp;
825  bit IsOrig = isOrig;
826}
827
828class AtomicNoRet <string noRetOp, bit isRet> {
829  string NoRetOp = noRetOp;
830  bit IsRet = isRet;
831}
832
833class VOP1_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
834  VOP1Common <outs, ins, "", pattern>,
835  VOP <opName>,
836  SIMCInstr <opName#"_e32", SISubtarget.NONE> {
837  let isPseudo = 1;
838}
839
840multiclass VOP1_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
841                   string opName> {
842  def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
843
844  def _si : VOP1<op.SI, outs, ins, asm, []>,
845            SIMCInstr <opName#"_e32", SISubtarget.SI>;
846  def _vi : VOP1<op.VI, outs, ins, asm, []>,
847            SIMCInstr <opName#"_e32", SISubtarget.VI>;
848}
849
850multiclass VOP1SI_m <vop1 op, dag outs, dag ins, string asm, list<dag> pattern,
851                   string opName> {
852  def "" : VOP1_Pseudo <outs, ins, pattern, opName>;
853
854  def _si : VOP1<op.SI, outs, ins, asm, []>,
855            SIMCInstr <opName#"_e32", SISubtarget.SI>;
856  // No VI instruction. This class is for SI only.
857}
858
859class VOP2_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
860  VOP2Common <outs, ins, "", pattern>,
861  VOP <opName>,
862  SIMCInstr<opName#"_e32", SISubtarget.NONE> {
863  let isPseudo = 1;
864}
865
866multiclass VOP2SI_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
867                     string opName, string revOp> {
868  def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
869           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
870
871  def _si : VOP2 <op.SI, outs, ins, opName#asm, []>,
872            SIMCInstr <opName#"_e32", SISubtarget.SI>;
873}
874
875multiclass VOP2_m <vop2 op, dag outs, dag ins, string asm, list<dag> pattern,
876                   string opName, string revOp> {
877  def "" : VOP2_Pseudo <outs, ins, pattern, opName>,
878           VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
879
880  def _si : VOP2 <op.SI, outs, ins, opName#asm, []>,
881            SIMCInstr <opName#"_e32", SISubtarget.SI>;
882  def _vi : VOP2 <op.VI, outs, ins, opName#asm, []>,
883            SIMCInstr <opName#"_e32", SISubtarget.VI>;
884}
885
886class VOP3DisableFields <bit HasSrc1, bit HasSrc2, bit HasModifiers> {
887
888  bits<2> src0_modifiers = !if(HasModifiers, ?, 0);
889  bits<2> src1_modifiers = !if(HasModifiers, !if(HasSrc1, ?, 0), 0);
890  bits<2> src2_modifiers = !if(HasModifiers, !if(HasSrc2, ? ,0) ,0);
891  bits<2> omod = !if(HasModifiers, ?, 0);
892  bits<1> clamp = !if(HasModifiers, ?, 0);
893  bits<9> src1 = !if(HasSrc1, ?, 0);
894  bits<9> src2 = !if(HasSrc2, ?, 0);
895}
896
897class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
898  VOP3Common <outs, ins, "", pattern>,
899  VOP <opName>,
900  SIMCInstr<opName#"_e64", SISubtarget.NONE> {
901  let isPseudo = 1;
902}
903
904class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
905  VOP3Common <outs, ins, asm, []>,
906  VOP3e <op>,
907  SIMCInstr<opName#"_e64", SISubtarget.SI>;
908
909class VOP3_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
910  VOP3Common <outs, ins, asm, []>,
911  VOP3e_vi <op>,
912  SIMCInstr <opName#"_e64", SISubtarget.VI>;
913
914class VOP3b_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
915  VOP3Common <outs, ins, asm, []>,
916  VOP3be <op>,
917  SIMCInstr<opName#"_e64", SISubtarget.SI>;
918
919class VOP3b_Real_vi <bits<10> op, dag outs, dag ins, string asm, string opName> :
920  VOP3Common <outs, ins, asm, []>,
921  VOP3be_vi <op>,
922  SIMCInstr <opName#"_e64", SISubtarget.VI>;
923
924multiclass VOP3_m <vop op, dag outs, dag ins, string asm, list<dag> pattern,
925                   string opName, int NumSrcArgs, bit HasMods = 1> {
926
927  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
928
929  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
930            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
931                              !if(!eq(NumSrcArgs, 2), 0, 1),
932                              HasMods>;
933  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
934            VOP3DisableFields<!if(!eq(NumSrcArgs, 1), 0, 1),
935                              !if(!eq(NumSrcArgs, 2), 0, 1),
936                              HasMods>;
937}
938
939// VOP3_m without source modifiers
940multiclass VOP3_m_nosrcmod <vop op, dag outs, dag ins, string asm, list<dag> pattern,
941                   string opName, int NumSrcArgs, bit HasMods = 1> {
942
943  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
944
945  let src0_modifiers = 0,
946      src1_modifiers = 0,
947      src2_modifiers = 0 in {
948    def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>;
949    def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>;
950  }
951}
952
953multiclass VOP3_1_m <vop op, dag outs, dag ins, string asm,
954                     list<dag> pattern, string opName, bit HasMods = 1> {
955
956  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
957
958  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
959            VOP3DisableFields<0, 0, HasMods>;
960
961  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
962            VOP3DisableFields<0, 0, HasMods>;
963}
964
965multiclass VOP3SI_1_m <vop op, dag outs, dag ins, string asm,
966                     list<dag> pattern, string opName, bit HasMods = 1> {
967
968  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
969
970  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
971            VOP3DisableFields<0, 0, HasMods>;
972  // No VI instruction. This class is for SI only.
973}
974
975multiclass VOP3_2_m <vop op, dag outs, dag ins, string asm,
976                     list<dag> pattern, string opName, string revOp,
977                     bit HasMods = 1, bit UseFullOp = 0> {
978
979  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
980           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
981
982  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
983            VOP3DisableFields<1, 0, HasMods>;
984
985  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
986            VOP3DisableFields<1, 0, HasMods>;
987}
988
989multiclass VOP3SI_2_m <vop op, dag outs, dag ins, string asm,
990                     list<dag> pattern, string opName, string revOp,
991                     bit HasMods = 1, bit UseFullOp = 0> {
992
993  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
994           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
995
996  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
997            VOP3DisableFields<1, 0, HasMods>;
998
999  // No VI instruction. This class is for SI only.
1000}
1001
1002// XXX - Is v_div_scale_{f32|f64} only available in vop3b without
1003// option of implicit vcc use?
1004multiclass VOP3b_2_m <vop op, dag outs, dag ins, string asm,
1005                      list<dag> pattern, string opName, string revOp,
1006                      bit HasMods = 1, bit UseFullOp = 0> {
1007  def "" : VOP3_Pseudo <outs, ins, pattern, opName>,
1008           VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
1009
1010  // The VOP2 variant puts the carry out into VCC, the VOP3 variant
1011  // can write it into any SGPR. We currently don't use the carry out,
1012  // so for now hardcode it to VCC as well.
1013  let sdst = SIOperand.VCC, Defs = [VCC] in {
1014    def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1015              VOP3DisableFields<1, 0, HasMods>;
1016
1017    def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1018              VOP3DisableFields<1, 0, HasMods>;
1019  } // End sdst = SIOperand.VCC, Defs = [VCC]
1020}
1021
1022multiclass VOP3b_3_m <vop op, dag outs, dag ins, string asm,
1023                      list<dag> pattern, string opName, string revOp,
1024                      bit HasMods = 1, bit UseFullOp = 0> {
1025  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1026
1027
1028  def _si : VOP3b_Real_si <op.SI3, outs, ins, asm, opName>,
1029            VOP3DisableFields<1, 1, HasMods>;
1030
1031  def _vi : VOP3b_Real_vi <op.VI3, outs, ins, asm, opName>,
1032            VOP3DisableFields<1, 1, HasMods>;
1033}
1034
1035multiclass VOP3_C_m <vop op, dag outs, dag ins, string asm,
1036                     list<dag> pattern, string opName,
1037                     bit HasMods, bit defExec> {
1038
1039  def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
1040
1041  def _si : VOP3_Real_si <op.SI3, outs, ins, asm, opName>,
1042            VOP3DisableFields<1, 0, HasMods> {
1043    let Defs = !if(defExec, [EXEC], []);
1044  }
1045
1046  def _vi : VOP3_Real_vi <op.VI3, outs, ins, asm, opName>,
1047            VOP3DisableFields<1, 0, HasMods> {
1048    let Defs = !if(defExec, [EXEC], []);
1049  }
1050}
1051
1052// An instruction that is VOP2 on SI and VOP3 on VI, no modifiers.
1053multiclass VOP2SI_3VI_m <vop3 op, string opName, dag outs, dag ins,
1054                         string asm, list<dag> pattern = []> {
1055  let isPseudo = 1 in {
1056    def "" : VOPAnyCommon <outs, ins, "", pattern>,
1057             SIMCInstr<opName, SISubtarget.NONE>;
1058  }
1059
1060  def _si : VOP2 <op.SI3{5-0}, outs, ins, asm, []>,
1061            SIMCInstr <opName, SISubtarget.SI>;
1062
1063  def _vi : VOP3Common <outs, ins, asm, []>,
1064            VOP3e_vi <op.VI3>,
1065            VOP3DisableFields <1, 0, 0>,
1066            SIMCInstr <opName, SISubtarget.VI>;
1067}
1068
1069multiclass VOP1_Helper <vop1 op, string opName, dag outs,
1070                        dag ins32, string asm32, list<dag> pat32,
1071                        dag ins64, string asm64, list<dag> pat64,
1072                        bit HasMods> {
1073
1074  defm _e32 : VOP1_m <op, outs, ins32, opName#asm32, pat32, opName>;
1075
1076  defm _e64 : VOP3_1_m <op, outs, ins64, opName#"_e64"#asm64, pat64, opName, HasMods>;
1077}
1078
1079multiclass VOP1Inst <vop1 op, string opName, VOPProfile P,
1080                     SDPatternOperator node = null_frag> : VOP1_Helper <
1081  op, opName, P.Outs,
1082  P.Ins32, P.Asm32, [],
1083  P.Ins64, P.Asm64,
1084  !if(P.HasModifiers,
1085      [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1086                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1087      [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1088  P.HasModifiers
1089>;
1090
1091multiclass VOP1InstSI <vop1 op, string opName, VOPProfile P,
1092                       SDPatternOperator node = null_frag> {
1093
1094  defm _e32 : VOP1SI_m <op, P.Outs, P.Ins32, opName#P.Asm32, [], opName>;
1095
1096  defm _e64 : VOP3SI_1_m <op, P.Outs, P.Ins64, opName#P.Asm64,
1097    !if(P.HasModifiers,
1098      [(set P.DstVT:$dst, (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0,
1099                                i32:$src0_modifiers, i1:$clamp, i32:$omod))))],
1100      [(set P.DstVT:$dst, (node P.Src0VT:$src0))]),
1101    opName, P.HasModifiers>;
1102}
1103
1104multiclass VOP2_Helper <vop2 op, string opName, dag outs,
1105                        dag ins32, string asm32, list<dag> pat32,
1106                        dag ins64, string asm64, list<dag> pat64,
1107                        string revOp, bit HasMods> {
1108  defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1109
1110  defm _e64 : VOP3_2_m <op,
1111    outs, ins64, opName#"_e64"#asm64, pat64, opName, revOp, HasMods
1112  >;
1113}
1114
1115multiclass VOP2Inst <vop2 op, string opName, VOPProfile P,
1116                     SDPatternOperator node = null_frag,
1117                     string revOp = opName> : VOP2_Helper <
1118  op, opName, P.Outs,
1119  P.Ins32, P.Asm32, [],
1120  P.Ins64, P.Asm64,
1121  !if(P.HasModifiers,
1122      [(set P.DstVT:$dst,
1123           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1124                                      i1:$clamp, i32:$omod)),
1125                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1126      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1127  revOp, P.HasModifiers
1128>;
1129
1130multiclass VOP2InstSI <vop2 op, string opName, VOPProfile P,
1131                       SDPatternOperator node = null_frag,
1132                       string revOp = opName> {
1133  defm _e32 : VOP2SI_m <op, P.Outs, P.Ins32, P.Asm32, [], opName, revOp>;
1134
1135  defm _e64 : VOP3SI_2_m <op, P.Outs, P.Ins64, opName#"_e64"#P.Asm64,
1136    !if(P.HasModifiers,
1137        [(set P.DstVT:$dst,
1138             (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1139                                        i1:$clamp, i32:$omod)),
1140                   (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1141        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1142    opName, revOp, P.HasModifiers>;
1143}
1144
1145multiclass VOP2b_Helper <vop2 op, string opName, dag outs,
1146                         dag ins32, string asm32, list<dag> pat32,
1147                         dag ins64, string asm64, list<dag> pat64,
1148                         string revOp, bit HasMods> {
1149
1150  defm _e32 : VOP2_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1151
1152  defm _e64 : VOP3b_2_m <op,
1153    outs, ins64, opName#"_e64"#asm64, pat64, opName, revOp, HasMods
1154  >;
1155}
1156
1157multiclass VOP2bInst <vop2 op, string opName, VOPProfile P,
1158                      SDPatternOperator node = null_frag,
1159                      string revOp = opName> : VOP2b_Helper <
1160  op, opName, P.Outs,
1161  P.Ins32, P.Asm32, [],
1162  P.Ins64, P.Asm64,
1163  !if(P.HasModifiers,
1164      [(set P.DstVT:$dst,
1165           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1166                                      i1:$clamp, i32:$omod)),
1167                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1168      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1169  revOp, P.HasModifiers
1170>;
1171
1172// A VOP2 instruction that is VOP3-only on VI.
1173multiclass VOP2_VI3_Helper <vop23 op, string opName, dag outs,
1174                            dag ins32, string asm32, list<dag> pat32,
1175                            dag ins64, string asm64, list<dag> pat64,
1176                            string revOp, bit HasMods> {
1177  defm _e32 : VOP2SI_m <op, outs, ins32, asm32, pat32, opName, revOp>;
1178
1179  defm _e64 : VOP3_2_m <op, outs, ins64, opName#"_e64"#asm64, pat64, opName,
1180                        revOp, HasMods>;
1181}
1182
1183multiclass VOP2_VI3_Inst <vop23 op, string opName, VOPProfile P,
1184                          SDPatternOperator node = null_frag,
1185                          string revOp = opName>
1186                          : VOP2_VI3_Helper <
1187  op, opName, P.Outs,
1188  P.Ins32, P.Asm32, [],
1189  P.Ins64, P.Asm64,
1190  !if(P.HasModifiers,
1191      [(set P.DstVT:$dst,
1192           (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1193                                      i1:$clamp, i32:$omod)),
1194                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1195      [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))]),
1196  revOp, P.HasModifiers
1197>;
1198
1199multiclass VOP2MADK <vop2 op, string opName, list<dag> pattern = []> {
1200
1201  def "" : VOP2_Pseudo <VOP_MADK.Outs, VOP_MADK.Ins, pattern, opName>;
1202
1203let isCodeGenOnly = 0 in {
1204  def _si : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1205                        !strconcat(opName, VOP_MADK.Asm), []>,
1206            SIMCInstr <opName#"_e32", SISubtarget.SI>,
1207            VOP2_MADKe <op.SI>;
1208
1209  def _vi : VOP2Common <VOP_MADK.Outs, VOP_MADK.Ins,
1210                        !strconcat(opName, VOP_MADK.Asm), []>,
1211            SIMCInstr <opName#"_e32", SISubtarget.VI>,
1212            VOP2_MADKe <op.VI>;
1213} // End isCodeGenOnly = 0
1214}
1215
1216class VOPC_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
1217  VOPCCommon <ins, "", pattern>,
1218  VOP <opName>,
1219  SIMCInstr<opName#"_e32", SISubtarget.NONE> {
1220  let isPseudo = 1;
1221}
1222
1223multiclass VOPC_m <vopc op, dag outs, dag ins, string asm, list<dag> pattern,
1224                   string opName, bit DefExec> {
1225  def "" : VOPC_Pseudo <outs, ins, pattern, opName>;
1226
1227  def _si : VOPC<op.SI, ins, asm, []>,
1228            SIMCInstr <opName#"_e32", SISubtarget.SI> {
1229    let Defs = !if(DefExec, [EXEC], []);
1230  }
1231
1232  def _vi : VOPC<op.VI, ins, asm, []>,
1233            SIMCInstr <opName#"_e32", SISubtarget.VI> {
1234    let Defs = !if(DefExec, [EXEC], []);
1235  }
1236}
1237
1238multiclass VOPC_Helper <vopc op, string opName,
1239                        dag ins32, string asm32, list<dag> pat32,
1240                        dag out64, dag ins64, string asm64, list<dag> pat64,
1241                        bit HasMods, bit DefExec> {
1242  defm _e32 : VOPC_m <op, (outs), ins32, opName#asm32, pat32, opName, DefExec>;
1243
1244  defm _e64 : VOP3_C_m <op, out64, ins64, opName#"_e64"#asm64, pat64,
1245                        opName, HasMods, DefExec>;
1246}
1247
1248multiclass VOPCInst <vopc op, string opName,
1249                     VOPProfile P, PatLeaf cond = COND_NULL,
1250                     bit DefExec = 0> : VOPC_Helper <
1251  op, opName,
1252  P.Ins32, P.Asm32, [],
1253  (outs SReg_64:$dst), P.Ins64, P.Asm64,
1254  !if(P.HasModifiers,
1255      [(set i1:$dst,
1256          (setcc (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1257                                      i1:$clamp, i32:$omod)),
1258                 (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1259                 cond))],
1260      [(set i1:$dst, (setcc P.Src0VT:$src0, P.Src1VT:$src1, cond))]),
1261  P.HasModifiers, DefExec
1262>;
1263
1264multiclass VOPCClassInst <vopc op, string opName, VOPProfile P,
1265                     bit DefExec = 0> : VOPC_Helper <
1266  op, opName,
1267  P.Ins32, P.Asm32, [],
1268  (outs SReg_64:$dst), P.Ins64, P.Asm64,
1269  !if(P.HasModifiers,
1270      [(set i1:$dst,
1271          (AMDGPUfp_class (P.Src0VT (VOP3Mods0Clamp0OMod P.Src0VT:$src0, i32:$src0_modifiers)), P.Src1VT:$src1))],
1272      [(set i1:$dst, (AMDGPUfp_class P.Src0VT:$src0, P.Src1VT:$src1))]),
1273  P.HasModifiers, DefExec
1274>;
1275
1276
1277multiclass VOPC_F32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1278  VOPCInst <op, opName, VOP_F32_F32_F32, cond>;
1279
1280multiclass VOPC_F64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1281  VOPCInst <op, opName, VOP_F64_F64_F64, cond>;
1282
1283multiclass VOPC_I32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1284  VOPCInst <op, opName, VOP_I32_I32_I32, cond>;
1285
1286multiclass VOPC_I64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1287  VOPCInst <op, opName, VOP_I64_I64_I64, cond>;
1288
1289
1290multiclass VOPCX <vopc op, string opName, VOPProfile P,
1291                  PatLeaf cond = COND_NULL>
1292  : VOPCInst <op, opName, P, cond, 1>;
1293
1294multiclass VOPCX_F32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1295  VOPCX <op, opName, VOP_F32_F32_F32, cond>;
1296
1297multiclass VOPCX_F64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1298  VOPCX <op, opName, VOP_F64_F64_F64, cond>;
1299
1300multiclass VOPCX_I32 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1301  VOPCX <op, opName, VOP_I32_I32_I32, cond>;
1302
1303multiclass VOPCX_I64 <vopc op, string opName, PatLeaf cond = COND_NULL> :
1304  VOPCX <op, opName, VOP_I64_I64_I64, cond>;
1305
1306multiclass VOP3_Helper <vop3 op, string opName, dag outs, dag ins, string asm,
1307                        list<dag> pat, int NumSrcArgs, bit HasMods> : VOP3_m <
1308    op, outs, ins, opName#asm, pat, opName, NumSrcArgs, HasMods
1309>;
1310
1311multiclass VOPC_CLASS_F32 <vopc op, string opName> :
1312  VOPCClassInst <op, opName, VOP_I1_F32_I32, 0>;
1313
1314multiclass VOPCX_CLASS_F32 <vopc op, string opName> :
1315  VOPCClassInst <op, opName, VOP_I1_F32_I32, 1>;
1316
1317multiclass VOPC_CLASS_F64 <vopc op, string opName> :
1318  VOPCClassInst <op, opName, VOP_I1_F64_I32, 0>;
1319
1320multiclass VOPCX_CLASS_F64 <vopc op, string opName> :
1321  VOPCClassInst <op, opName, VOP_I1_F64_I32, 1>;
1322
1323multiclass VOP3Inst <vop3 op, string opName, VOPProfile P,
1324                     SDPatternOperator node = null_frag> : VOP3_Helper <
1325  op, opName, P.Outs, P.Ins64, P.Asm64,
1326  !if(!eq(P.NumSrcArgs, 3),
1327    !if(P.HasModifiers,
1328        [(set P.DstVT:$dst,
1329            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1330                                       i1:$clamp, i32:$omod)),
1331                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1332                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))))],
1333        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1,
1334                                  P.Src2VT:$src2))]),
1335  !if(!eq(P.NumSrcArgs, 2),
1336    !if(P.HasModifiers,
1337        [(set P.DstVT:$dst,
1338            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1339                                       i1:$clamp, i32:$omod)),
1340                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers))))],
1341        [(set P.DstVT:$dst, (node P.Src0VT:$src0, P.Src1VT:$src1))])
1342  /* P.NumSrcArgs == 1 */,
1343    !if(P.HasModifiers,
1344        [(set P.DstVT:$dst,
1345            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1346                                       i1:$clamp, i32:$omod))))],
1347        [(set P.DstVT:$dst, (node P.Src0VT:$src0))]))),
1348  P.NumSrcArgs, P.HasModifiers
1349>;
1350
1351// Special case for v_div_fmas_{f32|f64}, since it seems to be the
1352// only VOP instruction that implicitly reads VCC.
1353multiclass VOP3_VCC_Inst <vop3 op, string opName,
1354                          VOPProfile P,
1355                          SDPatternOperator node = null_frag> : VOP3_Helper <
1356  op, opName,
1357  P.Outs,
1358  (ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
1359       InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
1360       InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
1361       ClampMod:$clamp,
1362       omod:$omod),
1363  " $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
1364  [(set P.DstVT:$dst,
1365            (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers,
1366                                       i1:$clamp, i32:$omod)),
1367                  (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1368                  (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers)),
1369                  (i1 VCC)))],
1370  3, 1
1371>;
1372
1373multiclass VOP3b_Helper <vop op, RegisterClass vrc, RegisterOperand arc,
1374                    string opName, list<dag> pattern> :
1375  VOP3b_3_m <
1376  op, (outs vrc:$vdst, SReg_64:$sdst),
1377      (ins InputModsNoDefault:$src0_modifiers, arc:$src0,
1378           InputModsNoDefault:$src1_modifiers, arc:$src1,
1379           InputModsNoDefault:$src2_modifiers, arc:$src2,
1380           ClampMod:$clamp, omod:$omod),
1381  opName#" $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod", pattern,
1382  opName, opName, 1, 1
1383>;
1384
1385multiclass VOP3b_64 <vop3 op, string opName, list<dag> pattern> :
1386  VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
1387
1388multiclass VOP3b_32 <vop3 op, string opName, list<dag> pattern> :
1389  VOP3b_Helper <op, VGPR_32, VSrc_32, opName, pattern>;
1390
1391
1392class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat<
1393  (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omod)),
1394        (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)),
1395        (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))),
1396  (Inst i32:$src0_modifiers, P.Src0VT:$src0,
1397        i32:$src1_modifiers, P.Src1VT:$src1,
1398        i32:$src2_modifiers, P.Src2VT:$src2,
1399        i1:$clamp,
1400        i32:$omod)>;
1401
1402//===----------------------------------------------------------------------===//
1403// Interpolation opcodes
1404//===----------------------------------------------------------------------===//
1405
1406class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1407  VINTRPCommon <outs, ins, "", pattern>,
1408  SIMCInstr<opName, SISubtarget.NONE> {
1409  let isPseudo = 1;
1410}
1411
1412class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1413                      string asm> :
1414  VINTRPCommon <outs, ins, asm, []>,
1415  VINTRPe <op>,
1416  SIMCInstr<opName, SISubtarget.SI>;
1417
1418class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1419                      string asm> :
1420  VINTRPCommon <outs, ins, asm, []>,
1421  VINTRPe_vi <op>,
1422  SIMCInstr<opName, SISubtarget.VI>;
1423
1424multiclass VINTRP_m <bits <2> op, string opName, dag outs, dag ins, string asm,
1425                     string disableEncoding = "", string constraints = "",
1426                     list<dag> pattern = []> {
1427  let DisableEncoding = disableEncoding,
1428      Constraints = constraints in {
1429    def "" : VINTRP_Pseudo <opName, outs, ins, pattern>;
1430
1431    def _si : VINTRP_Real_si <op, opName, outs, ins, asm>;
1432
1433    def _vi : VINTRP_Real_vi <op, opName, outs, ins, asm>;
1434  }
1435}
1436
1437//===----------------------------------------------------------------------===//
1438// Vector I/O classes
1439//===----------------------------------------------------------------------===//
1440
1441class DS_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1442  DS <outs, ins, "", pattern>,
1443  SIMCInstr <opName, SISubtarget.NONE> {
1444  let isPseudo = 1;
1445}
1446
1447class DS_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1448  DS <outs, ins, asm, []>,
1449  DSe <op>,
1450  SIMCInstr <opName, SISubtarget.SI>;
1451
1452class DS_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1453  DS <outs, ins, asm, []>,
1454  DSe_vi <op>,
1455  SIMCInstr <opName, SISubtarget.VI>;
1456
1457class DS_1A_Real_si <bits<8> op, string opName, dag outs, dag ins, string asm> :
1458  DS <outs, ins, asm, []>,
1459  DSe <op>,
1460  SIMCInstr <opName, SISubtarget.SI> {
1461
1462  // Single load interpret the 2 i8imm operands as a single i16 offset.
1463  bits<16> offset;
1464  let offset0 = offset{7-0};
1465  let offset1 = offset{15-8};
1466}
1467
1468class DS_1A_Real_vi <bits<8> op, string opName, dag outs, dag ins, string asm> :
1469  DS <outs, ins, asm, []>,
1470  DSe_vi <op>,
1471  SIMCInstr <opName, SISubtarget.VI> {
1472
1473  // Single load interpret the 2 i8imm operands as a single i16 offset.
1474  bits<16> offset;
1475  let offset0 = offset{7-0};
1476  let offset1 = offset{15-8};
1477}
1478
1479multiclass DS_1A_Load_m <bits<8> op, string opName, dag outs, dag ins, string asm,
1480                         list<dag> pat> {
1481  let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
1482    def "" : DS_Pseudo <opName, outs, ins, pat>;
1483
1484    let data0 = 0, data1 = 0 in {
1485      def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1486      def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1487    }
1488  }
1489}
1490
1491multiclass DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass>
1492    : DS_1A_Load_m <
1493  op,
1494  asm,
1495  (outs regClass:$vdst),
1496  (ins i1imm:$gds, VGPR_32:$addr, ds_offset:$offset, M0Reg:$m0),
1497  asm#" $vdst, $addr"#"$offset"#" [M0]",
1498  []>;
1499
1500multiclass DS_Load2_m <bits<8> op, string opName, dag outs, dag ins, string asm,
1501                       list<dag> pat> {
1502  let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
1503    def "" : DS_Pseudo <opName, outs, ins, pat>;
1504
1505    let data0 = 0, data1 = 0 in {
1506      def _si : DS_Real_si <op, opName, outs, ins, asm>;
1507      def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1508    }
1509  }
1510}
1511
1512multiclass DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass>
1513    : DS_Load2_m <
1514  op,
1515  asm,
1516  (outs regClass:$vdst),
1517  (ins i1imm:$gds, VGPR_32:$addr, ds_offset0:$offset0, ds_offset1:$offset1,
1518        M0Reg:$m0),
1519  asm#" $vdst, $addr"#"$offset0"#"$offset1 [M0]",
1520  []>;
1521
1522multiclass DS_1A_Store_m <bits<8> op, string opName, dag outs, dag ins,
1523                          string asm, list<dag> pat> {
1524  let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
1525    def "" : DS_Pseudo <opName, outs, ins, pat>;
1526
1527    let data1 = 0, vdst = 0 in {
1528      def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1529      def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1530    }
1531  }
1532}
1533
1534multiclass DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass>
1535    : DS_1A_Store_m <
1536  op,
1537  asm,
1538  (outs),
1539  (ins i1imm:$gds, VGPR_32:$addr, regClass:$data0, ds_offset:$offset, M0Reg:$m0),
1540  asm#" $addr, $data0"#"$offset"#" [M0]",
1541  []>;
1542
1543multiclass DS_Store_m <bits<8> op, string opName, dag outs, dag ins,
1544                       string asm, list<dag> pat> {
1545  let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
1546    def "" : DS_Pseudo <opName, outs, ins, pat>;
1547
1548    let vdst = 0 in {
1549      def _si : DS_Real_si <op, opName, outs, ins, asm>;
1550      def _vi : DS_Real_vi <op, opName, outs, ins, asm>;
1551    }
1552  }
1553}
1554
1555multiclass DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass>
1556    : DS_Store_m <
1557  op,
1558  asm,
1559  (outs),
1560  (ins i1imm:$gds, VGPR_32:$addr, regClass:$data0, regClass:$data1,
1561       ds_offset0:$offset0, ds_offset1:$offset1, M0Reg:$m0),
1562  asm#" $addr, $data0, $data1"#"$offset0"#"$offset1 [M0]",
1563  []>;
1564
1565// 1 address, 1 data.
1566multiclass DS_1A1D_RET_m <bits<8> op, string opName, dag outs, dag ins,
1567                          string asm, list<dag> pat, string noRetOp> {
1568  let mayLoad = 1, mayStore = 1,
1569      hasPostISelHook = 1 // Adjusted to no return version.
1570      in {
1571    def "" : DS_Pseudo <opName, outs, ins, pat>,
1572             AtomicNoRet<noRetOp, 1>;
1573
1574    let data1 = 0 in {
1575      def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1576      def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1577    }
1578  }
1579}
1580
1581multiclass DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc,
1582                        string noRetOp = ""> : DS_1A1D_RET_m <
1583  op, asm,
1584  (outs rc:$vdst),
1585  (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, ds_offset:$offset, M0Reg:$m0),
1586  asm#" $vdst, $addr, $data0"#"$offset"#" [M0]", [], noRetOp>;
1587
1588// 1 address, 2 data.
1589multiclass DS_1A2D_RET_m <bits<8> op, string opName, dag outs, dag ins,
1590                          string asm, list<dag> pat, string noRetOp> {
1591  let mayLoad = 1, mayStore = 1,
1592      hasPostISelHook = 1 // Adjusted to no return version.
1593      in {
1594    def "" : DS_Pseudo <opName, outs, ins, pat>,
1595             AtomicNoRet<noRetOp, 1>;
1596
1597    def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1598    def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1599  }
1600}
1601
1602multiclass DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc,
1603                   string noRetOp = ""> : DS_1A2D_RET_m <
1604  op, asm,
1605  (outs rc:$vdst),
1606  (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, rc:$data1, ds_offset:$offset, M0Reg:$m0),
1607  asm#" $vdst, $addr, $data0, $data1"#"$offset"#" [M0]",
1608  [], noRetOp>;
1609
1610// 1 address, 2 data.
1611multiclass DS_1A2D_NORET_m <bits<8> op, string opName, dag outs, dag ins,
1612                            string asm, list<dag> pat, string noRetOp> {
1613  let mayLoad = 1, mayStore = 1 in {
1614    def "" : DS_Pseudo <opName, outs, ins, pat>,
1615             AtomicNoRet<noRetOp, 0>;
1616
1617    def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1618    def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1619  }
1620}
1621
1622multiclass DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc,
1623                     string noRetOp = asm> : DS_1A2D_NORET_m <
1624  op, asm,
1625  (outs),
1626  (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, rc:$data1, ds_offset:$offset, M0Reg:$m0),
1627  asm#" $addr, $data0, $data1"#"$offset"#" [M0]",
1628  [], noRetOp>;
1629
1630// 1 address, 1 data.
1631multiclass DS_1A1D_NORET_m <bits<8> op, string opName, dag outs, dag ins,
1632                            string asm, list<dag> pat, string noRetOp> {
1633  let mayLoad = 1, mayStore = 1 in {
1634    def "" : DS_Pseudo <opName, outs, ins, pat>,
1635             AtomicNoRet<noRetOp, 0>;
1636
1637    let data1 = 0 in {
1638      def _si : DS_1A_Real_si <op, opName, outs, ins, asm>;
1639      def _vi : DS_1A_Real_vi <op, opName, outs, ins, asm>;
1640    }
1641  }
1642}
1643
1644multiclass DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc,
1645                          string noRetOp = asm> : DS_1A1D_NORET_m <
1646  op, asm,
1647  (outs),
1648  (ins i1imm:$gds, VGPR_32:$addr, rc:$data0, ds_offset:$offset, M0Reg:$m0),
1649  asm#" $addr, $data0"#"$offset"#" [M0]",
1650  [], noRetOp>;
1651
1652//===----------------------------------------------------------------------===//
1653// MTBUF classes
1654//===----------------------------------------------------------------------===//
1655
1656class MTBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1657  MTBUF <outs, ins, "", pattern>,
1658  SIMCInstr<opName, SISubtarget.NONE> {
1659  let isPseudo = 1;
1660}
1661
1662class MTBUF_Real_si <bits<3> op, string opName, dag outs, dag ins,
1663                    string asm> :
1664  MTBUF <outs, ins, asm, []>,
1665  MTBUFe <op>,
1666  SIMCInstr<opName, SISubtarget.SI>;
1667
1668class MTBUF_Real_vi <bits<4> op, string opName, dag outs, dag ins, string asm> :
1669  MTBUF <outs, ins, asm, []>,
1670  MTBUFe_vi <op>,
1671  SIMCInstr <opName, SISubtarget.VI>;
1672
1673multiclass MTBUF_m <bits<3> op, string opName, dag outs, dag ins, string asm,
1674                    list<dag> pattern> {
1675
1676  def "" : MTBUF_Pseudo <opName, outs, ins, pattern>;
1677
1678  def _si : MTBUF_Real_si <op, opName, outs, ins, asm>;
1679
1680  def _vi : MTBUF_Real_vi <{0, op{2}, op{1}, op{0}}, opName, outs, ins, asm>;
1681
1682}
1683
1684let mayStore = 1, mayLoad = 0 in {
1685
1686multiclass MTBUF_Store_Helper <bits<3> op, string opName,
1687                               RegisterClass regClass> : MTBUF_m <
1688  op, opName, (outs),
1689  (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
1690   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr,
1691   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
1692  opName#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1693        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1694>;
1695
1696} // mayStore = 1, mayLoad = 0
1697
1698let mayLoad = 1, mayStore = 0 in {
1699
1700multiclass MTBUF_Load_Helper <bits<3> op, string opName,
1701                              RegisterClass regClass> : MTBUF_m <
1702  op, opName, (outs regClass:$dst),
1703  (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
1704       i8imm:$dfmt, i8imm:$nfmt, VGPR_32:$vaddr, SReg_128:$srsrc,
1705       i1imm:$slc, i1imm:$tfe, SCSrc_32:$soffset),
1706  opName#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
1707        #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset", []
1708>;
1709
1710} // mayLoad = 1, mayStore = 0
1711
1712//===----------------------------------------------------------------------===//
1713// MUBUF classes
1714//===----------------------------------------------------------------------===//
1715
1716class mubuf <bits<7> si, bits<7> vi = si> {
1717  field bits<7> SI = si;
1718  field bits<7> VI = vi;
1719}
1720
1721class MUBUFAddr64Table <bit is_addr64, string suffix = ""> {
1722  bit IsAddr64 = is_addr64;
1723  string OpName = NAME # suffix;
1724}
1725
1726class MUBUF_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1727  MUBUF <outs, ins, "", pattern>,
1728  SIMCInstr<opName, SISubtarget.NONE> {
1729  let isPseudo = 1;
1730
1731  // dummy fields, so that we can use let statements around multiclasses
1732  bits<1> offen;
1733  bits<1> idxen;
1734  bits<8> vaddr;
1735  bits<1> glc;
1736  bits<1> slc;
1737  bits<1> tfe;
1738  bits<8> soffset;
1739}
1740
1741class MUBUF_Real_si <mubuf op, string opName, dag outs, dag ins,
1742                     string asm> :
1743  MUBUF <outs, ins, asm, []>,
1744  MUBUFe <op.SI>,
1745  SIMCInstr<opName, SISubtarget.SI> {
1746  let lds = 0;
1747}
1748
1749class MUBUF_Real_vi <mubuf op, string opName, dag outs, dag ins,
1750                     string asm> :
1751  MUBUF <outs, ins, asm, []>,
1752  MUBUFe_vi <op.VI>,
1753  SIMCInstr<opName, SISubtarget.VI> {
1754  let lds = 0;
1755}
1756
1757multiclass MUBUF_m <mubuf op, string opName, dag outs, dag ins, string asm,
1758                    list<dag> pattern> {
1759
1760  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
1761           MUBUFAddr64Table <0>;
1762
1763  let addr64 = 0 in {
1764    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
1765  }
1766
1767  def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
1768}
1769
1770multiclass MUBUFAddr64_m <mubuf op, string opName, dag outs,
1771                          dag ins, string asm, list<dag> pattern> {
1772
1773  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
1774           MUBUFAddr64Table <1>;
1775
1776  let addr64 = 1 in {
1777    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
1778  }
1779
1780  // There is no VI version. If the pseudo is selected, it should be lowered
1781  // for VI appropriately.
1782}
1783
1784class MUBUF_si <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
1785  MUBUF <outs, ins, asm, pattern>, MUBUFe <op> {
1786  let lds = 0;
1787}
1788
1789multiclass MUBUFAtomicOffset_m <mubuf op, string opName, dag outs, dag ins,
1790                                string asm, list<dag> pattern, bit is_return> {
1791
1792  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
1793           MUBUFAddr64Table <0, !if(is_return, "_RTN", "")>,
1794           AtomicNoRet<NAME#"_OFFSET", is_return>;
1795
1796  let offen = 0, idxen = 0, tfe = 0, vaddr = 0 in {
1797    let addr64 = 0 in {
1798      def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
1799    }
1800
1801    def _vi : MUBUF_Real_vi <op, opName, outs, ins, asm>;
1802  }
1803}
1804
1805multiclass MUBUFAtomicAddr64_m <mubuf op, string opName, dag outs, dag ins,
1806                                string asm, list<dag> pattern, bit is_return> {
1807
1808  def "" : MUBUF_Pseudo <opName, outs, ins, pattern>,
1809           MUBUFAddr64Table <1, !if(is_return, "_RTN", "")>,
1810           AtomicNoRet<NAME#"_ADDR64", is_return>;
1811
1812  let offen = 0, idxen = 0, addr64 = 1, tfe = 0, soffset = 128 in {
1813    def _si : MUBUF_Real_si <op, opName, outs, ins, asm>;
1814  }
1815
1816  // There is no VI version. If the pseudo is selected, it should be lowered
1817  // for VI appropriately.
1818}
1819
1820multiclass MUBUF_Atomic <mubuf op, string name, RegisterClass rc,
1821                         ValueType vt, SDPatternOperator atomic> {
1822
1823  let mayStore = 1, mayLoad = 1, hasPostISelHook = 1 in {
1824
1825    // No return variants
1826    let glc = 0 in {
1827
1828      defm _ADDR64 : MUBUFAtomicAddr64_m <
1829        op, name#"_addr64", (outs),
1830        (ins rc:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
1831             mbuf_offset:$offset, slc:$slc),
1832        name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#"$slc", [], 0
1833      >;
1834
1835      defm _OFFSET : MUBUFAtomicOffset_m <
1836        op, name#"_offset", (outs),
1837        (ins rc:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1838             SCSrc_32:$soffset, slc:$slc),
1839        name#" $vdata, $srsrc, $soffset"#"$offset"#"$slc", [], 0
1840      >;
1841    } // glc = 0
1842
1843    // Variant that return values
1844    let glc = 1, Constraints = "$vdata = $vdata_in",
1845        DisableEncoding = "$vdata_in"  in {
1846
1847      defm _RTN_ADDR64 : MUBUFAtomicAddr64_m <
1848        op, name#"_rtn_addr64", (outs rc:$vdata),
1849        (ins rc:$vdata_in, SReg_128:$srsrc, VReg_64:$vaddr,
1850             mbuf_offset:$offset, slc:$slc),
1851        name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset"#" glc"#"$slc",
1852        [(set vt:$vdata,
1853         (atomic (MUBUFAddr64Atomic v4i32:$srsrc, i64:$vaddr, i16:$offset,
1854                                    i1:$slc), vt:$vdata_in))], 1
1855      >;
1856
1857      defm _RTN_OFFSET : MUBUFAtomicOffset_m <
1858        op, name#"_rtn_offset", (outs rc:$vdata),
1859        (ins rc:$vdata_in, SReg_128:$srsrc, mbuf_offset:$offset,
1860             SCSrc_32:$soffset, slc:$slc),
1861        name#" $vdata, $srsrc, $soffset"#"$offset"#" glc $slc",
1862        [(set vt:$vdata,
1863         (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset,
1864                                    i1:$slc), vt:$vdata_in))], 1
1865      >;
1866
1867    } // glc = 1
1868
1869  } // mayStore = 1, mayLoad = 1, hasPostISelHook = 1
1870}
1871
1872multiclass MUBUF_Load_Helper <mubuf op, string name, RegisterClass regClass,
1873                              ValueType load_vt = i32,
1874                              SDPatternOperator ld = null_frag> {
1875
1876  let mayLoad = 1, mayStore = 0 in {
1877    let offen = 0, idxen = 0, vaddr = 0 in {
1878      defm _OFFSET : MUBUF_m <op, name#"_offset", (outs regClass:$vdata),
1879                           (ins SReg_128:$srsrc,
1880                           mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1881                           slc:$slc, tfe:$tfe),
1882                           name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1883                           [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc,
1884                                                     i32:$soffset, i16:$offset,
1885                                                     i1:$glc, i1:$slc, i1:$tfe)))]>;
1886    }
1887
1888    let offen = 1, idxen = 0  in {
1889      defm _OFFEN  : MUBUF_m <op, name#"_offen", (outs regClass:$vdata),
1890                           (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1891                           SCSrc_32:$soffset, mbuf_offset:$offset, glc:$glc, slc:$slc,
1892                           tfe:$tfe),
1893                           name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1894    }
1895
1896    let offen = 0, idxen = 1 in {
1897      defm _IDXEN  : MUBUF_m <op, name#"_idxen", (outs regClass:$vdata),
1898                           (ins SReg_128:$srsrc, VGPR_32:$vaddr,
1899                           mbuf_offset:$offset, SCSrc_32:$soffset, glc:$glc,
1900                           slc:$slc, tfe:$tfe),
1901                           name#" $vdata, $vaddr, $srsrc, $soffset idxen"#"$offset"#"$glc"#"$slc"#"$tfe", []>;
1902    }
1903
1904    let offen = 1, idxen = 1 in {
1905      defm _BOTHEN : MUBUF_m <op, name#"_bothen", (outs regClass:$vdata),
1906                           (ins SReg_128:$srsrc, VReg_64:$vaddr,
1907                           SCSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1908                           name#" $vdata, $vaddr, $srsrc, $soffset, idxen offen"#"$glc"#"$slc"#"$tfe", []>;
1909    }
1910
1911    let offen = 0, idxen = 0, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
1912      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs regClass:$vdata),
1913                           (ins SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1914                           name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1915                           [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
1916                                                  i64:$vaddr, i16:$offset)))]>;
1917    }
1918  }
1919}
1920
1921multiclass MUBUF_Store_Helper <mubuf op, string name, RegisterClass vdataClass,
1922                          ValueType store_vt, SDPatternOperator st> {
1923  let mayLoad = 0, mayStore = 1 in {
1924    defm : MUBUF_m <op, name, (outs),
1925                    (ins vdataClass:$vdata, SReg_128:$srsrc, VGPR_32:$vaddr, SCSrc_32:$soffset,
1926                    mbuf_offset:$offset, offen:$offen, idxen:$idxen, glc:$glc, slc:$slc,
1927                    tfe:$tfe),
1928                    name#" $vdata, $vaddr, $srsrc, $soffset"#"$offen"#"$idxen"#"$offset"#
1929                    "$glc"#"$slc"#"$tfe", []>;
1930
1931    let offen = 0, idxen = 0, vaddr = 0 in {
1932      defm _OFFSET : MUBUF_m <op, name#"_offset",(outs),
1933                              (ins vdataClass:$vdata, SReg_128:$srsrc, mbuf_offset:$offset,
1934                              SCSrc_32:$soffset, glc:$glc, slc:$slc, tfe:$tfe),
1935                              name#" $vdata, $srsrc, $soffset"#"$offset"#"$glc"#"$slc"#"$tfe",
1936                              [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset,
1937                                   i16:$offset, i1:$glc, i1:$slc, i1:$tfe))]>;
1938    } // offen = 0, idxen = 0, vaddr = 0
1939
1940    let offen = 1, idxen = 0  in {
1941      defm _OFFEN : MUBUF_m <op, name#"_offen", (outs),
1942                             (ins vdataClass:$vdata, SReg_128:$srsrc, VGPR_32:$vaddr, SCSrc_32:$soffset,
1943                             mbuf_offset:$offset, glc:$glc, slc:$slc, tfe:$tfe),
1944                             name#" $vdata, $vaddr, $srsrc, $soffset offen"#"$offset"#
1945                             "$glc"#"$slc"#"$tfe", []>;
1946    } // end offen = 1, idxen = 0
1947
1948    let offen = 0, idxen = 0, glc = 0, slc = 0, tfe = 0,
1949        soffset = 128 /* ZERO */ in {
1950      defm _ADDR64 : MUBUFAddr64_m <op, name#"_addr64", (outs),
1951                                    (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, mbuf_offset:$offset),
1952                                    name#" $vdata, $vaddr, $srsrc, 0 addr64"#"$offset",
1953                                    [(st store_vt:$vdata,
1954                                      (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, i16:$offset))]>;
1955    }
1956  } // End mayLoad = 0, mayStore = 1
1957}
1958
1959class FLAT_Load_Helper <bits<7> op, string asm, RegisterClass regClass> :
1960      FLAT <op, (outs regClass:$data),
1961                (ins VReg_64:$addr),
1962            asm#" $data, $addr, [M0, FLAT_SCRATCH]", []> {
1963  let glc = 0;
1964  let slc = 0;
1965  let tfe = 0;
1966  let mayLoad = 1;
1967}
1968
1969class FLAT_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
1970      FLAT <op, (outs), (ins vdataClass:$data, VReg_64:$addr),
1971          name#" $data, $addr, [M0, FLAT_SCRATCH]",
1972         []> {
1973
1974  let mayLoad = 0;
1975  let mayStore = 1;
1976
1977  // Encoding
1978  let glc = 0;
1979  let slc = 0;
1980  let tfe = 0;
1981}
1982
1983class MIMG_Mask <string op, int channels> {
1984  string Op = op;
1985  int Channels = channels;
1986}
1987
1988class MIMG_NoSampler_Helper <bits<7> op, string asm,
1989                             RegisterClass dst_rc,
1990                             RegisterClass src_rc> : MIMG <
1991  op,
1992  (outs dst_rc:$vdata),
1993  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
1994       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
1995       SReg_256:$srsrc),
1996  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
1997     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
1998  []> {
1999  let SSAMP = 0;
2000  let mayLoad = 1;
2001  let mayStore = 0;
2002  let hasPostISelHook = 1;
2003}
2004
2005multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
2006                                      RegisterClass dst_rc,
2007                                      int channels> {
2008  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VGPR_32>,
2009            MIMG_Mask<asm#"_V1", channels>;
2010  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
2011            MIMG_Mask<asm#"_V2", channels>;
2012  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
2013            MIMG_Mask<asm#"_V4", channels>;
2014}
2015
2016multiclass MIMG_NoSampler <bits<7> op, string asm> {
2017  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VGPR_32, 1>;
2018  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
2019  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
2020  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
2021}
2022
2023class MIMG_Sampler_Helper <bits<7> op, string asm,
2024                           RegisterClass dst_rc,
2025                           RegisterClass src_rc, int wqm> : MIMG <
2026  op,
2027  (outs dst_rc:$vdata),
2028  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2029       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2030       SReg_256:$srsrc, SReg_128:$ssamp),
2031  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2032     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2033  []> {
2034  let mayLoad = 1;
2035  let mayStore = 0;
2036  let hasPostISelHook = 1;
2037  let WQM = wqm;
2038}
2039
2040multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
2041                                    RegisterClass dst_rc,
2042                                    int channels, int wqm> {
2043  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2044            MIMG_Mask<asm#"_V1", channels>;
2045  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64, wqm>,
2046            MIMG_Mask<asm#"_V2", channels>;
2047  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128, wqm>,
2048            MIMG_Mask<asm#"_V4", channels>;
2049  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256, wqm>,
2050            MIMG_Mask<asm#"_V8", channels>;
2051  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512, wqm>,
2052            MIMG_Mask<asm#"_V16", channels>;
2053}
2054
2055multiclass MIMG_Sampler <bits<7> op, string asm> {
2056  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 0>;
2057  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 0>;
2058  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 0>;
2059  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 0>;
2060}
2061
2062multiclass MIMG_Sampler_WQM <bits<7> op, string asm> {
2063  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VGPR_32, 1, 1>;
2064  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2, 1>;
2065  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3, 1>;
2066  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4, 1>;
2067}
2068
2069class MIMG_Gather_Helper <bits<7> op, string asm,
2070                          RegisterClass dst_rc,
2071                          RegisterClass src_rc, int wqm> : MIMG <
2072  op,
2073  (outs dst_rc:$vdata),
2074  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
2075       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
2076       SReg_256:$srsrc, SReg_128:$ssamp),
2077  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
2078     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
2079  []> {
2080  let mayLoad = 1;
2081  let mayStore = 0;
2082
2083  // DMASK was repurposed for GATHER4. 4 components are always
2084  // returned and DMASK works like a swizzle - it selects
2085  // the component to fetch. The only useful DMASK values are
2086  // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
2087  // (red,red,red,red) etc.) The ISA document doesn't mention
2088  // this.
2089  // Therefore, disable all code which updates DMASK by setting these two:
2090  let MIMG = 0;
2091  let hasPostISelHook = 0;
2092  let WQM = wqm;
2093}
2094
2095multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
2096                                    RegisterClass dst_rc,
2097                                    int channels, int wqm> {
2098  def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VGPR_32, wqm>,
2099            MIMG_Mask<asm#"_V1", channels>;
2100  def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64, wqm>,
2101            MIMG_Mask<asm#"_V2", channels>;
2102  def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128, wqm>,
2103            MIMG_Mask<asm#"_V4", channels>;
2104  def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256, wqm>,
2105            MIMG_Mask<asm#"_V8", channels>;
2106  def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512, wqm>,
2107            MIMG_Mask<asm#"_V16", channels>;
2108}
2109
2110multiclass MIMG_Gather <bits<7> op, string asm> {
2111  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 0>;
2112  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 0>;
2113  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 0>;
2114  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 0>;
2115}
2116
2117multiclass MIMG_Gather_WQM <bits<7> op, string asm> {
2118  defm _V1 : MIMG_Gather_Src_Helper<op, asm, VGPR_32, 1, 1>;
2119  defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2, 1>;
2120  defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3, 1>;
2121  defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4, 1>;
2122}
2123
2124//===----------------------------------------------------------------------===//
2125// Vector instruction mappings
2126//===----------------------------------------------------------------------===//
2127
2128// Maps an opcode in e32 form to its e64 equivalent
2129def getVOPe64 : InstrMapping {
2130  let FilterClass = "VOP";
2131  let RowFields = ["OpName"];
2132  let ColFields = ["Size"];
2133  let KeyCol = ["4"];
2134  let ValueCols = [["8"]];
2135}
2136
2137// Maps an opcode in e64 form to its e32 equivalent
2138def getVOPe32 : InstrMapping {
2139  let FilterClass = "VOP";
2140  let RowFields = ["OpName"];
2141  let ColFields = ["Size"];
2142  let KeyCol = ["8"];
2143  let ValueCols = [["4"]];
2144}
2145
2146// Maps an original opcode to its commuted version
2147def getCommuteRev : InstrMapping {
2148  let FilterClass = "VOP2_REV";
2149  let RowFields = ["RevOp"];
2150  let ColFields = ["IsOrig"];
2151  let KeyCol = ["1"];
2152  let ValueCols = [["0"]];
2153}
2154
2155def getMaskedMIMGOp : InstrMapping {
2156  let FilterClass = "MIMG_Mask";
2157  let RowFields = ["Op"];
2158  let ColFields = ["Channels"];
2159  let KeyCol = ["4"];
2160  let ValueCols = [["1"], ["2"], ["3"] ];
2161}
2162
2163// Maps an commuted opcode to its original version
2164def getCommuteOrig : InstrMapping {
2165  let FilterClass = "VOP2_REV";
2166  let RowFields = ["RevOp"];
2167  let ColFields = ["IsOrig"];
2168  let KeyCol = ["0"];
2169  let ValueCols = [["1"]];
2170}
2171
2172def getMCOpcodeGen : InstrMapping {
2173  let FilterClass = "SIMCInstr";
2174  let RowFields = ["PseudoInstr"];
2175  let ColFields = ["Subtarget"];
2176  let KeyCol = [!cast<string>(SISubtarget.NONE)];
2177  let ValueCols = [[!cast<string>(SISubtarget.SI)],[!cast<string>(SISubtarget.VI)]];
2178}
2179
2180def getAddr64Inst : InstrMapping {
2181  let FilterClass = "MUBUFAddr64Table";
2182  let RowFields = ["OpName"];
2183  let ColFields = ["IsAddr64"];
2184  let KeyCol = ["0"];
2185  let ValueCols = [["1"]];
2186}
2187
2188// Maps an atomic opcode to its version with a return value.
2189def getAtomicRetOp : InstrMapping {
2190  let FilterClass = "AtomicNoRet";
2191  let RowFields = ["NoRetOp"];
2192  let ColFields = ["IsRet"];
2193  let KeyCol = ["0"];
2194  let ValueCols = [["1"]];
2195}
2196
2197// Maps an atomic opcode to its returnless version.
2198def getAtomicNoRetOp : InstrMapping {
2199  let FilterClass = "AtomicNoRet";
2200  let RowFields = ["NoRetOp"];
2201  let ColFields = ["IsRet"];
2202  let KeyCol = ["1"];
2203  let ValueCols = [["0"]];
2204}
2205
2206include "SIInstructions.td"
2207include "CIInstructions.td"
2208include "VIInstructions.td"
2209