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 "" : VOP3Common <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, bit defExec = 0> {
368 op, (ins arc:$src0, vrc:$src1),
369 opName#"_e32 $dst, $src0, $src1", []
371 let Defs = !if(defExec, [VCC, EXEC], [VCC]);
375 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
377 (ins InputMods:$src0_modifiers, arc:$src0,
378 InputMods:$src1_modifiers, arc:$src1,
379 InstFlag:$clamp, InstFlag:$omod),
380 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
381 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
382 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
385 let Defs = !if(defExec, [EXEC], []);
386 let src2 = SIOperand.ZERO;
387 let src2_modifiers = 0;
391 multiclass VOPC_32 <bits<8> op, string opName,
392 ValueType vt = untyped, PatLeaf cond = COND_NULL>
393 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
395 multiclass VOPC_64 <bits<8> op, string opName,
396 ValueType vt = untyped, PatLeaf cond = COND_NULL>
397 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
399 multiclass VOPCX_32 <bits<8> op, string opName,
400 ValueType vt = untyped, PatLeaf cond = COND_NULL>
401 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
403 multiclass VOPCX_64 <bits<8> op, string opName,
404 ValueType vt = untyped, PatLeaf cond = COND_NULL>
405 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
407 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
408 op, (outs VReg_32:$dst),
409 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
410 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
411 InstFlag:$clamp, InstFlag:$omod),
412 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
415 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
416 op, (outs VReg_64:$dst),
417 (ins VSrc_64:$src0, VSrc_32:$src1),
418 opName#" $dst, $src0, $src1", pattern
421 let src2 = SIOperand.ZERO;
422 let src0_modifiers = 0;
427 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
428 op, (outs VReg_64:$dst),
429 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
430 InputMods:$src1_modifiers, VSrc_64:$src1,
431 InputMods:$src2_modifiers, VSrc_64:$src2,
432 InstFlag:$clamp, InstFlag:$omod),
433 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
436 //===----------------------------------------------------------------------===//
437 // Vector I/O classes
438 //===----------------------------------------------------------------------===//
440 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
441 DS <op, outs, ins, asm, pat> {
444 // Single load interpret the 2 i8imm operands as a single i16 offset.
445 let offset0 = offset{7-0};
446 let offset1 = offset{15-8};
449 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
451 (outs regClass:$vdst),
452 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
453 asm#" $vdst, $addr, $offset, [M0]",
461 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
463 (outs regClass:$vdst),
464 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
465 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
473 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
476 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
477 asm#" $addr, $data0, $offset [M0]",
485 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
488 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
489 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
496 // 1 address, 1 data.
497 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
500 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
501 asm#" $vdst, $addr, $data0, $offset, [M0]",
509 // 1 address, 2 data.
510 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
513 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
514 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
520 // 1 address, 2 data.
521 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
524 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
525 asm#" $addr, $data0, $data1, $offset, [M0]",
531 // 1 address, 1 data.
532 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
535 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
536 asm#" $addr, $data0, $offset, [M0]",
544 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
547 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
548 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
549 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
550 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
551 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
557 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
559 let lds = 0, mayLoad = 1 in {
563 let offen = 0, idxen = 0 in {
564 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
565 (ins SReg_128:$srsrc, VReg_32:$vaddr,
566 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
567 i1imm:$slc, i1imm:$tfe),
568 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
571 let offen = 1, idxen = 0, offset = 0 in {
572 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
573 (ins SReg_128:$srsrc, VReg_32:$vaddr,
574 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
576 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
579 let offen = 0, idxen = 1 in {
580 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
581 (ins SReg_128:$srsrc, VReg_32:$vaddr,
582 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
583 i1imm:$slc, i1imm:$tfe),
584 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
587 let offen = 1, idxen = 1 in {
588 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
589 (ins SReg_128:$srsrc, VReg_64:$vaddr,
590 SSrc_32:$soffset, i1imm:$glc,
591 i1imm:$slc, i1imm:$tfe),
592 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
596 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
597 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
598 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
599 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
604 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
605 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
607 name#" $vdata, $srsrc + $vaddr + $offset",
621 let soffset = 128; // ZERO
624 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
626 (outs regClass:$dst),
627 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
628 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
629 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
630 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
631 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
637 class MIMG_Mask <string op, int channels> {
639 int Channels = channels;
642 class MIMG_NoSampler_Helper <bits<7> op, string asm,
643 RegisterClass dst_rc,
644 RegisterClass src_rc> : MIMG <
646 (outs dst_rc:$vdata),
647 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
648 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
650 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
651 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
656 let hasPostISelHook = 1;
659 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
660 RegisterClass dst_rc,
662 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
663 MIMG_Mask<asm#"_V1", channels>;
664 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
665 MIMG_Mask<asm#"_V2", channels>;
666 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
667 MIMG_Mask<asm#"_V4", channels>;
670 multiclass MIMG_NoSampler <bits<7> op, string asm> {
671 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
672 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
673 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
674 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
677 class MIMG_Sampler_Helper <bits<7> op, string asm,
678 RegisterClass dst_rc,
679 RegisterClass src_rc> : MIMG <
681 (outs dst_rc:$vdata),
682 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
683 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
684 SReg_256:$srsrc, SReg_128:$ssamp),
685 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
686 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
690 let hasPostISelHook = 1;
693 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
694 RegisterClass dst_rc,
696 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
697 MIMG_Mask<asm#"_V1", channels>;
698 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
699 MIMG_Mask<asm#"_V2", channels>;
700 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
701 MIMG_Mask<asm#"_V4", channels>;
702 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
703 MIMG_Mask<asm#"_V8", channels>;
704 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
705 MIMG_Mask<asm#"_V16", channels>;
708 multiclass MIMG_Sampler <bits<7> op, string asm> {
709 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
710 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
711 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
712 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
715 //===----------------------------------------------------------------------===//
716 // Vector instruction mappings
717 //===----------------------------------------------------------------------===//
719 // Maps an opcode in e32 form to its e64 equivalent
720 def getVOPe64 : InstrMapping {
721 let FilterClass = "VOP";
722 let RowFields = ["OpName"];
723 let ColFields = ["Size"];
725 let ValueCols = [["8"]];
728 // Maps an original opcode to its commuted version
729 def getCommuteRev : InstrMapping {
730 let FilterClass = "VOP2_REV";
731 let RowFields = ["RevOp"];
732 let ColFields = ["IsOrig"];
734 let ValueCols = [["0"]];
737 def getMaskedMIMGOp : InstrMapping {
738 let FilterClass = "MIMG_Mask";
739 let RowFields = ["Op"];
740 let ColFields = ["Channels"];
742 let ValueCols = [["1"], ["2"], ["3"] ];
745 // Maps an commuted opcode to its original version
746 def getCommuteOrig : InstrMapping {
747 let FilterClass = "VOP2_REV";
748 let RowFields = ["RevOp"];
749 let ColFields = ["IsOrig"];
751 let ValueCols = [["1"]];
754 def isDS : InstrMapping {
755 let FilterClass = "DS";
756 let RowFields = ["Inst"];
757 let ColFields = ["Size"];
759 let ValueCols = [["8"]];
762 def getMCOpcode : InstrMapping {
763 let FilterClass = "SIMCInstr";
764 let RowFields = ["PseudoInstr"];
765 let ColFields = ["Subtarget"];
766 let KeyCol = [!cast<string>(SISubtarget.NONE)];
767 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
770 include "SIInstructions.td"