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