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