R600: Move load/store ReplaceNodeResults to common code.
[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
581   let lds = 0, mayLoad = 1 in {
582
583     let addr64 = 0 in {
584
585       let offen = 0, idxen = 0 in {
586         def _OFFSET : MUBUF <op, (outs regClass:$vdata),
587                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
588                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
589                              i1imm:$slc, i1imm:$tfe),
590                              asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
591       }
592
593       let offen = 1, idxen = 0, offset = 0 in {
594         def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
595                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
596                              SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
597                              i1imm:$tfe),
598                              asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
599       }
600
601       let offen = 0, idxen = 1 in {
602         def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
603                              (ins SReg_128:$srsrc, VReg_32:$vaddr,
604                              u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
605                              i1imm:$slc, i1imm:$tfe),
606                              asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
607       }
608
609       let offen = 1, idxen = 1 in {
610         def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
611                              (ins SReg_128:$srsrc, VReg_64:$vaddr,
612                              SSrc_32:$soffset, i1imm:$glc,
613                              i1imm:$slc, i1imm:$tfe),
614                              asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
615       }
616     }
617
618     let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
619       def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
620                            (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
621                            asm#" $vdata, $srsrc + $vaddr + $offset", []>;
622     }
623   }
624 }
625
626 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
627                           ValueType store_vt, SDPatternOperator st> :
628     MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
629                             u16imm:$offset),
630           name#" $vdata, $srsrc + $vaddr + $offset",
631           [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
632
633   let mayLoad = 0;
634   let mayStore = 1;
635
636   // Encoding
637   let offen = 0;
638   let idxen = 0;
639   let glc = 0;
640   let addr64 = 1;
641   let lds = 0;
642   let slc = 0;
643   let tfe = 0;
644   let soffset = 128; // ZERO
645 }
646
647 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
648   op,
649   (outs regClass:$dst),
650   (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
651        i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
652        i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
653   asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
654      #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
655   []> {
656   let mayLoad = 1;
657   let mayStore = 0;
658 }
659
660 class MIMG_Mask <string op, int channels> {
661   string Op = op;
662   int Channels = channels;
663 }
664
665 class MIMG_NoSampler_Helper <bits<7> op, string asm,
666                              RegisterClass dst_rc,
667                              RegisterClass src_rc> : MIMG <
668   op,
669   (outs dst_rc:$vdata),
670   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
671        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
672        SReg_256:$srsrc),
673   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
674      #" $tfe, $lwe, $slc, $vaddr, $srsrc",
675   []> {
676   let SSAMP = 0;
677   let mayLoad = 1;
678   let mayStore = 0;
679   let hasPostISelHook = 1;
680 }
681
682 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
683                                       RegisterClass dst_rc,
684                                       int channels> {
685   def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
686             MIMG_Mask<asm#"_V1", channels>;
687   def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
688             MIMG_Mask<asm#"_V2", channels>;
689   def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
690             MIMG_Mask<asm#"_V4", channels>;
691 }
692
693 multiclass MIMG_NoSampler <bits<7> op, string asm> {
694   defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
695   defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
696   defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
697   defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
698 }
699
700 class MIMG_Sampler_Helper <bits<7> op, string asm,
701                            RegisterClass dst_rc,
702                            RegisterClass src_rc> : MIMG <
703   op,
704   (outs dst_rc:$vdata),
705   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
706        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
707        SReg_256:$srsrc, SReg_128:$ssamp),
708   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
709      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
710   []> {
711   let mayLoad = 1;
712   let mayStore = 0;
713   let hasPostISelHook = 1;
714 }
715
716 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
717                                     RegisterClass dst_rc,
718                                     int channels> {
719   def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
720             MIMG_Mask<asm#"_V1", channels>;
721   def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
722             MIMG_Mask<asm#"_V2", channels>;
723   def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
724             MIMG_Mask<asm#"_V4", channels>;
725   def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
726             MIMG_Mask<asm#"_V8", channels>;
727   def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
728             MIMG_Mask<asm#"_V16", channels>;
729 }
730
731 multiclass MIMG_Sampler <bits<7> op, string asm> {
732   defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
733   defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
734   defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
735   defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
736 }
737
738 class MIMG_Gather_Helper <bits<7> op, string asm,
739                           RegisterClass dst_rc,
740                           RegisterClass src_rc> : MIMG <
741   op,
742   (outs dst_rc:$vdata),
743   (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
744        i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
745        SReg_256:$srsrc, SReg_128:$ssamp),
746   asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
747      #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
748   []> {
749   let mayLoad = 1;
750   let mayStore = 0;
751
752   // DMASK was repurposed for GATHER4. 4 components are always
753   // returned and DMASK works like a swizzle - it selects
754   // the component to fetch. The only useful DMASK values are
755   // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
756   // (red,red,red,red) etc.) The ISA document doesn't mention
757   // this.
758   // Therefore, disable all code which updates DMASK by setting these two:
759   let MIMG = 0;
760   let hasPostISelHook = 0;
761 }
762
763 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
764                                     RegisterClass dst_rc,
765                                     int channels> {
766   def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
767             MIMG_Mask<asm#"_V1", channels>;
768   def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
769             MIMG_Mask<asm#"_V2", channels>;
770   def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
771             MIMG_Mask<asm#"_V4", channels>;
772   def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
773             MIMG_Mask<asm#"_V8", channels>;
774   def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
775             MIMG_Mask<asm#"_V16", channels>;
776 }
777
778 multiclass MIMG_Gather <bits<7> op, string asm> {
779   defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
780   defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
781   defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
782   defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
783 }
784
785 //===----------------------------------------------------------------------===//
786 // Vector instruction mappings
787 //===----------------------------------------------------------------------===//
788
789 // Maps an opcode in e32 form to its e64 equivalent
790 def getVOPe64 : InstrMapping {
791   let FilterClass = "VOP";
792   let RowFields = ["OpName"];
793   let ColFields = ["Size"];
794   let KeyCol = ["4"];
795   let ValueCols = [["8"]];
796 }
797
798 // Maps an original opcode to its commuted version
799 def getCommuteRev : InstrMapping {
800   let FilterClass = "VOP2_REV";
801   let RowFields = ["RevOp"];
802   let ColFields = ["IsOrig"];
803   let KeyCol = ["1"];
804   let ValueCols = [["0"]];
805 }
806
807 def getMaskedMIMGOp : InstrMapping {
808   let FilterClass = "MIMG_Mask";
809   let RowFields = ["Op"];
810   let ColFields = ["Channels"];
811   let KeyCol = ["4"];
812   let ValueCols = [["1"], ["2"], ["3"] ];
813 }
814
815 // Maps an commuted opcode to its original version
816 def getCommuteOrig : InstrMapping {
817   let FilterClass = "VOP2_REV";
818   let RowFields = ["RevOp"];
819   let ColFields = ["IsOrig"];
820   let KeyCol = ["0"];
821   let ValueCols = [["1"]];
822 }
823
824 def isDS : InstrMapping {
825   let FilterClass = "DS";
826   let RowFields = ["Inst"];
827   let ColFields = ["Size"];
828   let KeyCol = ["8"];
829   let ValueCols = [["8"]];
830 }
831
832 def getMCOpcode : InstrMapping {
833   let FilterClass = "SIMCInstr";
834   let RowFields = ["PseudoInstr"];
835   let ColFields = ["Subtarget"];
836   let KeyCol = [!cast<string>(SISubtarget.NONE)];
837   let ValueCols = [[!cast<string>(SISubtarget.SI)]];
838 }
839
840 include "SIInstructions.td"