SIInstrInfo.td revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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
12def SISubtarget {
13  int NONE = -1;
14  int SI = 0;
15}
16
17//===----------------------------------------------------------------------===//
18// SI DAG Nodes
19//===----------------------------------------------------------------------===//
20
21def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
22  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
23                      [SDNPMayLoad, SDNPMemOperand]
24>;
25
26def 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
45def 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
50class SDSample<string opcode> : SDNode <opcode,
51  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
52                       SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
53>;
54
55def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
56def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
57def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
58def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
59
60// Transformation function, extract the lower 32bit of a 64bit immediate
61def LO32 : SDNodeXForm<imm, [{
62  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
63}]>;
64
65def 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
71def HI32 : SDNodeXForm<imm, [{
72  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
73}]>;
74
75def 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
80def IMM8bitDWORD : PatLeaf <(imm),
81  [{return (N->getZExtValue() & ~0x3FC) == 0;}]
82>;
83
84def as_dword_i32imm : SDNodeXForm<imm, [{
85  return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
86}]>;
87
88def as_i1imm : SDNodeXForm<imm, [{
89  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
90}]>;
91
92def as_i8imm : SDNodeXForm<imm, [{
93  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
94}]>;
95
96def as_i16imm : SDNodeXForm<imm, [{
97  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
98}]>;
99
100def as_i32imm: SDNodeXForm<imm, [{
101  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
102}]>;
103
104def IMM8bit : PatLeaf <(imm),
105  [{return isUInt<8>(N->getZExtValue());}]
106>;
107
108def IMM12bit : PatLeaf <(imm),
109  [{return isUInt<12>(N->getZExtValue());}]
110>;
111
112def IMM16bit : PatLeaf <(imm),
113  [{return isUInt<16>(N->getZExtValue());}]
114>;
115
116def IMM32bit : PatLeaf <(imm),
117  [{return isUInt<32>(N->getZExtValue());}]
118>;
119
120def 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
125class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
126  return isInlineImmediate(N);
127}]>;
128
129class 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
145def FRAMEri32 : Operand<iPTR> {
146  let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
147}
148
149//===----------------------------------------------------------------------===//
150// SI assembler operands
151//===----------------------------------------------------------------------===//
152
153def SIOperand {
154  int ZERO = 0x80;
155  int VCC = 0x6A;
156}
157
158include "SIInstrFormats.td"
159
160//===----------------------------------------------------------------------===//
161//
162// SI Instruction multiclass helpers.
163//
164// Instructions with _32 take 32-bit operands.
165// Instructions with _64 take 64-bit operands.
166//
167// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
168// encoding is the standard encoding, but instruction that make use of
169// any of the instruction modifiers must use the 64-bit encoding.
170//
171// Instructions with _e32 use the 32-bit encoding.
172// Instructions with _e64 use the 64-bit encoding.
173//
174//===----------------------------------------------------------------------===//
175
176//===----------------------------------------------------------------------===//
177// Scalar classes
178//===----------------------------------------------------------------------===//
179
180class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
181  op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
182  opName#" $dst, $src0", pattern
183>;
184
185class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
186  op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
187  opName#" $dst, $src0", pattern
188>;
189
190class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
191  op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
192  opName#" $dst, $src0, $src1", pattern
193>;
194
195class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
196  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
197  opName#" $dst, $src0, $src1", pattern
198>;
199
200class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
201  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
202  opName#" $dst, $src0, $src1", pattern
203>;
204
205
206class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
207                    string opName, PatLeaf cond> : SOPC <
208  op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
209  opName#" $dst, $src0, $src1", []>;
210
211class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
212  : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
213
214class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
215  : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
216
217class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
218  op, (outs SReg_32:$dst), (ins i16imm:$src0),
219  opName#" $dst, $src0", pattern
220>;
221
222class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
223  op, (outs SReg_64:$dst), (ins i16imm:$src0),
224  opName#" $dst, $src0", pattern
225>;
226
227multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
228                        RegisterClass dstClass> {
229  def _IMM : SMRD <
230    op, 1, (outs dstClass:$dst),
231    (ins baseClass:$sbase, u32imm:$offset),
232    asm#" $dst, $sbase, $offset", []
233  >;
234
235  def _SGPR : SMRD <
236    op, 0, (outs dstClass:$dst),
237    (ins baseClass:$sbase, SReg_32:$soff),
238    asm#" $dst, $sbase, $soff", []
239  >;
240}
241
242//===----------------------------------------------------------------------===//
243// Vector ALU classes
244//===----------------------------------------------------------------------===//
245
246class VOP <string opName> {
247  string OpName = opName;
248}
249
250class VOP2_REV <string revOp, bit isOrig> {
251  string RevOp = revOp;
252  bit IsOrig = isOrig;
253}
254
255class SIMCInstr <string pseudo, int subtarget> {
256  string PseudoInstr = pseudo;
257  int Subtarget = subtarget;
258}
259
260multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
261                   string opName> {
262
263  def "" : InstSI <outs, ins, "", pattern>, VOP <opName>,
264           SIMCInstr<OpName, SISubtarget.NONE> {
265    let isPseudo = 1;
266  }
267
268  def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
269
270}
271
272// This must always be right before the operand being input modified.
273def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
274  let PrintMethod = "printOperandAndMods";
275}
276
277multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
278                        string opName, list<dag> pattern> {
279
280  def _e32 : VOP1 <
281    op, (outs drc:$dst), (ins src:$src0),
282    opName#"_e32 $dst, $src0", pattern
283  >, VOP <opName>;
284
285  def _e64 : VOP3 <
286    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
287    (outs drc:$dst),
288    (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
289    opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
290  >, VOP <opName> {
291    let src1 = SIOperand.ZERO;
292    let src2 = SIOperand.ZERO;
293  }
294}
295
296multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
297  : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
298
299multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
300  : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
301
302multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
303  : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
304
305multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
306  : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
307
308multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
309                        string opName, list<dag> pattern, string revOp> {
310  def _e32 : VOP2 <
311    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
312    opName#"_e32 $dst, $src0, $src1", pattern
313  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
314
315  def _e64 : VOP3 <
316    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
317    (outs vrc:$dst),
318    (ins InputMods:$src0_modifiers, arc:$src0,
319         InputMods:$src1_modifiers, arc:$src1,
320         i32imm:$clamp, i32imm:$omod),
321    opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
322  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
323    let src2 = SIOperand.ZERO;
324  }
325}
326
327multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
328                    string revOp = opName>
329  : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
330
331multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
332                    string revOp = opName>
333  : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
334
335multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
336                     RegisterClass src0_rc, string revOp = opName> {
337
338  def _e32 : VOP2 <
339    op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
340    opName#"_e32 $dst, $src0, $src1", pattern
341  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
342
343  def _e64 : VOP3b <
344    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
345    (outs VReg_32:$dst),
346    (ins InputMods: $src0_modifiers, VSrc_32:$src0,
347         InputMods:$src1_modifiers, VSrc_32:$src1,
348         i32imm:$clamp, i32imm:$omod),
349    opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
350  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
351    let src2 = SIOperand.ZERO;
352    /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
353       can write it into any SGPR. We currently don't use the carry out,
354       so for now hardcode it to VCC as well */
355    let sdst = SIOperand.VCC;
356  }
357}
358
359multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
360                        string opName, ValueType vt, PatLeaf cond> {
361
362  def _e32 : VOPC <
363    op, (ins arc:$src0, vrc:$src1),
364    opName#"_e32 $dst, $src0, $src1", []
365  >, VOP <opName>;
366
367  def _e64 : VOP3 <
368    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
369    (outs SReg_64:$dst),
370    (ins InputMods:$src0_modifiers, arc:$src0,
371         InputMods:$src1_modifiers, arc:$src1,
372         InstFlag:$clamp, InstFlag:$omod),
373    opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
374    !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
375      [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
376    )
377  >, VOP <opName> {
378    let src2 = SIOperand.ZERO;
379    let src2_modifiers = 0;
380  }
381}
382
383multiclass VOPC_32 <bits<8> op, string opName,
384  ValueType vt = untyped, PatLeaf cond = COND_NULL>
385  : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
386
387multiclass VOPC_64 <bits<8> op, string opName,
388  ValueType vt = untyped, PatLeaf cond = COND_NULL>
389  : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
390
391multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
392  op, (outs VReg_32:$dst),
393  (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
394   VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
395   InstFlag:$clamp, InstFlag:$omod),
396  opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
397>;
398
399class VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
400  op, (outs VReg_64:$dst),
401  (ins VSrc_64:$src0, VSrc_32:$src1),
402  opName#" $dst, $src0, $src1", pattern
403>, VOP <opName> {
404
405  let src2 = SIOperand.ZERO;
406  let src0_modifiers = 0;
407  let clamp = 0;
408  let omod = 0;
409}
410
411class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
412  op, (outs VReg_64:$dst),
413  (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
414   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
415  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
416>, VOP <opName>;
417
418//===----------------------------------------------------------------------===//
419// Vector I/O classes
420//===----------------------------------------------------------------------===//
421
422class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
423    DS <op, outs, ins, asm, pat> {
424  bits<16> offset;
425
426  // Single load interpret the 2 i8imm operands as a single i16 offset.
427  let offset0 = offset{7-0};
428  let offset1 = offset{15-8};
429}
430
431class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
432  op,
433  (outs regClass:$vdst),
434  (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
435  asm#" $vdst, $addr, $offset, [M0]",
436  []> {
437  let data0 = 0;
438  let data1 = 0;
439  let mayLoad = 1;
440  let mayStore = 0;
441}
442
443class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
444  op,
445  (outs regClass:$vdst),
446  (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
447  asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
448  []> {
449  let data0 = 0;
450  let data1 = 0;
451  let mayLoad = 1;
452  let mayStore = 0;
453}
454
455class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
456  op,
457  (outs),
458  (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
459  asm#" $addr, $data0, $offset [M0]",
460  []> {
461  let data1 = 0;
462  let mayStore = 1;
463  let mayLoad = 0;
464  let vdst = 0;
465}
466
467class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
468  op,
469  (outs),
470  (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
471  asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
472  []> {
473  let mayStore = 1;
474  let mayLoad = 0;
475  let vdst = 0;
476}
477
478class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
479  op,
480  (outs rc:$vdst),
481  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
482  asm#" $vdst, $addr, $data0, $offset, [M0]",
483  []> {
484
485  let data1 = 0;
486  let mayStore = 1;
487  let mayLoad = 1;
488}
489
490class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
491  op,
492  (outs),
493  (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
494   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
495   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
496  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
497     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
498  []> {
499  let mayStore = 1;
500  let mayLoad = 0;
501}
502
503multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
504
505  let lds = 0, mayLoad = 1 in {
506
507    let addr64 = 0 in {
508
509      let offen = 0, idxen = 0 in {
510        def _OFFSET : MUBUF <op, (outs regClass:$vdata),
511                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
512                             u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
513                             i1imm:$slc, i1imm:$tfe),
514                             asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
515      }
516
517      let offen = 1, idxen = 0, offset = 0 in {
518        def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
519                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
520                             SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
521                             i1imm:$tfe),
522                             asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
523      }
524
525      let offen = 0, idxen = 1 in {
526        def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
527                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
528                             u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
529                             i1imm:$slc, i1imm:$tfe),
530                             asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
531      }
532
533      let offen = 1, idxen = 1 in {
534        def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
535                             (ins SReg_128:$srsrc, VReg_64:$vaddr,
536                             SSrc_32:$soffset, i1imm:$glc,
537                             i1imm:$slc, i1imm:$tfe),
538                             asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
539      }
540    }
541
542    let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
543      def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
544                           (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
545                           asm#" $vdata, $srsrc + $vaddr + $offset", []>;
546    }
547  }
548}
549
550class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
551    MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
552                            u16imm:$offset),
553          name#" $vdata, $srsrc + $vaddr + $offset",
554         []> {
555
556  let mayLoad = 0;
557  let mayStore = 1;
558
559  // Encoding
560  let offen = 0;
561  let idxen = 0;
562  let glc = 0;
563  let addr64 = 1;
564  let lds = 0;
565  let slc = 0;
566  let tfe = 0;
567  let soffset = 128; // ZERO
568}
569
570class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
571  op,
572  (outs regClass:$dst),
573  (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
574       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
575       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
576  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
577     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
578  []> {
579  let mayLoad = 1;
580  let mayStore = 0;
581}
582
583class MIMG_Mask <string op, int channels> {
584  string Op = op;
585  int Channels = channels;
586}
587
588class MIMG_NoSampler_Helper <bits<7> op, string asm,
589                             RegisterClass dst_rc,
590                             RegisterClass src_rc> : MIMG <
591  op,
592  (outs dst_rc:$vdata),
593  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
594       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
595       SReg_256:$srsrc),
596  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
597     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
598  []> {
599  let SSAMP = 0;
600  let mayLoad = 1;
601  let mayStore = 0;
602  let hasPostISelHook = 1;
603}
604
605multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
606                                      RegisterClass dst_rc,
607                                      int channels> {
608  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
609            MIMG_Mask<asm#"_V1", channels>;
610  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
611            MIMG_Mask<asm#"_V2", channels>;
612  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
613            MIMG_Mask<asm#"_V4", channels>;
614}
615
616multiclass MIMG_NoSampler <bits<7> op, string asm> {
617  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
618  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
619  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
620  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
621}
622
623class MIMG_Sampler_Helper <bits<7> op, string asm,
624                           RegisterClass dst_rc,
625                           RegisterClass src_rc> : MIMG <
626  op,
627  (outs dst_rc:$vdata),
628  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
629       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
630       SReg_256:$srsrc, SReg_128:$ssamp),
631  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
632     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
633  []> {
634  let mayLoad = 1;
635  let mayStore = 0;
636  let hasPostISelHook = 1;
637}
638
639multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
640                                    RegisterClass dst_rc,
641                                    int channels> {
642  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
643            MIMG_Mask<asm#"_V1", channels>;
644  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
645            MIMG_Mask<asm#"_V2", channels>;
646  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
647            MIMG_Mask<asm#"_V4", channels>;
648  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
649            MIMG_Mask<asm#"_V8", channels>;
650  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
651            MIMG_Mask<asm#"_V16", channels>;
652}
653
654multiclass MIMG_Sampler <bits<7> op, string asm> {
655  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
656  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
657  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
658  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
659}
660
661//===----------------------------------------------------------------------===//
662// Vector instruction mappings
663//===----------------------------------------------------------------------===//
664
665// Maps an opcode in e32 form to its e64 equivalent
666def getVOPe64 : InstrMapping {
667  let FilterClass = "VOP";
668  let RowFields = ["OpName"];
669  let ColFields = ["Size"];
670  let KeyCol = ["4"];
671  let ValueCols = [["8"]];
672}
673
674// Maps an original opcode to its commuted version
675def getCommuteRev : InstrMapping {
676  let FilterClass = "VOP2_REV";
677  let RowFields = ["RevOp"];
678  let ColFields = ["IsOrig"];
679  let KeyCol = ["1"];
680  let ValueCols = [["0"]];
681}
682
683def getMaskedMIMGOp : InstrMapping {
684  let FilterClass = "MIMG_Mask";
685  let RowFields = ["Op"];
686  let ColFields = ["Channels"];
687  let KeyCol = ["4"];
688  let ValueCols = [["1"], ["2"], ["3"] ];
689}
690
691// Maps an commuted opcode to its original version
692def getCommuteOrig : InstrMapping {
693  let FilterClass = "VOP2_REV";
694  let RowFields = ["RevOp"];
695  let ColFields = ["IsOrig"];
696  let KeyCol = ["0"];
697  let ValueCols = [["1"]];
698}
699
700def isDS : InstrMapping {
701  let FilterClass = "DS";
702  let RowFields = ["Inst"];
703  let ColFields = ["Size"];
704  let KeyCol = ["8"];
705  let ValueCols = [["8"]];
706}
707
708def getMCOpcode : InstrMapping {
709  let FilterClass = "SIMCInstr";
710  let RowFields = ["PseudoInstr"];
711  let ColFields = ["Subtarget"];
712  let KeyCol = [!cast<string>(SISubtarget.NONE)];
713  let ValueCols = [[!cast<string>(SISubtarget.SI)]];
714}
715
716include "SIInstructions.td"
717