R600/SI: Fix div_scale intrinsic.
[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 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
11 // in AMDGPUMCInstLower.h
12 def SISubtarget {
13   int NONE = -1;
14   int SI = 0;
15 }
16
17 //===----------------------------------------------------------------------===//
18 // SI DAG Nodes
19 //===----------------------------------------------------------------------===//
20
21 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
22   SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
23                       [SDNPMayLoad, SDNPMemOperand]
24 >;
25
26 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
27   SDTypeProfile<0, 13,
28     [SDTCisVT<0, v4i32>,   // rsrc(SGPR)
29      SDTCisVT<1, iAny>,   // vdata(VGPR)
30      SDTCisVT<2, i32>,    // num_channels(imm)
31      SDTCisVT<3, i32>,    // vaddr(VGPR)
32      SDTCisVT<4, i32>,    // soffset(SGPR)
33      SDTCisVT<5, i32>,    // inst_offset(imm)
34      SDTCisVT<6, i32>,    // dfmt(imm)
35      SDTCisVT<7, i32>,    // nfmt(imm)
36      SDTCisVT<8, i32>,    // offen(imm)
37      SDTCisVT<9, i32>,    // idxen(imm)
38      SDTCisVT<10, i32>,   // glc(imm)
39      SDTCisVT<11, i32>,   // slc(imm)
40      SDTCisVT<12, i32>    // tfe(imm)
41     ]>,
42   [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
43 >;
44
45 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
46   SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
47                        SDTCisVT<3, i32>]>
48 >;
49
50 class SDSample<string opcode> : SDNode <opcode,
51   SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
52                        SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
53 >;
54
55 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
56 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
57 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
58 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
59
60 // Transformation function, extract the lower 32bit of a 64bit immediate
61 def LO32 : SDNodeXForm<imm, [{
62   return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
63 }]>;
64
65 def LO32f : SDNodeXForm<fpimm, [{
66   APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
67   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
68 }]>;
69
70 // Transformation function, extract the upper 32bit of a 64bit immediate
71 def HI32 : SDNodeXForm<imm, [{
72   return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
73 }]>;
74
75 def HI32f : SDNodeXForm<fpimm, [{
76   APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
77   return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
78 }]>;
79
80 def IMM8bitDWORD : PatLeaf <(imm),
81   [{return (N->getZExtValue() & ~0x3FC) == 0;}]
82 >;
83
84 def as_dword_i32imm : SDNodeXForm<imm, [{
85   return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
86 }]>;
87
88 def as_i1imm : SDNodeXForm<imm, [{
89   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
90 }]>;
91
92 def as_i8imm : SDNodeXForm<imm, [{
93   return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
94 }]>;
95
96 def as_i16imm : SDNodeXForm<imm, [{
97   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
98 }]>;
99
100 def as_i32imm: SDNodeXForm<imm, [{
101   return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
102 }]>;
103
104 def IMM8bit : PatLeaf <(imm),
105   [{return isUInt<8>(N->getZExtValue());}]
106 >;
107
108 def IMM12bit : PatLeaf <(imm),
109   [{return isUInt<12>(N->getZExtValue());}]
110 >;
111
112 def IMM16bit : PatLeaf <(imm),
113   [{return isUInt<16>(N->getZExtValue());}]
114 >;
115
116 def IMM32bit : PatLeaf <(imm),
117   [{return isUInt<32>(N->getZExtValue());}]
118 >;
119
120 def mubuf_vaddr_offset : PatFrag<
121   (ops node:$ptr, node:$offset, node:$imm_offset),
122   (add (add node:$ptr, node:$offset), node:$imm_offset)
123 >;
124
125 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
126   return isInlineImmediate(N);
127 }]>;
128
129 class SGPRImm <dag frag> : PatLeaf<frag, [{
130   if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
131       AMDGPUSubtarget::SOUTHERN_ISLANDS) {
132     return false;
133   }
134   const SIRegisterInfo *SIRI =
135                        static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
136   for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
137                                                 U != E; ++U) {
138     if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
139       return true;
140     }
141   }
142   return false;
143 }]>;
144
145 def FRAMEri32 : Operand<iPTR> {
146   let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
147 }
148
149 //===----------------------------------------------------------------------===//
150 // SI assembler operands
151 //===----------------------------------------------------------------------===//
152
153 def SIOperand {
154   int ZERO = 0x80;
155   int VCC = 0x6A;
156 }
157
158 include "SIInstrFormats.td"
159
160 //===----------------------------------------------------------------------===//
161 //
162 // SI Instruction multiclass helpers.
163 //
164 // Instructions with _32 take 32-bit operands.
165 // Instructions with _64 take 64-bit operands.
166 //
167 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
168 // encoding is the standard encoding, but instruction that make use of
169 // any of the instruction modifiers must use the 64-bit encoding.
170 //
171 // Instructions with _e32 use the 32-bit encoding.
172 // Instructions with _e64 use the 64-bit encoding.
173 //
174 //===----------------------------------------------------------------------===//
175
176 //===----------------------------------------------------------------------===//
177 // Scalar classes
178 //===----------------------------------------------------------------------===//
179
180 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
181   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
182   opName#" $dst, $src0", pattern
183 >;
184
185 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
186   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
187   opName#" $dst, $src0", pattern
188 >;
189
190 // 64-bit input, 32-bit output.
191 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
192   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
193   opName#" $dst, $src0", pattern
194 >;
195
196 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
197   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
198   opName#" $dst, $src0, $src1", pattern
199 >;
200
201 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
202   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
203   opName#" $dst, $src0, $src1", pattern
204 >;
205
206 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
207   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
208   opName#" $dst, $src0, $src1", pattern
209 >;
210
211
212 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
213                     string opName, PatLeaf cond> : SOPC <
214   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
215   opName#" $dst, $src0, $src1", []>;
216
217 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
218   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
219
220 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
221   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
222
223 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
224   op, (outs SReg_32:$dst), (ins i16imm:$src0),
225   opName#" $dst, $src0", pattern
226 >;
227
228 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
229   op, (outs SReg_64:$dst), (ins i16imm:$src0),
230   opName#" $dst, $src0", pattern
231 >;
232
233 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
234                         RegisterClass dstClass> {
235   def _IMM : SMRD <
236     op, 1, (outs dstClass:$dst),
237     (ins baseClass:$sbase, u32imm:$offset),
238     asm#" $dst, $sbase, $offset", []
239   >;
240
241   def _SGPR : SMRD <
242     op, 0, (outs dstClass:$dst),
243     (ins baseClass:$sbase, SReg_32:$soff),
244     asm#" $dst, $sbase, $soff", []
245   >;
246 }
247
248 //===----------------------------------------------------------------------===//
249 // Vector ALU classes
250 //===----------------------------------------------------------------------===//
251
252 class VOP <string opName> {
253   string OpName = opName;
254 }
255
256 class VOP2_REV <string revOp, bit isOrig> {
257   string RevOp = revOp;
258   bit IsOrig = isOrig;
259 }
260
261 class SIMCInstr <string pseudo, int subtarget> {
262   string PseudoInstr = pseudo;
263   int Subtarget = subtarget;
264 }
265
266 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
267                    string opName> {
268
269   def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
270            SIMCInstr<OpName, SISubtarget.NONE> {
271     let isPseudo = 1;
272   }
273
274   def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
275
276 }
277
278 // This must always be right before the operand being input modified.
279 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
280   let PrintMethod = "printOperandAndMods";
281 }
282
283 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
284                         string opName, list<dag> pattern> {
285
286   def _e32 : VOP1 <
287     op, (outs drc:$dst), (ins src:$src0),
288     opName#"_e32 $dst, $src0", pattern
289   >, VOP <opName>;
290
291   def _e64 : VOP3 <
292     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
293     (outs drc:$dst),
294     (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
295     opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
296   >, VOP <opName> {
297     let src1 = SIOperand.ZERO;
298     let src2 = SIOperand.ZERO;
299   }
300 }
301
302 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
303   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
304
305 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
306   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
307
308 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
309   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
310
311 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
312   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
313
314 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
315                         string opName, list<dag> pattern, string revOp> {
316   def _e32 : VOP2 <
317     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
318     opName#"_e32 $dst, $src0, $src1", pattern
319   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
320
321   def _e64 : VOP3 <
322     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
323     (outs vrc:$dst),
324     (ins InputMods:$src0_modifiers, arc:$src0,
325          InputMods:$src1_modifiers, arc:$src1,
326          i32imm:$clamp, i32imm:$omod),
327     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
328   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
329     let src2 = SIOperand.ZERO;
330   }
331 }
332
333 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
334                     string revOp = opName>
335   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
336
337 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
338                     string revOp = opName>
339   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
340
341 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
342                      RegisterClass src0_rc, string revOp = opName> {
343
344   def _e32 : VOP2 <
345     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
346     opName#"_e32 $dst, $src0, $src1", pattern
347   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
348
349   def _e64 : VOP3b <
350     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
351     (outs VReg_32:$dst),
352     (ins InputMods: $src0_modifiers, VSrc_32:$src0,
353          InputMods:$src1_modifiers, VSrc_32:$src1,
354          i32imm:$clamp, i32imm:$omod),
355     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
356   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
357     let src2 = SIOperand.ZERO;
358     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
359        can write it into any SGPR. We currently don't use the carry out,
360        so for now hardcode it to VCC as well */
361     let sdst = SIOperand.VCC;
362   }
363 }
364
365 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
366                         string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
367   def _e32 : VOPC <
368     op, (ins arc:$src0, vrc:$src1),
369     opName#"_e32 $dst, $src0, $src1", []
370   >, VOP <opName> {
371     let Defs = !if(defExec, [VCC, EXEC], [VCC]);
372   }
373
374   def _e64 : VOP3 <
375     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
376     (outs SReg_64:$dst),
377     (ins InputMods:$src0_modifiers, arc:$src0,
378          InputMods:$src1_modifiers, arc:$src1,
379          InstFlag:$clamp, InstFlag:$omod),
380     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
381     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
382       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
383     )
384   >, VOP <opName> {
385     let Defs = !if(defExec, [EXEC], []);
386     let src2 = SIOperand.ZERO;
387     let src2_modifiers = 0;
388   }
389 }
390
391 multiclass VOPC_32 <bits<8> op, string opName,
392   ValueType vt = untyped, PatLeaf cond = COND_NULL>
393   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
394
395 multiclass VOPC_64 <bits<8> op, string opName,
396   ValueType vt = untyped, PatLeaf cond = COND_NULL>
397   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
398
399 multiclass VOPCX_32 <bits<8> op, string opName,
400   ValueType vt = untyped, PatLeaf cond = COND_NULL>
401   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
402
403 multiclass VOPCX_64 <bits<8> op, string opName,
404   ValueType vt = untyped, PatLeaf cond = COND_NULL>
405   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
406
407 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
408   op, (outs VReg_32:$dst),
409   (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
410    VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
411    InstFlag:$clamp, InstFlag:$omod),
412   opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
413 >;
414
415 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
416   op, (outs VReg_64:$dst),
417   (ins VSrc_64:$src0, VSrc_32:$src1),
418   opName#" $dst, $src0, $src1", pattern
419 >, VOP <opName> {
420
421   let src2 = SIOperand.ZERO;
422   let src0_modifiers = 0;
423   let clamp = 0;
424   let omod = 0;
425 }
426
427 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
428   op, (outs VReg_64:$dst),
429   (ins InputMods:$src0_modifiers, VSrc_64:$src0,
430        InputMods:$src1_modifiers, VSrc_64:$src1,
431        InputMods:$src2_modifiers, VSrc_64:$src2,
432        InstFlag:$clamp, InstFlag:$omod),
433   opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
434 >, VOP <opName>;
435
436
437 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
438                     string opName, list<dag> pattern> : VOP3 <
439   op, (outs vrc:$dst0, SReg_64:$dst1),
440   (ins arc:$src0, arc:$src1, arc:$src2,
441    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
442   opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
443 >, VOP <opName>;
444
445
446 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
447   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
448
449 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
450   VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
451
452 //===----------------------------------------------------------------------===//
453 // Vector I/O classes
454 //===----------------------------------------------------------------------===//
455
456 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
457     DS <op, outs, ins, asm, pat> {
458   bits<16> offset;
459
460   // Single load interpret the 2 i8imm operands as a single i16 offset.
461   let offset0 = offset{7-0};
462   let offset1 = offset{15-8};
463 }
464
465 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
466   op,
467   (outs regClass:$vdst),
468   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
469   asm#" $vdst, $addr, $offset, [M0]",
470   []> {
471   let data0 = 0;
472   let data1 = 0;
473   let mayLoad = 1;
474   let mayStore = 0;
475 }
476
477 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
478   op,
479   (outs regClass:$vdst),
480   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
481   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
482   []> {
483   let data0 = 0;
484   let data1 = 0;
485   let mayLoad = 1;
486   let mayStore = 0;
487 }
488
489 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
490   op,
491   (outs),
492   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
493   asm#" $addr, $data0, $offset [M0]",
494   []> {
495   let data1 = 0;
496   let mayStore = 1;
497   let mayLoad = 0;
498   let vdst = 0;
499 }
500
501 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
502   op,
503   (outs),
504   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
505   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
506   []> {
507   let mayStore = 1;
508   let mayLoad = 0;
509   let vdst = 0;
510 }
511
512 // 1 address, 1 data.
513 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
514   op,
515   (outs rc:$vdst),
516   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
517   asm#" $vdst, $addr, $data0, $offset, [M0]",
518   []> {
519
520   let data1 = 0;
521   let mayStore = 1;
522   let mayLoad = 1;
523 }
524
525 // 1 address, 2 data.
526 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
527   op,
528   (outs rc:$vdst),
529   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
530   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
531   []> {
532   let mayStore = 1;
533   let mayLoad = 1;
534 }
535
536 // 1 address, 2 data.
537 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
538   op,
539   (outs),
540   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
541   asm#" $addr, $data0, $data1, $offset, [M0]",
542   []> {
543   let mayStore = 1;
544   let mayLoad = 1;
545 }
546
547 // 1 address, 1 data.
548 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
549   op,
550   (outs),
551   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
552   asm#" $addr, $data0, $offset, [M0]",
553   []> {
554
555   let data1 = 0;
556   let mayStore = 1;
557   let mayLoad = 1;
558 }
559
560 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
561   op,
562   (outs),
563   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
564    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
565    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
566   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
567      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
568   []> {
569   let mayStore = 1;
570   let mayLoad = 0;
571 }
572
573 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
574
575   let lds = 0, mayLoad = 1 in {
576
577     let addr64 = 0 in {
578
579       let offen = 0, idxen = 0 in {
580         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
581                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
582                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
583                              i1imm:$slc, i1imm:$tfe),
584                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
585       }
586
587       let offen = 1, idxen = 0, offset = 0 in {
588         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
589                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
590                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
591                              i1imm:$tfe),
592                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
593       }
594
595       let offen = 0, idxen = 1 in {
596         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
597                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
598                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
599                              i1imm:$slc, i1imm:$tfe),
600                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
601       }
602
603       let offen = 1, idxen = 1 in {
604         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
605                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
606                              SSrc_32:$soffset, i1imm:$glc,
607                              i1imm:$slc, i1imm:$tfe),
608                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
609       }
610     }
611
612     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
613       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
614                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
615                            asm#" $vdata, $srsrc + $vaddr + $offset", []>;
616     }
617   }
618 }
619
620 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
621     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
622                             u16imm:$offset),
623           name#" $vdata, $srsrc + $vaddr + $offset",
624          []> {
625
626   let mayLoad = 0;
627   let mayStore = 1;
628
629   // Encoding
630   let offen = 0;
631   let idxen = 0;
632   let glc = 0;
633   let addr64 = 1;
634   let lds = 0;
635   let slc = 0;
636   let tfe = 0;
637   let soffset = 128; // ZERO
638 }
639
640 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
641   op,
642   (outs regClass:$dst),
643   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
644        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
645        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
646   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
647      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
648   []> {
649   let mayLoad = 1;
650   let mayStore = 0;
651 }
652
653 class MIMG_Mask <string op, int channels> {
654   string Op = op;
655   int Channels = channels;
656 }
657
658 class MIMG_NoSampler_Helper <bits<7> op, string asm,
659                              RegisterClass dst_rc,
660                              RegisterClass src_rc> : MIMG <
661   op,
662   (outs dst_rc:$vdata),
663   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
664        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
665        SReg_256:$srsrc),
666   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
667      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
668   []> {
669   let SSAMP = 0;
670   let mayLoad = 1;
671   let mayStore = 0;
672   let hasPostISelHook = 1;
673 }
674
675 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
676                                       RegisterClass dst_rc,
677                                       int channels> {
678   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
679             MIMG_Mask<asm#"_V1", channels>;
680   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
681             MIMG_Mask<asm#"_V2", channels>;
682   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
683             MIMG_Mask<asm#"_V4", channels>;
684 }
685
686 multiclass MIMG_NoSampler <bits<7> op, string asm> {
687   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
688   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
689   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
690   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
691 }
692
693 class MIMG_Sampler_Helper <bits<7> op, string asm,
694                            RegisterClass dst_rc,
695                            RegisterClass src_rc> : MIMG <
696   op,
697   (outs dst_rc:$vdata),
698   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
699        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
700        SReg_256:$srsrc, SReg_128:$ssamp),
701   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
702      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
703   []> {
704   let mayLoad = 1;
705   let mayStore = 0;
706   let hasPostISelHook = 1;
707 }
708
709 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
710                                     RegisterClass dst_rc,
711                                     int channels> {
712   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
713             MIMG_Mask<asm#"_V1", channels>;
714   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
715             MIMG_Mask<asm#"_V2", channels>;
716   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
717             MIMG_Mask<asm#"_V4", channels>;
718   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
719             MIMG_Mask<asm#"_V8", channels>;
720   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
721             MIMG_Mask<asm#"_V16", channels>;
722 }
723
724 multiclass MIMG_Sampler <bits<7> op, string asm> {
725   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
726   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
727   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
728   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
729 }
730
731 class MIMG_Gather_Helper <bits<7> op, string asm,
732                           RegisterClass dst_rc,
733                           RegisterClass src_rc> : MIMG <
734   op,
735   (outs dst_rc:$vdata),
736   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
737        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
738        SReg_256:$srsrc, SReg_128:$ssamp),
739   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
740      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
741   []> {
742   let mayLoad = 1;
743   let mayStore = 0;
744
745   // DMASK was repurposed for GATHER4. 4 components are always
746   // returned and DMASK works like a swizzle - it selects
747   // the component to fetch. The only useful DMASK values are
748   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
749   // (red,red,red,red) etc.) The ISA document doesn't mention
750   // this.
751   // Therefore, disable all code which updates DMASK by setting these two:
752   let MIMG = 0;
753   let hasPostISelHook = 0;
754 }
755
756 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
757                                     RegisterClass dst_rc,
758                                     int channels> {
759   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
760             MIMG_Mask<asm#"_V1", channels>;
761   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
762             MIMG_Mask<asm#"_V2", channels>;
763   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
764             MIMG_Mask<asm#"_V4", channels>;
765   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
766             MIMG_Mask<asm#"_V8", channels>;
767   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
768             MIMG_Mask<asm#"_V16", channels>;
769 }
770
771 multiclass MIMG_Gather <bits<7> op, string asm> {
772   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
773   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
774   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
775   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
776 }
777
778 //===----------------------------------------------------------------------===//
779 // Vector instruction mappings
780 //===----------------------------------------------------------------------===//
781
782 // Maps an opcode in e32 form to its e64 equivalent
783 def getVOPe64 : InstrMapping {
784   let FilterClass = "VOP";
785   let RowFields = ["OpName"];
786   let ColFields = ["Size"];
787   let KeyCol = ["4"];
788   let ValueCols = [["8"]];
789 }
790
791 // Maps an original opcode to its commuted version
792 def getCommuteRev : InstrMapping {
793   let FilterClass = "VOP2_REV";
794   let RowFields = ["RevOp"];
795   let ColFields = ["IsOrig"];
796   let KeyCol = ["1"];
797   let ValueCols = [["0"]];
798 }
799
800 def getMaskedMIMGOp : InstrMapping {
801   let FilterClass = "MIMG_Mask";
802   let RowFields = ["Op"];
803   let ColFields = ["Channels"];
804   let KeyCol = ["4"];
805   let ValueCols = [["1"], ["2"], ["3"] ];
806 }
807
808 // Maps an commuted opcode to its original version
809 def getCommuteOrig : InstrMapping {
810   let FilterClass = "VOP2_REV";
811   let RowFields = ["RevOp"];
812   let ColFields = ["IsOrig"];
813   let KeyCol = ["0"];
814   let ValueCols = [["1"]];
815 }
816
817 def isDS : InstrMapping {
818   let FilterClass = "DS";
819   let RowFields = ["Inst"];
820   let ColFields = ["Size"];
821   let KeyCol = ["8"];
822   let ValueCols = [["8"]];
823 }
824
825 def getMCOpcode : InstrMapping {
826   let FilterClass = "SIMCInstr";
827   let RowFields = ["PseudoInstr"];
828   let ColFields = ["Subtarget"];
829   let KeyCol = [!cast<string>(SISubtarget.NONE)];
830   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
831 }
832
833 include "SIInstructions.td"