SIInstrInfo.td revision 266715
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
10//===----------------------------------------------------------------------===//
11// SI DAG Nodes
12//===----------------------------------------------------------------------===//
13
14// SMRD takes a 64bit memory address and can only add an 32bit offset
15def SIadd64bit32bit : SDNode<"ISD::ADD",
16  SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
17>;
18
19def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
20  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, i128>, SDTCisVT<2, i32>]>,
21                      [SDNPMayLoad, SDNPMemOperand]
22>;
23
24def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
25  SDTypeProfile<0, 13,
26    [SDTCisVT<0, i128>,   // rsrc(SGPR)
27     SDTCisVT<1, iAny>,   // vdata(VGPR)
28     SDTCisVT<2, i32>,    // num_channels(imm)
29     SDTCisVT<3, i32>,    // vaddr(VGPR)
30     SDTCisVT<4, i32>,    // soffset(SGPR)
31     SDTCisVT<5, i32>,    // inst_offset(imm)
32     SDTCisVT<6, i32>,    // dfmt(imm)
33     SDTCisVT<7, i32>,    // nfmt(imm)
34     SDTCisVT<8, i32>,    // offen(imm)
35     SDTCisVT<9, i32>,    // idxen(imm)
36     SDTCisVT<10, i32>,   // glc(imm)
37     SDTCisVT<11, i32>,   // slc(imm)
38     SDTCisVT<12, i32>    // tfe(imm)
39    ]>,
40  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
41>;
42
43def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
44  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, i128>, SDTCisVT<2, i16>,
45                       SDTCisVT<3, i32>]>
46>;
47
48class SDSample<string opcode> : SDNode <opcode,
49  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
50                       SDTCisVT<3, i128>, SDTCisVT<4, i32>]>
51>;
52
53def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
54def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
55def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
56def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
57
58// Transformation function, extract the lower 32bit of a 64bit immediate
59def LO32 : SDNodeXForm<imm, [{
60  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
61}]>;
62
63def LO32f : SDNodeXForm<fpimm, [{
64  APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
65  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
66}]>;
67
68// Transformation function, extract the upper 32bit of a 64bit immediate
69def HI32 : SDNodeXForm<imm, [{
70  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
71}]>;
72
73def HI32f : SDNodeXForm<fpimm, [{
74  APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
75  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
76}]>;
77
78def IMM8bitDWORD : ImmLeaf <
79  i32, [{
80    return (Imm & ~0x3FC) == 0;
81  }], SDNodeXForm<imm, [{
82    return CurDAG->getTargetConstant(
83      N->getZExtValue() >> 2, MVT::i32);
84  }]>
85>;
86
87def as_i1imm : SDNodeXForm<imm, [{
88  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
89}]>;
90
91def as_i8imm : SDNodeXForm<imm, [{
92  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
93}]>;
94
95def as_i16imm : SDNodeXForm<imm, [{
96  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
97}]>;
98
99def IMM12bit : PatLeaf <(imm),
100  [{return isUInt<12>(N->getZExtValue());}]
101>;
102
103class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
104  return
105    (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
106}]>;
107
108class SGPRImm <dag frag> : PatLeaf<frag, [{
109  if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
110      AMDGPUSubtarget::SOUTHERN_ISLANDS) {
111    return false;
112  }
113  const SIRegisterInfo *SIRI =
114                       static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
115  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
116                                                U != E; ++U) {
117    if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
118      return true;
119    }
120  }
121  return false;
122}]>;
123
124def FRAMEri64 : Operand<iPTR> {
125  let MIOperandInfo = (ops SReg_32:$ptr, i32imm:$index);
126}
127
128//===----------------------------------------------------------------------===//
129// SI assembler operands
130//===----------------------------------------------------------------------===//
131
132def SIOperand {
133  int ZERO = 0x80;
134  int VCC = 0x6A;
135}
136
137include "SIInstrFormats.td"
138
139//===----------------------------------------------------------------------===//
140//
141// SI Instruction multiclass helpers.
142//
143// Instructions with _32 take 32-bit operands.
144// Instructions with _64 take 64-bit operands.
145//
146// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
147// encoding is the standard encoding, but instruction that make use of
148// any of the instruction modifiers must use the 64-bit encoding.
149//
150// Instructions with _e32 use the 32-bit encoding.
151// Instructions with _e64 use the 64-bit encoding.
152//
153//===----------------------------------------------------------------------===//
154
155//===----------------------------------------------------------------------===//
156// Scalar classes
157//===----------------------------------------------------------------------===//
158
159class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
160  op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
161  opName#" $dst, $src0", pattern
162>;
163
164class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
165  op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
166  opName#" $dst, $src0", pattern
167>;
168
169class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
170  op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
171  opName#" $dst, $src0, $src1", pattern
172>;
173
174class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
175  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
176  opName#" $dst, $src0, $src1", pattern
177>;
178
179class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
180  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
181  opName#" $dst, $src0, $src1", pattern
182>;
183
184class SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
185  op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
186  opName#" $dst, $src0, $src1", pattern
187>;
188
189class SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
190  op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
191  opName#" $dst, $src0, $src1", pattern
192>;
193
194class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
195  op, (outs SReg_32:$dst), (ins i16imm:$src0),
196  opName#" $dst, $src0", pattern
197>;
198
199class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
200  op, (outs SReg_64:$dst), (ins i16imm:$src0),
201  opName#" $dst, $src0", pattern
202>;
203
204multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
205                        RegisterClass dstClass> {
206  def _IMM : SMRD <
207    op, 1, (outs dstClass:$dst),
208    (ins baseClass:$sbase, i32imm:$offset),
209    asm#" $dst, $sbase, $offset", []
210  >;
211
212  def _SGPR : SMRD <
213    op, 0, (outs dstClass:$dst),
214    (ins baseClass:$sbase, SReg_32:$soff),
215    asm#" $dst, $sbase, $soff", []
216  >;
217}
218
219//===----------------------------------------------------------------------===//
220// Vector ALU classes
221//===----------------------------------------------------------------------===//
222
223class VOP <string opName> {
224  string OpName = opName;
225}
226
227class VOP2_REV <string revOp, bit isOrig> {
228  string RevOp = revOp;
229  bit IsOrig = isOrig;
230}
231
232multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
233                        string opName, list<dag> pattern> {
234
235  def _e32 : VOP1 <
236    op, (outs drc:$dst), (ins src:$src0),
237    opName#"_e32 $dst, $src0", pattern
238  >, VOP <opName>;
239
240  def _e64 : VOP3 <
241    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
242    (outs drc:$dst),
243    (ins src:$src0,
244         i32imm:$abs, i32imm:$clamp,
245         i32imm:$omod, i32imm:$neg),
246    opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
247  >, VOP <opName> {
248    let src1 = SIOperand.ZERO;
249    let src2 = SIOperand.ZERO;
250  }
251}
252
253multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
254  : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
255
256multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
257  : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
258
259multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
260  : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
261
262multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
263  : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
264
265multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
266                        string opName, list<dag> pattern, string revOp> {
267  def _e32 : VOP2 <
268    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
269    opName#"_e32 $dst, $src0, $src1", pattern
270  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
271
272  def _e64 : VOP3 <
273    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
274    (outs vrc:$dst),
275    (ins arc:$src0, arc:$src1,
276         i32imm:$abs, i32imm:$clamp,
277         i32imm:$omod, i32imm:$neg),
278    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
279  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
280    let src2 = SIOperand.ZERO;
281  }
282}
283
284multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
285                    string revOp = opName>
286  : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
287
288multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
289                    string revOp = opName>
290  : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
291
292multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
293                     RegisterClass src0_rc, string revOp = opName> {
294
295  def _e32 : VOP2 <
296    op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
297    opName#"_e32 $dst, $src0, $src1", pattern
298  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
299
300  def _e64 : VOP3b <
301    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
302    (outs VReg_32:$dst),
303    (ins VSrc_32:$src0, VSrc_32:$src1,
304         i32imm:$abs, i32imm:$clamp,
305         i32imm:$omod, i32imm:$neg),
306    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
307  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
308    let src2 = SIOperand.ZERO;
309    /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
310       can write it into any SGPR. We currently don't use the carry out,
311       so for now hardcode it to VCC as well */
312    let sdst = SIOperand.VCC;
313  }
314}
315
316multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
317                        string opName, ValueType vt, PatLeaf cond> {
318
319  def _e32 : VOPC <
320    op, (ins arc:$src0, vrc:$src1),
321    opName#"_e32 $dst, $src0, $src1", []
322  >, VOP <opName>;
323
324  def _e64 : VOP3 <
325    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
326    (outs SReg_64:$dst),
327    (ins arc:$src0, arc:$src1,
328         InstFlag:$abs, InstFlag:$clamp,
329         InstFlag:$omod, InstFlag:$neg),
330    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
331    !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
332      [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
333    )
334  >, VOP <opName> {
335    let src2 = SIOperand.ZERO;
336  }
337}
338
339multiclass VOPC_32 <bits<8> op, string opName,
340  ValueType vt = untyped, PatLeaf cond = COND_NULL>
341  : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
342
343multiclass VOPC_64 <bits<8> op, string opName,
344  ValueType vt = untyped, PatLeaf cond = COND_NULL>
345  : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
346
347class VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
348  op, (outs VReg_32:$dst),
349  (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
350   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
351  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
352>, VOP <opName>;
353
354class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
355  op, (outs VReg_64:$dst),
356  (ins VSrc_64:$src0, VSrc_32:$src1),
357  opName#" $dst, $src0, $src1", pattern
358>, VOP <opName> {
359
360  let src2 = SIOperand.ZERO;
361  let abs = 0;
362  let clamp = 0;
363  let omod = 0;
364  let neg = 0;
365}
366
367class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
368  op, (outs VReg_64:$dst),
369  (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
370   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
371  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
372>, VOP <opName>;
373
374//===----------------------------------------------------------------------===//
375// Vector I/O classes
376//===----------------------------------------------------------------------===//
377
378class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
379  op,
380  (outs regClass:$vdst),
381  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
382       i8imm:$offset0, i8imm:$offset1),
383  asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
384  []> {
385  let mayLoad = 1;
386  let mayStore = 0;
387}
388
389class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
390  op,
391  (outs),
392  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
393       i8imm:$offset0, i8imm:$offset1),
394  asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
395  []> {
396  let mayStore = 1;
397  let mayLoad = 0;
398  let vdst = 0;
399}
400
401class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
402  op,
403  (outs rc:$vdst),
404  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
405       i8imm:$offset1),
406  asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
407  []> {
408  let mayStore = 1;
409  let mayLoad = 1;
410  let data1 = 0;
411}
412
413class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
414  op,
415  (outs),
416  (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
417   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
418   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
419  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
420     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
421  []> {
422  let mayStore = 1;
423  let mayLoad = 0;
424}
425
426multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
427
428  let lds = 0, mayLoad = 1 in {
429
430    let addr64 = 0 in {
431
432      let offen = 0, idxen = 0 in {
433        def _OFFSET : MUBUF <op, (outs regClass:$vdata),
434                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
435                             i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
436                             i1imm:$slc, i1imm:$tfe),
437                             asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
438      }
439
440      let offen = 1, idxen = 0, offset = 0 in {
441        def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
442                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
443                             SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
444                             i1imm:$tfe),
445                             asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
446      }
447
448      let offen = 0, idxen = 1 in {
449        def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
450                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
451                             i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
452                             i1imm:$slc, i1imm:$tfe),
453                             asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
454      }
455
456      let offen = 1, idxen = 1 in {
457        def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
458                             (ins SReg_128:$srsrc, VReg_64:$vaddr,
459                             SSrc_32:$soffset, i1imm:$glc,
460                             i1imm:$slc, i1imm:$tfe),
461                             asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
462      }
463    }
464
465    let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
466      def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
467                           (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
468                           asm#" $vdata, $srsrc + $vaddr + $offset", []>;
469    }
470  }
471}
472
473class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
474    MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
475                            i16imm:$offset),
476          name#" $vdata, $srsrc + $vaddr + $offset",
477         []> {
478
479  let mayLoad = 0;
480  let mayStore = 1;
481
482  // Encoding
483  let offen = 0;
484  let idxen = 0;
485  let glc = 0;
486  let addr64 = 1;
487  let lds = 0;
488  let slc = 0;
489  let tfe = 0;
490  let soffset = 128; // ZERO
491}
492
493class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
494  op,
495  (outs regClass:$dst),
496  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
497       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
498       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
499  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
500     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
501  []> {
502  let mayLoad = 1;
503  let mayStore = 0;
504}
505
506class MIMG_Mask <string op, int channels> {
507  string Op = op;
508  int Channels = channels;
509}
510
511class MIMG_NoSampler_Helper <bits<7> op, string asm,
512                             RegisterClass dst_rc,
513                             RegisterClass src_rc> : MIMG <
514  op,
515  (outs dst_rc:$vdata),
516  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
517       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
518       SReg_256:$srsrc),
519  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
520     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
521  []> {
522  let SSAMP = 0;
523  let mayLoad = 1;
524  let mayStore = 0;
525  let hasPostISelHook = 1;
526}
527
528multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
529                                      RegisterClass dst_rc,
530                                      int channels> {
531  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
532            MIMG_Mask<asm#"_V1", channels>;
533  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
534            MIMG_Mask<asm#"_V2", channels>;
535  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
536            MIMG_Mask<asm#"_V4", channels>;
537}
538
539multiclass MIMG_NoSampler <bits<7> op, string asm> {
540  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
541  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
542  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
543  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
544}
545
546class MIMG_Sampler_Helper <bits<7> op, string asm,
547                           RegisterClass dst_rc,
548                           RegisterClass src_rc> : MIMG <
549  op,
550  (outs dst_rc:$vdata),
551  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
552       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
553       SReg_256:$srsrc, SReg_128:$ssamp),
554  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
555     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
556  []> {
557  let mayLoad = 1;
558  let mayStore = 0;
559  let hasPostISelHook = 1;
560}
561
562multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
563                                    RegisterClass dst_rc,
564                                    int channels> {
565  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
566            MIMG_Mask<asm#"_V1", channels>;
567  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
568            MIMG_Mask<asm#"_V2", channels>;
569  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
570            MIMG_Mask<asm#"_V4", channels>;
571  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
572            MIMG_Mask<asm#"_V8", channels>;
573  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
574            MIMG_Mask<asm#"_V16", channels>;
575}
576
577multiclass MIMG_Sampler <bits<7> op, string asm> {
578  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
579  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
580  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
581  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
582}
583
584//===----------------------------------------------------------------------===//
585// Vector instruction mappings
586//===----------------------------------------------------------------------===//
587
588// Maps an opcode in e32 form to its e64 equivalent
589def getVOPe64 : InstrMapping {
590  let FilterClass = "VOP";
591  let RowFields = ["OpName"];
592  let ColFields = ["Size"];
593  let KeyCol = ["4"];
594  let ValueCols = [["8"]];
595}
596
597// Maps an original opcode to its commuted version
598def getCommuteRev : InstrMapping {
599  let FilterClass = "VOP2_REV";
600  let RowFields = ["RevOp"];
601  let ColFields = ["IsOrig"];
602  let KeyCol = ["1"];
603  let ValueCols = [["0"]];
604}
605
606def getMaskedMIMGOp : InstrMapping {
607  let FilterClass = "MIMG_Mask";
608  let RowFields = ["Op"];
609  let ColFields = ["Channels"];
610  let KeyCol = ["4"];
611  let ValueCols = [["1"], ["2"], ["3"] ];
612}
613
614// Maps an commuted opcode to its original version
615def getCommuteOrig : InstrMapping {
616  let FilterClass = "VOP2_REV";
617  let RowFields = ["RevOp"];
618  let ColFields = ["IsOrig"];
619  let KeyCol = ["0"];
620  let ValueCols = [["1"]];
621}
622
623include "SIInstructions.td"
624