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 // 1 address, 1 data.
485 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
488 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
489 asm#" $vdst, $addr, $data0, $offset, [M0]",
497 // 1 address, 0 data.
498 class DS_1A0D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
501 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
502 asm#" $vdst, $addr, $offset, [M0]",
510 // 1 address, 0 data.
511 class DS_1A0D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
514 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
515 asm#" $addr, $offset, [M0]",
523 // 1 address, 2 data.
524 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
527 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1, u16imm:$offset),
528 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
534 // 1 address, 2 data.
535 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
538 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, VReg_32:$data1, u16imm:$offset),
539 asm#" $addr, $data0, $data1, $offset, [M0]",
545 // 1 address, 1 data.
546 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
549 (ins i1imm:$gds, VReg_32:$addr, VReg_32:$data0, u16imm:$offset),
550 asm#" $addr, $data0, $offset, [M0]",
558 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
561 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
562 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
563 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
564 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
565 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
571 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
573 let lds = 0, mayLoad = 1 in {
577 let offen = 0, idxen = 0 in {
578 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
579 (ins SReg_128:$srsrc, VReg_32:$vaddr,
580 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
581 i1imm:$slc, i1imm:$tfe),
582 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
585 let offen = 1, idxen = 0, offset = 0 in {
586 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
587 (ins SReg_128:$srsrc, VReg_32:$vaddr,
588 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
590 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
593 let offen = 0, idxen = 1 in {
594 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
595 (ins SReg_128:$srsrc, VReg_32:$vaddr,
596 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
597 i1imm:$slc, i1imm:$tfe),
598 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
601 let offen = 1, idxen = 1 in {
602 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
603 (ins SReg_128:$srsrc, VReg_64:$vaddr,
604 SSrc_32:$soffset, i1imm:$glc,
605 i1imm:$slc, i1imm:$tfe),
606 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
610 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
611 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
612 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
613 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
618 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
619 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
621 name#" $vdata, $srsrc + $vaddr + $offset",
635 let soffset = 128; // ZERO
638 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
640 (outs regClass:$dst),
641 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
642 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
643 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
644 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
645 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
651 class MIMG_Mask <string op, int channels> {
653 int Channels = channels;
656 class MIMG_NoSampler_Helper <bits<7> op, string asm,
657 RegisterClass dst_rc,
658 RegisterClass src_rc> : MIMG <
660 (outs dst_rc:$vdata),
661 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
662 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
664 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
665 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
670 let hasPostISelHook = 1;
673 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
674 RegisterClass dst_rc,
676 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
677 MIMG_Mask<asm#"_V1", channels>;
678 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
679 MIMG_Mask<asm#"_V2", channels>;
680 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
681 MIMG_Mask<asm#"_V4", channels>;
684 multiclass MIMG_NoSampler <bits<7> op, string asm> {
685 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
686 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
687 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
688 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
691 class MIMG_Sampler_Helper <bits<7> op, string asm,
692 RegisterClass dst_rc,
693 RegisterClass src_rc> : MIMG <
695 (outs dst_rc:$vdata),
696 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
697 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
698 SReg_256:$srsrc, SReg_128:$ssamp),
699 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
700 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
704 let hasPostISelHook = 1;
707 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
708 RegisterClass dst_rc,
710 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
711 MIMG_Mask<asm#"_V1", channels>;
712 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
713 MIMG_Mask<asm#"_V2", channels>;
714 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
715 MIMG_Mask<asm#"_V4", channels>;
716 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
717 MIMG_Mask<asm#"_V8", channels>;
718 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
719 MIMG_Mask<asm#"_V16", channels>;
722 multiclass MIMG_Sampler <bits<7> op, string asm> {
723 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
724 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
725 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
726 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
729 //===----------------------------------------------------------------------===//
730 // Vector instruction mappings
731 //===----------------------------------------------------------------------===//
733 // Maps an opcode in e32 form to its e64 equivalent
734 def getVOPe64 : InstrMapping {
735 let FilterClass = "VOP";
736 let RowFields = ["OpName"];
737 let ColFields = ["Size"];
739 let ValueCols = [["8"]];
742 // Maps an original opcode to its commuted version
743 def getCommuteRev : InstrMapping {
744 let FilterClass = "VOP2_REV";
745 let RowFields = ["RevOp"];
746 let ColFields = ["IsOrig"];
748 let ValueCols = [["0"]];
751 def getMaskedMIMGOp : InstrMapping {
752 let FilterClass = "MIMG_Mask";
753 let RowFields = ["Op"];
754 let ColFields = ["Channels"];
756 let ValueCols = [["1"], ["2"], ["3"] ];
759 // Maps an commuted opcode to its original version
760 def getCommuteOrig : InstrMapping {
761 let FilterClass = "VOP2_REV";
762 let RowFields = ["RevOp"];
763 let ColFields = ["IsOrig"];
765 let ValueCols = [["1"]];
768 def isDS : InstrMapping {
769 let FilterClass = "DS";
770 let RowFields = ["Inst"];
771 let ColFields = ["Size"];
773 let ValueCols = [["8"]];
776 def getMCOpcode : InstrMapping {
777 let FilterClass = "SIMCInstr";
778 let RowFields = ["PseudoInstr"];
779 let ColFields = ["Subtarget"];
780 let KeyCol = [!cast<string>(SISubtarget.NONE)];
781 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
784 include "SIInstructions.td"