1 //===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Execpt for the NONE field, this must be kept in sync with the SISubtarget enum
11 // in AMDGPUMCInstLower.h
17 //===----------------------------------------------------------------------===//
19 //===----------------------------------------------------------------------===//
21 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
22 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
23 [SDNPMayLoad, SDNPMemOperand]
26 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
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)
42 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
45 def SIload_input : SDNode<"AMDGPUISD::LOAD_INPUT",
46 SDTypeProfile<1, 3, [SDTCisVT<0, v4f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i16>,
50 class SDSample<string opcode> : SDNode <opcode,
51 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v32i8>,
52 SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
55 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
56 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
57 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
58 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
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);
65 def LO32f : SDNodeXForm<fpimm, [{
66 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
67 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
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);
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);
80 def IMM8bitDWORD : PatLeaf <(imm),
81 [{return (N->getZExtValue() & ~0x3FC) == 0;}]
84 def as_dword_i32imm : SDNodeXForm<imm, [{
85 return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
88 def as_i1imm : SDNodeXForm<imm, [{
89 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
92 def as_i8imm : SDNodeXForm<imm, [{
93 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
96 def as_i16imm : SDNodeXForm<imm, [{
97 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
100 def as_i32imm: SDNodeXForm<imm, [{
101 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
104 def IMM8bit : PatLeaf <(imm),
105 [{return isUInt<8>(N->getZExtValue());}]
108 def IMM12bit : PatLeaf <(imm),
109 [{return isUInt<12>(N->getZExtValue());}]
112 def IMM16bit : PatLeaf <(imm),
113 [{return isUInt<16>(N->getZExtValue());}]
116 def IMM32bit : PatLeaf <(imm),
117 [{return isUInt<32>(N->getZExtValue());}]
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)
125 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
126 return isInlineImmediate(N);
129 class SGPRImm <dag frag> : PatLeaf<frag, [{
130 if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
131 AMDGPUSubtarget::SOUTHERN_ISLANDS) {
134 const SIRegisterInfo *SIRI =
135 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
136 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
138 if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
145 def FRAMEri32 : Operand<iPTR> {
146 let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
149 //===----------------------------------------------------------------------===//
150 // SI assembler operands
151 //===----------------------------------------------------------------------===//
158 include "SIInstrFormats.td"
160 //===----------------------------------------------------------------------===//
162 // SI Instruction multiclass helpers.
164 // Instructions with _32 take 32-bit operands.
165 // Instructions with _64 take 64-bit operands.
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.
171 // Instructions with _e32 use the 32-bit encoding.
172 // Instructions with _e64 use the 64-bit encoding.
174 //===----------------------------------------------------------------------===//
176 //===----------------------------------------------------------------------===//
178 //===----------------------------------------------------------------------===//
180 class 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
185 class 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
190 // 64-bit input, 32-bit output.
191 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
192 op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
193 opName#" $dst, $src0", pattern
196 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
197 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
198 opName#" $dst, $src0, $src1", pattern
201 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
202 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
203 opName#" $dst, $src0, $src1", pattern
206 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
207 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
208 opName#" $dst, $src0, $src1", pattern
212 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
213 string opName, PatLeaf cond> : SOPC <
214 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
215 opName#" $dst, $src0, $src1", []>;
217 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
218 : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
220 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
221 : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
223 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
224 op, (outs SReg_32:$dst), (ins i16imm:$src0),
225 opName#" $dst, $src0", pattern
228 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
229 op, (outs SReg_64:$dst), (ins i16imm:$src0),
230 opName#" $dst, $src0", pattern
233 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
234 RegisterClass dstClass> {
236 op, 1, (outs dstClass:$dst),
237 (ins baseClass:$sbase, u32imm:$offset),
238 asm#" $dst, $sbase, $offset", []
242 op, 0, (outs dstClass:$dst),
243 (ins baseClass:$sbase, SReg_32:$soff),
244 asm#" $dst, $sbase, $soff", []
248 //===----------------------------------------------------------------------===//
249 // Vector ALU classes
250 //===----------------------------------------------------------------------===//
252 class VOP <string opName> {
253 string OpName = opName;
256 class VOP2_REV <string revOp, bit isOrig> {
257 string RevOp = revOp;
261 class SIMCInstr <string pseudo, int subtarget> {
262 string PseudoInstr = pseudo;
263 int Subtarget = subtarget;
266 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
269 def "" : InstSI <outs, ins, "", pattern>, VOP <opName>,
270 SIMCInstr<OpName, SISubtarget.NONE> {
274 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
278 // This must always be right before the operand being input modified.
279 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
280 let PrintMethod = "printOperandAndMods";
283 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
284 string opName, list<dag> pattern> {
287 op, (outs drc:$dst), (ins src:$src0),
288 opName#"_e32 $dst, $src0", pattern
292 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
294 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
295 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
297 let src1 = SIOperand.ZERO;
298 let src2 = SIOperand.ZERO;
302 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
303 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
305 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
306 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
308 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
309 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
311 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
312 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
314 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
315 string opName, list<dag> pattern, string revOp> {
317 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
318 opName#"_e32 $dst, $src0, $src1", pattern
319 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
322 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
324 (ins InputMods:$src0_modifiers, arc:$src0,
325 InputMods:$src1_modifiers, arc:$src1,
326 i32imm:$clamp, i32imm:$omod),
327 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
328 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
329 let src2 = SIOperand.ZERO;
333 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
334 string revOp = opName>
335 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
337 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
338 string revOp = opName>
339 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
341 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
342 RegisterClass src0_rc, string revOp = opName> {
345 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
346 opName#"_e32 $dst, $src0, $src1", pattern
347 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
350 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
352 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
353 InputMods:$src1_modifiers, VSrc_32:$src1,
354 i32imm:$clamp, i32imm:$omod),
355 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
356 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
357 let src2 = SIOperand.ZERO;
358 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
359 can write it into any SGPR. We currently don't use the carry out,
360 so for now hardcode it to VCC as well */
361 let sdst = SIOperand.VCC;
365 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
366 string opName, ValueType vt, PatLeaf cond> {
369 op, (ins arc:$src0, vrc:$src1),
370 opName#"_e32 $dst, $src0, $src1", []
374 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
376 (ins InputMods:$src0_modifiers, arc:$src0,
377 InputMods:$src1_modifiers, arc:$src1,
378 InstFlag:$clamp, InstFlag:$omod),
379 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
380 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
381 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
384 let src2 = SIOperand.ZERO;
385 let src2_modifiers = 0;
389 multiclass VOPC_32 <bits<8> op, string opName,
390 ValueType vt = untyped, PatLeaf cond = COND_NULL>
391 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
393 multiclass VOPC_64 <bits<8> op, string opName,
394 ValueType vt = untyped, PatLeaf cond = COND_NULL>
395 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
397 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
398 op, (outs VReg_32:$dst),
399 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
400 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
401 InstFlag:$clamp, InstFlag:$omod),
402 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
405 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
406 op, (outs VReg_64:$dst),
407 (ins VSrc_64:$src0, VSrc_32:$src1),
408 opName#" $dst, $src0, $src1", pattern
411 let src2 = SIOperand.ZERO;
412 let src0_modifiers = 0;
417 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
418 op, (outs VReg_64:$dst),
419 (ins VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
420 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
421 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
424 //===----------------------------------------------------------------------===//
425 // Vector I/O classes
426 //===----------------------------------------------------------------------===//
428 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
429 DS <op, outs, ins, asm, pat> {
432 // Single load interpret the 2 i8imm operands as a single i16 offset.
433 let offset0 = offset{7-0};
434 let offset1 = offset{15-8};
437 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
439 (outs regClass:$vdst),
440 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
441 asm#" $vdst, $addr, $offset, [M0]",
449 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
451 (outs regClass:$vdst),
452 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
453 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
461 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
464 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
465 asm#" $addr, $data0, $offset [M0]",
473 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
476 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
477 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
484 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
487 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
488 asm#" $vdst, $addr, $data0, $offset, [M0]",
496 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
499 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
500 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
501 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
502 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
503 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
509 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
511 let lds = 0, mayLoad = 1 in {
515 let offen = 0, idxen = 0 in {
516 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
517 (ins SReg_128:$srsrc, VReg_32:$vaddr,
518 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
519 i1imm:$slc, i1imm:$tfe),
520 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
523 let offen = 1, idxen = 0, offset = 0 in {
524 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
525 (ins SReg_128:$srsrc, VReg_32:$vaddr,
526 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
528 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
531 let offen = 0, idxen = 1 in {
532 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
533 (ins SReg_128:$srsrc, VReg_32:$vaddr,
534 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
535 i1imm:$slc, i1imm:$tfe),
536 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
539 let offen = 1, idxen = 1 in {
540 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
541 (ins SReg_128:$srsrc, VReg_64:$vaddr,
542 SSrc_32:$soffset, i1imm:$glc,
543 i1imm:$slc, i1imm:$tfe),
544 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
548 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
549 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
550 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
551 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
556 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
557 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
559 name#" $vdata, $srsrc + $vaddr + $offset",
573 let soffset = 128; // ZERO
576 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
578 (outs regClass:$dst),
579 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
580 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
581 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
582 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
583 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
589 class MIMG_Mask <string op, int channels> {
591 int Channels = channels;
594 class MIMG_NoSampler_Helper <bits<7> op, string asm,
595 RegisterClass dst_rc,
596 RegisterClass src_rc> : MIMG <
598 (outs dst_rc:$vdata),
599 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
600 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
602 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
603 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
608 let hasPostISelHook = 1;
611 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
612 RegisterClass dst_rc,
614 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
615 MIMG_Mask<asm#"_V1", channels>;
616 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
617 MIMG_Mask<asm#"_V2", channels>;
618 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
619 MIMG_Mask<asm#"_V4", channels>;
622 multiclass MIMG_NoSampler <bits<7> op, string asm> {
623 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
624 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
625 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
626 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
629 class MIMG_Sampler_Helper <bits<7> op, string asm,
630 RegisterClass dst_rc,
631 RegisterClass src_rc> : MIMG <
633 (outs dst_rc:$vdata),
634 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
635 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
636 SReg_256:$srsrc, SReg_128:$ssamp),
637 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
638 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
642 let hasPostISelHook = 1;
645 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
646 RegisterClass dst_rc,
648 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
649 MIMG_Mask<asm#"_V1", channels>;
650 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
651 MIMG_Mask<asm#"_V2", channels>;
652 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
653 MIMG_Mask<asm#"_V4", channels>;
654 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
655 MIMG_Mask<asm#"_V8", channels>;
656 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
657 MIMG_Mask<asm#"_V16", channels>;
660 multiclass MIMG_Sampler <bits<7> op, string asm> {
661 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
662 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
663 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
664 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
667 //===----------------------------------------------------------------------===//
668 // Vector instruction mappings
669 //===----------------------------------------------------------------------===//
671 // Maps an opcode in e32 form to its e64 equivalent
672 def getVOPe64 : InstrMapping {
673 let FilterClass = "VOP";
674 let RowFields = ["OpName"];
675 let ColFields = ["Size"];
677 let ValueCols = [["8"]];
680 // Maps an original opcode to its commuted version
681 def getCommuteRev : InstrMapping {
682 let FilterClass = "VOP2_REV";
683 let RowFields = ["RevOp"];
684 let ColFields = ["IsOrig"];
686 let ValueCols = [["0"]];
689 def getMaskedMIMGOp : InstrMapping {
690 let FilterClass = "MIMG_Mask";
691 let RowFields = ["Op"];
692 let ColFields = ["Channels"];
694 let ValueCols = [["1"], ["2"], ["3"] ];
697 // Maps an commuted opcode to its original version
698 def getCommuteOrig : InstrMapping {
699 let FilterClass = "VOP2_REV";
700 let RowFields = ["RevOp"];
701 let ColFields = ["IsOrig"];
703 let ValueCols = [["1"]];
706 def isDS : InstrMapping {
707 let FilterClass = "DS";
708 let RowFields = ["Inst"];
709 let ColFields = ["Size"];
711 let ValueCols = [["8"]];
714 def getMCOpcode : InstrMapping {
715 let FilterClass = "SIMCInstr";
716 let RowFields = ["PseudoInstr"];
717 let ColFields = ["Subtarget"];
718 let KeyCol = [!cast<string>(SISubtarget.NONE)];
719 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
722 include "SIInstructions.td"