SIInstrInfo.td revision 263508
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                     string revOp = opName> {
294
295  def _e32 : VOP2 <
296    op, (outs VReg_32:$dst), (ins VSrc_32:$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 glc = 0, lds = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */,
429                                          mayLoad = 1 in {
430
431  let offen = 1, idxen = 0, addr64 = 0, offset = 0 in {
432    def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
433                         (ins SReg_128:$srsrc, VReg_32:$vaddr),
434                         asm#" $vdata, $srsrc + $vaddr", []>;
435  }
436
437  let offen = 0, idxen = 1, addr64 = 0 in {
438    def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
439                         (ins SReg_128:$srsrc, VReg_32:$vaddr, i16imm:$offset),
440                         asm#" $vdata, $srsrc[$vaddr] + $offset", []>;
441  }
442
443  let offen = 0, idxen = 0, addr64 = 1 in {
444    def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
445                         (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
446                         asm#" $vdata, $srsrc + $vaddr + $offset", []>;
447  }
448  }
449}
450
451class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
452    MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
453                            i16imm:$offset),
454          name#" $vdata, $srsrc + $vaddr + $offset",
455         []> {
456
457  let mayLoad = 0;
458  let mayStore = 1;
459
460  // Encoding
461  let offen = 0;
462  let idxen = 0;
463  let glc = 0;
464  let addr64 = 1;
465  let lds = 0;
466  let slc = 0;
467  let tfe = 0;
468  let soffset = 128; // ZERO
469}
470
471class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
472  op,
473  (outs regClass:$dst),
474  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
475       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
476       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
477  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
478     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
479  []> {
480  let mayLoad = 1;
481  let mayStore = 0;
482}
483
484class MIMG_Mask <string op, int channels> {
485  string Op = op;
486  int Channels = channels;
487}
488
489class MIMG_NoSampler_Helper <bits<7> op, string asm,
490                             RegisterClass dst_rc,
491                             RegisterClass src_rc> : MIMG <
492  op,
493  (outs dst_rc:$vdata),
494  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
495       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
496       SReg_256:$srsrc),
497  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
498     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
499  []> {
500  let SSAMP = 0;
501  let mayLoad = 1;
502  let mayStore = 0;
503  let hasPostISelHook = 1;
504}
505
506multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
507                                      RegisterClass dst_rc,
508                                      int channels> {
509  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
510            MIMG_Mask<asm#"_V1", channels>;
511  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
512            MIMG_Mask<asm#"_V2", channels>;
513  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
514            MIMG_Mask<asm#"_V4", channels>;
515}
516
517multiclass MIMG_NoSampler <bits<7> op, string asm> {
518  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
519  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
520  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
521  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
522}
523
524class MIMG_Sampler_Helper <bits<7> op, string asm,
525                           RegisterClass dst_rc,
526                           RegisterClass src_rc> : MIMG <
527  op,
528  (outs dst_rc:$vdata),
529  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
530       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
531       SReg_256:$srsrc, SReg_128:$ssamp),
532  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
533     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
534  []> {
535  let mayLoad = 1;
536  let mayStore = 0;
537  let hasPostISelHook = 1;
538}
539
540multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
541                                    RegisterClass dst_rc,
542                                    int channels> {
543  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
544            MIMG_Mask<asm#"_V1", channels>;
545  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
546            MIMG_Mask<asm#"_V2", channels>;
547  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
548            MIMG_Mask<asm#"_V4", channels>;
549  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
550            MIMG_Mask<asm#"_V8", channels>;
551  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
552            MIMG_Mask<asm#"_V16", channels>;
553}
554
555multiclass MIMG_Sampler <bits<7> op, string asm> {
556  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
557  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
558  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
559  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
560}
561
562//===----------------------------------------------------------------------===//
563// Vector instruction mappings
564//===----------------------------------------------------------------------===//
565
566// Maps an opcode in e32 form to its e64 equivalent
567def getVOPe64 : InstrMapping {
568  let FilterClass = "VOP";
569  let RowFields = ["OpName"];
570  let ColFields = ["Size"];
571  let KeyCol = ["4"];
572  let ValueCols = [["8"]];
573}
574
575// Maps an original opcode to its commuted version
576def getCommuteRev : InstrMapping {
577  let FilterClass = "VOP2_REV";
578  let RowFields = ["RevOp"];
579  let ColFields = ["IsOrig"];
580  let KeyCol = ["1"];
581  let ValueCols = [["0"]];
582}
583
584def getMaskedMIMGOp : InstrMapping {
585  let FilterClass = "MIMG_Mask";
586  let RowFields = ["Op"];
587  let ColFields = ["Channels"];
588  let KeyCol = ["4"];
589  let ValueCols = [["1"], ["2"], ["3"] ];
590}
591
592// Maps an commuted opcode to its original version
593def getCommuteOrig : InstrMapping {
594  let FilterClass = "VOP2_REV";
595  let RowFields = ["RevOp"];
596  let ColFields = ["IsOrig"];
597  let KeyCol = ["0"];
598  let ValueCols = [["1"]];
599}
600
601include "SIInstructions.td"
602