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