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