1249259Sdim//===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim
10249259Sdim//===----------------------------------------------------------------------===//
11249259Sdim// SI DAG Nodes
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdim// SMRD takes a 64bit memory address and can only add an 32bit offset
15249259Sdimdef SIadd64bit32bit : SDNode<"ISD::ADD",
16249259Sdim  SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVT<0, i64>, SDTCisVT<2, i32>]>
17249259Sdim>;
18249259Sdim
19263508Sdimdef SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
20263508Sdim  SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, i128>, SDTCisVT<2, i32>]>,
21263508Sdim                      [SDNPMayLoad, SDNPMemOperand]
22263508Sdim>;
23263508Sdim
24263508Sdimdef SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
25263508Sdim  SDTypeProfile<0, 13,
26263508Sdim    [SDTCisVT<0, i128>,   // rsrc(SGPR)
27263508Sdim     SDTCisVT<1, iAny>,   // vdata(VGPR)
28263508Sdim     SDTCisVT<2, i32>,    // num_channels(imm)
29263508Sdim     SDTCisVT<3, i32>,    // vaddr(VGPR)
30263508Sdim     SDTCisVT<4, i32>,    // soffset(SGPR)
31263508Sdim     SDTCisVT<5, i32>,    // inst_offset(imm)
32263508Sdim     SDTCisVT<6, i32>,    // dfmt(imm)
33263508Sdim     SDTCisVT<7, i32>,    // nfmt(imm)
34263508Sdim     SDTCisVT<8, i32>,    // offen(imm)
35263508Sdim     SDTCisVT<9, i32>,    // idxen(imm)
36263508Sdim     SDTCisVT<10, i32>,   // glc(imm)
37263508Sdim     SDTCisVT<11, i32>,   // slc(imm)
38263508Sdim     SDTCisVT<12, i32>    // tfe(imm)
39263508Sdim    ]>,
40263508Sdim  [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
41263508Sdim>;
42263508Sdim
43263508Sdimdef SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
44263508Sdim  SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, i128>, SDTCisVT<2, i16>,
45263508Sdim                       SDTCisVT<3, i32>]>
46263508Sdim>;
47263508Sdim
48263508Sdimclass SDSample<string opcode> : SDNode <opcode,
49263508Sdim  SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
50263508Sdim                       SDTCisVT<3, i128>, SDTCisVT<4, i32>]>
51263508Sdim>;
52263508Sdim
53263508Sdimdef SIsample : SDSample<"AMDGPUISD::SAMPLE">;
54263508Sdimdef SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
55263508Sdimdef SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
56263508Sdimdef SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
57263508Sdim
58249259Sdim// Transformation function, extract the lower 32bit of a 64bit immediate
59249259Sdimdef LO32 : SDNodeXForm<imm, [{
60249259Sdim  return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
61249259Sdim}]>;
62249259Sdim
63263508Sdimdef LO32f : SDNodeXForm<fpimm, [{
64263508Sdim  APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
65263508Sdim  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
66263508Sdim}]>;
67263508Sdim
68249259Sdim// Transformation function, extract the upper 32bit of a 64bit immediate
69249259Sdimdef HI32 : SDNodeXForm<imm, [{
70249259Sdim  return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
71249259Sdim}]>;
72249259Sdim
73263508Sdimdef HI32f : SDNodeXForm<fpimm, [{
74263508Sdim  APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
75263508Sdim  return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
76263508Sdim}]>;
77251662Sdim
78249259Sdimdef IMM8bitDWORD : ImmLeaf <
79249259Sdim  i32, [{
80249259Sdim    return (Imm & ~0x3FC) == 0;
81249259Sdim  }], SDNodeXForm<imm, [{
82249259Sdim    return CurDAG->getTargetConstant(
83249259Sdim      N->getZExtValue() >> 2, MVT::i32);
84249259Sdim  }]>
85249259Sdim>;
86249259Sdim
87263508Sdimdef as_i1imm : SDNodeXForm<imm, [{
88263508Sdim  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
89263508Sdim}]>;
90263508Sdim
91263508Sdimdef as_i8imm : SDNodeXForm<imm, [{
92263508Sdim  return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
93263508Sdim}]>;
94263508Sdim
95263508Sdimdef as_i16imm : SDNodeXForm<imm, [{
96263508Sdim  return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
97263508Sdim}]>;
98263508Sdim
99263508Sdimdef IMM12bit : PatLeaf <(imm),
100263508Sdim  [{return isUInt<12>(N->getZExtValue());}]
101249259Sdim>;
102249259Sdim
103249259Sdimclass InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
104263508Sdim  return
105263508Sdim    (*(const SITargetLowering *)getTargetLowering()).analyzeImmediate(N) == 0;
106249259Sdim}]>;
107249259Sdim
108263508Sdimclass SGPRImm <dag frag> : PatLeaf<frag, [{
109263508Sdim  if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
110263508Sdim      AMDGPUSubtarget::SOUTHERN_ISLANDS) {
111263508Sdim    return false;
112263508Sdim  }
113263508Sdim  const SIRegisterInfo *SIRI =
114263508Sdim                       static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
115263508Sdim  for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
116263508Sdim                                                U != E; ++U) {
117263508Sdim    if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
118263508Sdim      return true;
119263508Sdim    }
120263508Sdim  }
121263508Sdim  return false;
122263508Sdim}]>;
123263508Sdim
124263508Sdimdef FRAMEri64 : Operand<iPTR> {
125263508Sdim  let MIOperandInfo = (ops SReg_32:$ptr, i32imm:$index);
126263508Sdim}
127263508Sdim
128249259Sdim//===----------------------------------------------------------------------===//
129249259Sdim// SI assembler operands
130249259Sdim//===----------------------------------------------------------------------===//
131249259Sdim
132249259Sdimdef SIOperand {
133249259Sdim  int ZERO = 0x80;
134249259Sdim  int VCC = 0x6A;
135249259Sdim}
136249259Sdim
137249259Sdiminclude "SIInstrFormats.td"
138249259Sdim
139249259Sdim//===----------------------------------------------------------------------===//
140249259Sdim//
141249259Sdim// SI Instruction multiclass helpers.
142249259Sdim//
143249259Sdim// Instructions with _32 take 32-bit operands.
144249259Sdim// Instructions with _64 take 64-bit operands.
145249259Sdim//
146249259Sdim// VOP_* instructions can use either a 32-bit or 64-bit encoding.  The 32-bit
147249259Sdim// encoding is the standard encoding, but instruction that make use of
148249259Sdim// any of the instruction modifiers must use the 64-bit encoding.
149249259Sdim//
150249259Sdim// Instructions with _e32 use the 32-bit encoding.
151249259Sdim// Instructions with _e64 use the 64-bit encoding.
152249259Sdim//
153249259Sdim//===----------------------------------------------------------------------===//
154249259Sdim
155249259Sdim//===----------------------------------------------------------------------===//
156249259Sdim// Scalar classes
157249259Sdim//===----------------------------------------------------------------------===//
158249259Sdim
159249259Sdimclass SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
160249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
161249259Sdim  opName#" $dst, $src0", pattern
162249259Sdim>;
163249259Sdim
164249259Sdimclass SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
165249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
166249259Sdim  opName#" $dst, $src0", pattern
167249259Sdim>;
168249259Sdim
169249259Sdimclass SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
170249259Sdim  op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
171249259Sdim  opName#" $dst, $src0, $src1", pattern
172249259Sdim>;
173249259Sdim
174249259Sdimclass SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
175249259Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
176249259Sdim  opName#" $dst, $src0, $src1", pattern
177249259Sdim>;
178249259Sdim
179263508Sdimclass SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
180263508Sdim  op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
181263508Sdim  opName#" $dst, $src0, $src1", pattern
182263508Sdim>;
183263508Sdim
184249259Sdimclass SOPC_32 <bits<7> op, string opName, list<dag> pattern> : SOPC <
185249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
186249259Sdim  opName#" $dst, $src0, $src1", pattern
187249259Sdim>;
188249259Sdim
189249259Sdimclass SOPC_64 <bits<7> op, string opName, list<dag> pattern> : SOPC <
190249259Sdim  op, (outs SCCReg:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
191249259Sdim  opName#" $dst, $src0, $src1", pattern
192249259Sdim>;
193249259Sdim
194249259Sdimclass SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
195249259Sdim  op, (outs SReg_32:$dst), (ins i16imm:$src0),
196249259Sdim  opName#" $dst, $src0", pattern
197249259Sdim>;
198249259Sdim
199249259Sdimclass SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
200249259Sdim  op, (outs SReg_64:$dst), (ins i16imm:$src0),
201249259Sdim  opName#" $dst, $src0", pattern
202249259Sdim>;
203249259Sdim
204249259Sdimmulticlass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
205249259Sdim                        RegisterClass dstClass> {
206249259Sdim  def _IMM : SMRD <
207249259Sdim    op, 1, (outs dstClass:$dst),
208249259Sdim    (ins baseClass:$sbase, i32imm:$offset),
209249259Sdim    asm#" $dst, $sbase, $offset", []
210249259Sdim  >;
211249259Sdim
212249259Sdim  def _SGPR : SMRD <
213249259Sdim    op, 0, (outs dstClass:$dst),
214249259Sdim    (ins baseClass:$sbase, SReg_32:$soff),
215249259Sdim    asm#" $dst, $sbase, $soff", []
216249259Sdim  >;
217249259Sdim}
218249259Sdim
219249259Sdim//===----------------------------------------------------------------------===//
220249259Sdim// Vector ALU classes
221249259Sdim//===----------------------------------------------------------------------===//
222249259Sdim
223249259Sdimclass VOP <string opName> {
224249259Sdim  string OpName = opName;
225249259Sdim}
226249259Sdim
227249259Sdimclass VOP2_REV <string revOp, bit isOrig> {
228249259Sdim  string RevOp = revOp;
229249259Sdim  bit IsOrig = isOrig;
230249259Sdim}
231249259Sdim
232249259Sdimmulticlass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
233249259Sdim                        string opName, list<dag> pattern> {
234249259Sdim
235249259Sdim  def _e32 : VOP1 <
236249259Sdim    op, (outs drc:$dst), (ins src:$src0),
237249259Sdim    opName#"_e32 $dst, $src0", pattern
238249259Sdim  >, VOP <opName>;
239249259Sdim
240249259Sdim  def _e64 : VOP3 <
241249259Sdim    {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
242249259Sdim    (outs drc:$dst),
243249259Sdim    (ins src:$src0,
244249259Sdim         i32imm:$abs, i32imm:$clamp,
245249259Sdim         i32imm:$omod, i32imm:$neg),
246249259Sdim    opName#"_e64 $dst, $src0, $abs, $clamp, $omod, $neg", []
247249259Sdim  >, VOP <opName> {
248263508Sdim    let src1 = SIOperand.ZERO;
249263508Sdim    let src2 = SIOperand.ZERO;
250249259Sdim  }
251249259Sdim}
252249259Sdim
253249259Sdimmulticlass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
254249259Sdim  : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
255249259Sdim
256249259Sdimmulticlass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
257249259Sdim  : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
258249259Sdim
259263508Sdimmulticlass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
260263508Sdim  : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
261263508Sdim
262263508Sdimmulticlass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
263263508Sdim  : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
264263508Sdim
265249259Sdimmulticlass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
266249259Sdim                        string opName, list<dag> pattern, string revOp> {
267249259Sdim  def _e32 : VOP2 <
268249259Sdim    op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
269249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
270249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
271249259Sdim
272249259Sdim  def _e64 : VOP3 <
273249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
274249259Sdim    (outs vrc:$dst),
275249259Sdim    (ins arc:$src0, arc:$src1,
276249259Sdim         i32imm:$abs, i32imm:$clamp,
277249259Sdim         i32imm:$omod, i32imm:$neg),
278249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
279249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
280263508Sdim    let src2 = SIOperand.ZERO;
281249259Sdim  }
282249259Sdim}
283249259Sdim
284249259Sdimmulticlass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
285249259Sdim                    string revOp = opName>
286249259Sdim  : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
287249259Sdim
288249259Sdimmulticlass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
289249259Sdim                    string revOp = opName>
290249259Sdim  : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
291249259Sdim
292249259Sdimmulticlass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
293266715Sdim                     RegisterClass src0_rc, string revOp = opName> {
294249259Sdim
295249259Sdim  def _e32 : VOP2 <
296266715Sdim    op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
297249259Sdim    opName#"_e32 $dst, $src0, $src1", pattern
298249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
299249259Sdim
300249259Sdim  def _e64 : VOP3b <
301249259Sdim    {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
302249259Sdim    (outs VReg_32:$dst),
303249259Sdim    (ins VSrc_32:$src0, VSrc_32:$src1,
304249259Sdim         i32imm:$abs, i32imm:$clamp,
305249259Sdim         i32imm:$omod, i32imm:$neg),
306249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg", []
307249259Sdim  >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
308263508Sdim    let src2 = SIOperand.ZERO;
309249259Sdim    /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
310249259Sdim       can write it into any SGPR. We currently don't use the carry out,
311249259Sdim       so for now hardcode it to VCC as well */
312263508Sdim    let sdst = SIOperand.VCC;
313249259Sdim  }
314249259Sdim}
315249259Sdim
316249259Sdimmulticlass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
317249259Sdim                        string opName, ValueType vt, PatLeaf cond> {
318249259Sdim
319249259Sdim  def _e32 : VOPC <
320249259Sdim    op, (ins arc:$src0, vrc:$src1),
321249259Sdim    opName#"_e32 $dst, $src0, $src1", []
322249259Sdim  >, VOP <opName>;
323249259Sdim
324249259Sdim  def _e64 : VOP3 <
325249259Sdim    {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
326249259Sdim    (outs SReg_64:$dst),
327249259Sdim    (ins arc:$src0, arc:$src1,
328249259Sdim         InstFlag:$abs, InstFlag:$clamp,
329249259Sdim         InstFlag:$omod, InstFlag:$neg),
330249259Sdim    opName#"_e64 $dst, $src0, $src1, $abs, $clamp, $omod, $neg",
331249259Sdim    !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
332249259Sdim      [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
333249259Sdim    )
334249259Sdim  >, VOP <opName> {
335263508Sdim    let src2 = SIOperand.ZERO;
336249259Sdim  }
337249259Sdim}
338249259Sdim
339249259Sdimmulticlass VOPC_32 <bits<8> op, string opName,
340249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
341249259Sdim  : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
342249259Sdim
343249259Sdimmulticlass VOPC_64 <bits<8> op, string opName,
344249259Sdim  ValueType vt = untyped, PatLeaf cond = COND_NULL>
345249259Sdim  : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
346249259Sdim
347249259Sdimclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
348249259Sdim  op, (outs VReg_32:$dst),
349249259Sdim  (ins VSrc_32:$src0, VSrc_32:$src1, VSrc_32:$src2,
350251662Sdim   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
351249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
352249259Sdim>, VOP <opName>;
353249259Sdim
354263508Sdimclass VOP3_64_Shift <bits <9> op, string opName, list<dag> pattern> : VOP3 <
355263508Sdim  op, (outs VReg_64:$dst),
356263508Sdim  (ins VSrc_64:$src0, VSrc_32:$src1),
357263508Sdim  opName#" $dst, $src0, $src1", pattern
358263508Sdim>, VOP <opName> {
359263508Sdim
360263508Sdim  let src2 = SIOperand.ZERO;
361263508Sdim  let abs = 0;
362263508Sdim  let clamp = 0;
363263508Sdim  let omod = 0;
364263508Sdim  let neg = 0;
365263508Sdim}
366263508Sdim
367249259Sdimclass VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
368249259Sdim  op, (outs VReg_64:$dst),
369249259Sdim  (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
370251662Sdim   InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
371249259Sdim  opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
372249259Sdim>, VOP <opName>;
373249259Sdim
374249259Sdim//===----------------------------------------------------------------------===//
375249259Sdim// Vector I/O classes
376249259Sdim//===----------------------------------------------------------------------===//
377249259Sdim
378263508Sdimclass DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
379263508Sdim  op,
380263508Sdim  (outs regClass:$vdst),
381263508Sdim  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
382263508Sdim       i8imm:$offset0, i8imm:$offset1),
383263508Sdim  asm#" $vdst, $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
384263508Sdim  []> {
385263508Sdim  let mayLoad = 1;
386263508Sdim  let mayStore = 0;
387263508Sdim}
388263508Sdim
389263508Sdimclass DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
390263508Sdim  op,
391263508Sdim  (outs),
392263508Sdim  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1,
393263508Sdim       i8imm:$offset0, i8imm:$offset1),
394263508Sdim  asm#" $gds, $addr, $data0, $data1, $offset0, $offset1, [M0]",
395263508Sdim  []> {
396263508Sdim  let mayStore = 1;
397263508Sdim  let mayLoad = 0;
398263508Sdim  let vdst = 0;
399263508Sdim}
400263508Sdim
401263508Sdimclass DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS <
402263508Sdim  op,
403263508Sdim  (outs rc:$vdst),
404263508Sdim  (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, i8imm:$offset0,
405263508Sdim       i8imm:$offset1),
406263508Sdim  asm#" $gds, $vdst, $addr, $data0, $offset0, $offset1, [M0]",
407263508Sdim  []> {
408263508Sdim  let mayStore = 1;
409263508Sdim  let mayLoad = 1;
410263508Sdim  let data1 = 0;
411263508Sdim}
412263508Sdim
413249259Sdimclass MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
414249259Sdim  op,
415249259Sdim  (outs),
416249259Sdim  (ins regClass:$vdata, i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
417249259Sdim   i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
418249259Sdim   SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
419249259Sdim  asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
420249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
421249259Sdim  []> {
422249259Sdim  let mayStore = 1;
423249259Sdim  let mayLoad = 0;
424249259Sdim}
425249259Sdim
426263508Sdimmulticlass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
427263508Sdim
428266715Sdim  let lds = 0, mayLoad = 1 in {
429263508Sdim
430266715Sdim    let addr64 = 0 in {
431263508Sdim
432266715Sdim      let offen = 0, idxen = 0 in {
433266715Sdim        def _OFFSET : MUBUF <op, (outs regClass:$vdata),
434266715Sdim                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
435266715Sdim                             i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
436266715Sdim                             i1imm:$slc, i1imm:$tfe),
437266715Sdim                             asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
438266715Sdim      }
439263508Sdim
440266715Sdim      let offen = 1, idxen = 0, offset = 0 in {
441266715Sdim        def _OFFEN  : MUBUF <op, (outs regClass:$vdata),
442266715Sdim                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
443266715Sdim                             SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
444266715Sdim                             i1imm:$tfe),
445266715Sdim                             asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
446266715Sdim      }
447266715Sdim
448266715Sdim      let offen = 0, idxen = 1 in {
449266715Sdim        def _IDXEN  : MUBUF <op, (outs regClass:$vdata),
450266715Sdim                             (ins SReg_128:$srsrc, VReg_32:$vaddr,
451266715Sdim                             i16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
452266715Sdim                             i1imm:$slc, i1imm:$tfe),
453266715Sdim                             asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
454266715Sdim      }
455266715Sdim
456266715Sdim      let offen = 1, idxen = 1 in {
457266715Sdim        def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
458266715Sdim                             (ins SReg_128:$srsrc, VReg_64:$vaddr,
459266715Sdim                             SSrc_32:$soffset, i1imm:$glc,
460266715Sdim                             i1imm:$slc, i1imm:$tfe),
461266715Sdim                             asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
462266715Sdim      }
463266715Sdim    }
464266715Sdim
465266715Sdim    let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
466266715Sdim      def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
467266715Sdim                           (ins SReg_128:$srsrc, VReg_64:$vaddr, i16imm:$offset),
468266715Sdim                           asm#" $vdata, $srsrc + $vaddr + $offset", []>;
469266715Sdim    }
470263508Sdim  }
471249259Sdim}
472249259Sdim
473263508Sdimclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
474263508Sdim    MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
475263508Sdim                            i16imm:$offset),
476263508Sdim          name#" $vdata, $srsrc + $vaddr + $offset",
477263508Sdim         []> {
478251662Sdim
479251662Sdim  let mayLoad = 0;
480251662Sdim  let mayStore = 1;
481251662Sdim
482251662Sdim  // Encoding
483251662Sdim  let offen = 0;
484251662Sdim  let idxen = 0;
485251662Sdim  let glc = 0;
486251662Sdim  let addr64 = 1;
487251662Sdim  let lds = 0;
488251662Sdim  let slc = 0;
489251662Sdim  let tfe = 0;
490251662Sdim  let soffset = 128; // ZERO
491251662Sdim}
492251662Sdim
493249259Sdimclass MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
494249259Sdim  op,
495249259Sdim  (outs regClass:$dst),
496249259Sdim  (ins i16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
497249259Sdim       i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
498249259Sdim       i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
499249259Sdim  asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
500249259Sdim     #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
501249259Sdim  []> {
502249259Sdim  let mayLoad = 1;
503249259Sdim  let mayStore = 0;
504249259Sdim}
505249259Sdim
506263508Sdimclass MIMG_Mask <string op, int channels> {
507263508Sdim  string Op = op;
508263508Sdim  int Channels = channels;
509263508Sdim}
510263508Sdim
511263508Sdimclass MIMG_NoSampler_Helper <bits<7> op, string asm,
512263508Sdim                             RegisterClass dst_rc,
513263508Sdim                             RegisterClass src_rc> : MIMG <
514249259Sdim  op,
515263508Sdim  (outs dst_rc:$vdata),
516249259Sdim  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
517263508Sdim       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
518251662Sdim       SReg_256:$srsrc),
519251662Sdim  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
520251662Sdim     #" $tfe, $lwe, $slc, $vaddr, $srsrc",
521251662Sdim  []> {
522251662Sdim  let SSAMP = 0;
523251662Sdim  let mayLoad = 1;
524251662Sdim  let mayStore = 0;
525251662Sdim  let hasPostISelHook = 1;
526251662Sdim}
527251662Sdim
528263508Sdimmulticlass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
529263508Sdim                                      RegisterClass dst_rc,
530263508Sdim                                      int channels> {
531263508Sdim  def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
532263508Sdim            MIMG_Mask<asm#"_V1", channels>;
533263508Sdim  def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
534263508Sdim            MIMG_Mask<asm#"_V2", channels>;
535263508Sdim  def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
536263508Sdim            MIMG_Mask<asm#"_V4", channels>;
537263508Sdim}
538263508Sdim
539263508Sdimmulticlass MIMG_NoSampler <bits<7> op, string asm> {
540263508Sdim  defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
541263508Sdim  defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
542263508Sdim  defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
543263508Sdim  defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
544263508Sdim}
545263508Sdim
546263508Sdimclass MIMG_Sampler_Helper <bits<7> op, string asm,
547263508Sdim                           RegisterClass dst_rc,
548263508Sdim                           RegisterClass src_rc> : MIMG <
549251662Sdim  op,
550263508Sdim  (outs dst_rc:$vdata),
551251662Sdim  (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
552263508Sdim       i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
553249259Sdim       SReg_256:$srsrc, SReg_128:$ssamp),
554249259Sdim  asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
555249259Sdim     #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
556249259Sdim  []> {
557249259Sdim  let mayLoad = 1;
558249259Sdim  let mayStore = 0;
559251662Sdim  let hasPostISelHook = 1;
560249259Sdim}
561249259Sdim
562263508Sdimmulticlass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
563263508Sdim                                    RegisterClass dst_rc,
564263508Sdim                                    int channels> {
565263508Sdim  def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
566263508Sdim            MIMG_Mask<asm#"_V1", channels>;
567263508Sdim  def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
568263508Sdim            MIMG_Mask<asm#"_V2", channels>;
569263508Sdim  def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
570263508Sdim            MIMG_Mask<asm#"_V4", channels>;
571263508Sdim  def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
572263508Sdim            MIMG_Mask<asm#"_V8", channels>;
573263508Sdim  def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
574263508Sdim            MIMG_Mask<asm#"_V16", channels>;
575263508Sdim}
576263508Sdim
577263508Sdimmulticlass MIMG_Sampler <bits<7> op, string asm> {
578263508Sdim  defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
579263508Sdim  defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
580263508Sdim  defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
581263508Sdim  defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
582263508Sdim}
583263508Sdim
584249259Sdim//===----------------------------------------------------------------------===//
585249259Sdim// Vector instruction mappings
586249259Sdim//===----------------------------------------------------------------------===//
587249259Sdim
588249259Sdim// Maps an opcode in e32 form to its e64 equivalent
589249259Sdimdef getVOPe64 : InstrMapping {
590249259Sdim  let FilterClass = "VOP";
591249259Sdim  let RowFields = ["OpName"];
592249259Sdim  let ColFields = ["Size"];
593249259Sdim  let KeyCol = ["4"];
594249259Sdim  let ValueCols = [["8"]];
595249259Sdim}
596249259Sdim
597249259Sdim// Maps an original opcode to its commuted version
598249259Sdimdef getCommuteRev : InstrMapping {
599249259Sdim  let FilterClass = "VOP2_REV";
600249259Sdim  let RowFields = ["RevOp"];
601249259Sdim  let ColFields = ["IsOrig"];
602249259Sdim  let KeyCol = ["1"];
603249259Sdim  let ValueCols = [["0"]];
604249259Sdim}
605249259Sdim
606263508Sdimdef getMaskedMIMGOp : InstrMapping {
607263508Sdim  let FilterClass = "MIMG_Mask";
608263508Sdim  let RowFields = ["Op"];
609263508Sdim  let ColFields = ["Channels"];
610263508Sdim  let KeyCol = ["4"];
611263508Sdim  let ValueCols = [["1"], ["2"], ["3"] ];
612263508Sdim}
613263508Sdim
614249259Sdim// Maps an commuted opcode to its original version
615249259Sdimdef getCommuteOrig : InstrMapping {
616249259Sdim  let FilterClass = "VOP2_REV";
617249259Sdim  let RowFields = ["RevOp"];
618249259Sdim  let ColFields = ["IsOrig"];
619249259Sdim  let KeyCol = ["0"];
620249259Sdim  let ValueCols = [["1"]];
621249259Sdim}
622249259Sdim
623249259Sdiminclude "SIInstructions.td"
624