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