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