R600/SI: Use a ComplexPattern for ADDR64 addressing of MUBUF loads
[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 // Complex patterns
151 //===----------------------------------------------------------------------===//
152
153 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
154
155 //===----------------------------------------------------------------------===//
156 // SI assembler operands
157 //===----------------------------------------------------------------------===//
158
159 def SIOperand {
160   int ZERO = 0x80;
161   int VCC = 0x6A;
162 }
163
164 include "SIInstrFormats.td"
165
166 //===----------------------------------------------------------------------===//
167 //
168 // SI Instruction multiclass helpers.
169 //
170 // Instructions with _32 take 32-bit operands.
171 // Instructions with _64 take 64-bit operands.
172 //
173 // VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
174 // encoding is the standard encoding, but instruction that make use of
175 // any of the instruction modifiers must use the 64-bit encoding.
176 //
177 // Instructions with _e32 use the 32-bit encoding.
178 // Instructions with _e64 use the 64-bit encoding.
179 //
180 //===----------------------------------------------------------------------===//
181
182 //===----------------------------------------------------------------------===//
183 // Scalar classes
184 //===----------------------------------------------------------------------===//
185
186 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
187   op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
188   opName#" $dst, $src0", pattern
189 >;
190
191 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
192   op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
193   opName#" $dst, $src0", pattern
194 >;
195
196 // 64-bit input, 32-bit output.
197 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
198   op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
199   opName#" $dst, $src0", pattern
200 >;
201
202 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
203   op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
204   opName#" $dst, $src0, $src1", pattern
205 >;
206
207 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
208   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
209   opName#" $dst, $src0, $src1", pattern
210 >;
211
212 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
213   op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
214   opName#" $dst, $src0, $src1", pattern
215 >;
216
217
218 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
219                     string opName, PatLeaf cond> : SOPC <
220   op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
221   opName#" $dst, $src0, $src1", []>;
222
223 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
224   : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
225
226 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
227   : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
228
229 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
230   op, (outs SReg_32:$dst), (ins i16imm:$src0),
231   opName#" $dst, $src0", pattern
232 >;
233
234 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
235   op, (outs SReg_64:$dst), (ins i16imm:$src0),
236   opName#" $dst, $src0", pattern
237 >;
238
239 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
240                         RegisterClass dstClass> {
241   def _IMM : SMRD <
242     op, 1, (outs dstClass:$dst),
243     (ins baseClass:$sbase, u32imm:$offset),
244     asm#" $dst, $sbase, $offset", []
245   >;
246
247   def _SGPR : SMRD <
248     op, 0, (outs dstClass:$dst),
249     (ins baseClass:$sbase, SReg_32:$soff),
250     asm#" $dst, $sbase, $soff", []
251   >;
252 }
253
254 //===----------------------------------------------------------------------===//
255 // Vector ALU classes
256 //===----------------------------------------------------------------------===//
257
258 class VOP <string opName> {
259   string OpName = opName;
260 }
261
262 class VOP2_REV <string revOp, bit isOrig> {
263   string RevOp = revOp;
264   bit IsOrig = isOrig;
265 }
266
267 class SIMCInstr <string pseudo, int subtarget> {
268   string PseudoInstr = pseudo;
269   int Subtarget = subtarget;
270 }
271
272 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
273                    string opName> {
274
275   def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
276            SIMCInstr<OpName, SISubtarget.NONE> {
277     let isPseudo = 1;
278   }
279
280   def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
281
282 }
283
284 // This must always be right before the operand being input modified.
285 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
286   let PrintMethod = "printOperandAndMods";
287 }
288
289 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
290                         string opName, list<dag> pattern> {
291
292   def _e32 : VOP1 <
293     op, (outs drc:$dst), (ins src:$src0),
294     opName#"_e32 $dst, $src0", pattern
295   >, VOP <opName>;
296
297   def _e64 : VOP3 <
298     {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
299     (outs drc:$dst),
300     (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
301     opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
302   >, VOP <opName> {
303     let src1 = SIOperand.ZERO;
304     let src2 = SIOperand.ZERO;
305   }
306 }
307
308 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
309   : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
310
311 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
312   : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
313
314 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
315   : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
316
317 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
318   : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
319
320 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
321                         string opName, list<dag> pattern, string revOp> {
322   def _e32 : VOP2 <
323     op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
324     opName#"_e32 $dst, $src0, $src1", pattern
325   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
326
327   def _e64 : VOP3 <
328     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
329     (outs vrc:$dst),
330     (ins InputMods:$src0_modifiers, arc:$src0,
331          InputMods:$src1_modifiers, arc:$src1,
332          i32imm:$clamp, i32imm:$omod),
333     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
334   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
335     let src2 = SIOperand.ZERO;
336   }
337 }
338
339 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
340                     string revOp = opName>
341   : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
342
343 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
344                     string revOp = opName>
345   : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
346
347 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
348                      RegisterClass src0_rc, string revOp = opName> {
349
350   def _e32 : VOP2 <
351     op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
352     opName#"_e32 $dst, $src0, $src1", pattern
353   >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
354
355   def _e64 : VOP3b <
356     {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
357     (outs VReg_32:$dst),
358     (ins InputMods: $src0_modifiers, VSrc_32:$src0,
359          InputMods:$src1_modifiers, VSrc_32:$src1,
360          i32imm:$clamp, i32imm:$omod),
361     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
362   >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
363     let src2 = SIOperand.ZERO;
364     /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
365        can write it into any SGPR. We currently don't use the carry out,
366        so for now hardcode it to VCC as well */
367     let sdst = SIOperand.VCC;
368   }
369 }
370
371 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
372                         string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
373   def _e32 : VOPC <
374     op, (ins arc:$src0, vrc:$src1),
375     opName#"_e32 $dst, $src0, $src1", []
376   >, VOP <opName> {
377     let Defs = !if(defExec, [VCC, EXEC], [VCC]);
378   }
379
380   def _e64 : VOP3 <
381     {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
382     (outs SReg_64:$dst),
383     (ins InputMods:$src0_modifiers, arc:$src0,
384          InputMods:$src1_modifiers, arc:$src1,
385          InstFlag:$clamp, InstFlag:$omod),
386     opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
387     !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
388       [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
389     )
390   >, VOP <opName> {
391     let Defs = !if(defExec, [EXEC], []);
392     let src2 = SIOperand.ZERO;
393     let src2_modifiers = 0;
394   }
395 }
396
397 multiclass VOPC_32 <bits<8> op, string opName,
398   ValueType vt = untyped, PatLeaf cond = COND_NULL>
399   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
400
401 multiclass VOPC_64 <bits<8> op, string opName,
402   ValueType vt = untyped, PatLeaf cond = COND_NULL>
403   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
404
405 multiclass VOPCX_32 <bits<8> op, string opName,
406   ValueType vt = untyped, PatLeaf cond = COND_NULL>
407   : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
408
409 multiclass VOPCX_64 <bits<8> op, string opName,
410   ValueType vt = untyped, PatLeaf cond = COND_NULL>
411   : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
412
413 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
414   op, (outs VReg_32:$dst),
415   (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
416    VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
417    InstFlag:$clamp, InstFlag:$omod),
418   opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
419 >;
420
421 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
422   op, (outs VReg_64:$dst),
423   (ins VSrc_64:$src0, VSrc_32:$src1),
424   opName#" $dst, $src0, $src1", pattern
425 >, VOP <opName> {
426
427   let src2 = SIOperand.ZERO;
428   let src0_modifiers = 0;
429   let clamp = 0;
430   let omod = 0;
431 }
432
433 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
434   op, (outs VReg_64:$dst),
435   (ins InputMods:$src0_modifiers, VSrc_64:$src0,
436        InputMods:$src1_modifiers, VSrc_64:$src1,
437        InputMods:$src2_modifiers, VSrc_64:$src2,
438        InstFlag:$clamp, InstFlag:$omod),
439   opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
440 >, VOP <opName>;
441
442
443 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
444                     string opName, list<dag> pattern> : VOP3 <
445   op, (outs vrc:$dst0, SReg_64:$dst1),
446   (ins arc:$src0, arc:$src1, arc:$src2,
447    InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
448   opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
449 >, VOP <opName>;
450
451
452 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
453   VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
454
455 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
456   VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
457
458 //===----------------------------------------------------------------------===//
459 // Vector I/O classes
460 //===----------------------------------------------------------------------===//
461
462 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
463     DS <op, outs, ins, asm, pat> {
464   bits<16> offset;
465
466   // Single load interpret the 2 i8imm operands as a single i16 offset.
467   let offset0 = offset{7-0};
468   let offset1 = offset{15-8};
469 }
470
471 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
472   op,
473   (outs regClass:$vdst),
474   (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
475   asm#" $vdst, $addr, $offset, [M0]",
476   []> {
477   let data0 = 0;
478   let data1 = 0;
479   let mayLoad = 1;
480   let mayStore = 0;
481 }
482
483 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
484   op,
485   (outs regClass:$vdst),
486   (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
487   asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
488   []> {
489   let data0 = 0;
490   let data1 = 0;
491   let mayLoad = 1;
492   let mayStore = 0;
493 }
494
495 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
496   op,
497   (outs),
498   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
499   asm#" $addr, $data0, $offset [M0]",
500   []> {
501   let data1 = 0;
502   let mayStore = 1;
503   let mayLoad = 0;
504   let vdst = 0;
505 }
506
507 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
508   op,
509   (outs),
510   (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
511   asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
512   []> {
513   let mayStore = 1;
514   let mayLoad = 0;
515   let vdst = 0;
516 }
517
518 // 1 address, 1 data.
519 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
520   op,
521   (outs rc:$vdst),
522   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
523   asm#" $vdst, $addr, $data0, $offset, [M0]",
524   []> {
525
526   let data1 = 0;
527   let mayStore = 1;
528   let mayLoad = 1;
529 }
530
531 // 1 address, 2 data.
532 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
533   op,
534   (outs rc:$vdst),
535   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
536   asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
537   []> {
538   let mayStore = 1;
539   let mayLoad = 1;
540 }
541
542 // 1 address, 2 data.
543 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
544   op,
545   (outs),
546   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
547   asm#" $addr, $data0, $data1, $offset, [M0]",
548   []> {
549   let mayStore = 1;
550   let mayLoad = 1;
551 }
552
553 // 1 address, 1 data.
554 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
555   op,
556   (outs),
557   (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
558   asm#" $addr, $data0, $offset, [M0]",
559   []> {
560
561   let data1 = 0;
562   let mayStore = 1;
563   let mayLoad = 1;
564 }
565
566 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
567   op,
568   (outs),
569   (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
570    i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
571    SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
572   asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
573      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
574   []> {
575   let mayStore = 1;
576   let mayLoad = 0;
577 }
578
579 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
580                               ValueType load_vt = i32,
581                               SDPatternOperator ld = null_frag> {
582
583   let lds = 0, mayLoad = 1 in {
584
585     let addr64 = 0 in {
586
587       let offen = 0, idxen = 0 in {
588         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
589                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
590                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
591                              i1imm:$slc, i1imm:$tfe),
592                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
593       }
594
595       let offen = 1, idxen = 0, offset = 0 in {
596         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
597                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
598                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
599                              i1imm:$tfe),
600                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
601       }
602
603       let offen = 0, idxen = 1 in {
604         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
605                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
606                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
607                              i1imm:$slc, i1imm:$tfe),
608                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
609       }
610
611       let offen = 1, idxen = 1 in {
612         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
613                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
614                              SSrc_32:$soffset, i1imm:$glc,
615                              i1imm:$slc, i1imm:$tfe),
616                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
617       }
618     }
619
620     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
621       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
622                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
623                            asm#" $vdata, $srsrc + $vaddr + $offset",
624                            [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
625                                                   i64:$vaddr, u16imm:$offset)))]>;
626     }
627   }
628 }
629
630 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
631                           ValueType store_vt, SDPatternOperator st> :
632     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
633                             u16imm:$offset),
634           name#" $vdata, $srsrc + $vaddr + $offset",
635           [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
636
637   let mayLoad = 0;
638   let mayStore = 1;
639
640   // Encoding
641   let offen = 0;
642   let idxen = 0;
643   let glc = 0;
644   let addr64 = 1;
645   let lds = 0;
646   let slc = 0;
647   let tfe = 0;
648   let soffset = 128; // ZERO
649 }
650
651 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
652   op,
653   (outs regClass:$dst),
654   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
655        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
656        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
657   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
658      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
659   []> {
660   let mayLoad = 1;
661   let mayStore = 0;
662 }
663
664 class MIMG_Mask <string op, int channels> {
665   string Op = op;
666   int Channels = channels;
667 }
668
669 class MIMG_NoSampler_Helper <bits<7> op, string asm,
670                              RegisterClass dst_rc,
671                              RegisterClass src_rc> : MIMG <
672   op,
673   (outs dst_rc:$vdata),
674   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
675        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
676        SReg_256:$srsrc),
677   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
678      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
679   []> {
680   let SSAMP = 0;
681   let mayLoad = 1;
682   let mayStore = 0;
683   let hasPostISelHook = 1;
684 }
685
686 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
687                                       RegisterClass dst_rc,
688                                       int channels> {
689   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
690             MIMG_Mask<asm#"_V1", channels>;
691   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
692             MIMG_Mask<asm#"_V2", channels>;
693   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
694             MIMG_Mask<asm#"_V4", channels>;
695 }
696
697 multiclass MIMG_NoSampler <bits<7> op, string asm> {
698   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
699   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
700   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
701   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
702 }
703
704 class MIMG_Sampler_Helper <bits<7> op, string asm,
705                            RegisterClass dst_rc,
706                            RegisterClass src_rc> : MIMG <
707   op,
708   (outs dst_rc:$vdata),
709   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
710        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
711        SReg_256:$srsrc, SReg_128:$ssamp),
712   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
713      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
714   []> {
715   let mayLoad = 1;
716   let mayStore = 0;
717   let hasPostISelHook = 1;
718 }
719
720 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
721                                     RegisterClass dst_rc,
722                                     int channels> {
723   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
724             MIMG_Mask<asm#"_V1", channels>;
725   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
726             MIMG_Mask<asm#"_V2", channels>;
727   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
728             MIMG_Mask<asm#"_V4", channels>;
729   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
730             MIMG_Mask<asm#"_V8", channels>;
731   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
732             MIMG_Mask<asm#"_V16", channels>;
733 }
734
735 multiclass MIMG_Sampler <bits<7> op, string asm> {
736   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
737   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
738   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
739   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
740 }
741
742 class MIMG_Gather_Helper <bits<7> op, string asm,
743                           RegisterClass dst_rc,
744                           RegisterClass src_rc> : MIMG <
745   op,
746   (outs dst_rc:$vdata),
747   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
748        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
749        SReg_256:$srsrc, SReg_128:$ssamp),
750   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
751      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
752   []> {
753   let mayLoad = 1;
754   let mayStore = 0;
755
756   // DMASK was repurposed for GATHER4. 4 components are always
757   // returned and DMASK works like a swizzle - it selects
758   // the component to fetch. The only useful DMASK values are
759   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
760   // (red,red,red,red) etc.) The ISA document doesn't mention
761   // this.
762   // Therefore, disable all code which updates DMASK by setting these two:
763   let MIMG = 0;
764   let hasPostISelHook = 0;
765 }
766
767 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
768                                     RegisterClass dst_rc,
769                                     int channels> {
770   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
771             MIMG_Mask<asm#"_V1", channels>;
772   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
773             MIMG_Mask<asm#"_V2", channels>;
774   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
775             MIMG_Mask<asm#"_V4", channels>;
776   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
777             MIMG_Mask<asm#"_V8", channels>;
778   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
779             MIMG_Mask<asm#"_V16", channels>;
780 }
781
782 multiclass MIMG_Gather <bits<7> op, string asm> {
783   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
784   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
785   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
786   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
787 }
788
789 //===----------------------------------------------------------------------===//
790 // Vector instruction mappings
791 //===----------------------------------------------------------------------===//
792
793 // Maps an opcode in e32 form to its e64 equivalent
794 def getVOPe64 : InstrMapping {
795   let FilterClass = "VOP";
796   let RowFields = ["OpName"];
797   let ColFields = ["Size"];
798   let KeyCol = ["4"];
799   let ValueCols = [["8"]];
800 }
801
802 // Maps an original opcode to its commuted version
803 def getCommuteRev : InstrMapping {
804   let FilterClass = "VOP2_REV";
805   let RowFields = ["RevOp"];
806   let ColFields = ["IsOrig"];
807   let KeyCol = ["1"];
808   let ValueCols = [["0"]];
809 }
810
811 def getMaskedMIMGOp : InstrMapping {
812   let FilterClass = "MIMG_Mask";
813   let RowFields = ["Op"];
814   let ColFields = ["Channels"];
815   let KeyCol = ["4"];
816   let ValueCols = [["1"], ["2"], ["3"] ];
817 }
818
819 // Maps an commuted opcode to its original version
820 def getCommuteOrig : InstrMapping {
821   let FilterClass = "VOP2_REV";
822   let RowFields = ["RevOp"];
823   let ColFields = ["IsOrig"];
824   let KeyCol = ["0"];
825   let ValueCols = [["1"]];
826 }
827
828 def isDS : InstrMapping {
829   let FilterClass = "DS";
830   let RowFields = ["Inst"];
831   let ColFields = ["Size"];
832   let KeyCol = ["8"];
833   let ValueCols = [["8"]];
834 }
835
836 def getMCOpcode : InstrMapping {
837   let FilterClass = "SIMCInstr";
838   let RowFields = ["PseudoInstr"];
839   let ColFields = ["Subtarget"];
840   let KeyCol = [!cast<string>(SISubtarget.NONE)];
841   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
842 }
843
844 include "SIInstructions.td"