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 VSrc_64:$src0, VSrc_64:$src1, VSrc_64:$src2,
430 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
431 opName#" $dst, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
434 //===----------------------------------------------------------------------===//
435 // Vector I/O classes
436 //===----------------------------------------------------------------------===//
438 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
439 DS <op, outs, ins, asm, pat> {
442 // Single load interpret the 2 i8imm operands as a single i16 offset.
443 let offset0 = offset{7-0};
444 let offset1 = offset{15-8};
447 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
449 (outs regClass:$vdst),
450 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
451 asm#" $vdst, $addr, $offset, [M0]",
459 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
461 (outs regClass:$vdst),
462 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
463 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
471 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
474 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
475 asm#" $addr, $data0, $offset [M0]",
483 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
486 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
487 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
494 // 1 address, 1 data.
495 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
498 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
499 asm#" $vdst, $addr, $data0, $offset, [M0]",
507 // 1 address, 2 data.
508 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
511 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
512 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
518 // 1 address, 2 data.
519 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
522 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
523 asm#" $addr, $data0, $data1, $offset, [M0]",
529 // 1 address, 1 data.
530 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
533 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
534 asm#" $addr, $data0, $offset, [M0]",
542 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
545 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
546 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
547 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
548 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
549 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
555 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
557 let lds = 0, mayLoad = 1 in {
561 let offen = 0, idxen = 0 in {
562 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
563 (ins SReg_128:$srsrc, VReg_32:$vaddr,
564 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
565 i1imm:$slc, i1imm:$tfe),
566 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
569 let offen = 1, idxen = 0, offset = 0 in {
570 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
571 (ins SReg_128:$srsrc, VReg_32:$vaddr,
572 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
574 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
577 let offen = 0, idxen = 1 in {
578 def _IDXEN : 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[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
585 let offen = 1, idxen = 1 in {
586 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
587 (ins SReg_128:$srsrc, VReg_64:$vaddr,
588 SSrc_32:$soffset, i1imm:$glc,
589 i1imm:$slc, i1imm:$tfe),
590 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
594 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
595 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
596 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
597 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
602 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
603 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
605 name#" $vdata, $srsrc + $vaddr + $offset",
619 let soffset = 128; // ZERO
622 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
624 (outs regClass:$dst),
625 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
626 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
627 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
628 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
629 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
635 class MIMG_Mask <string op, int channels> {
637 int Channels = channels;
640 class MIMG_NoSampler_Helper <bits<7> op, string asm,
641 RegisterClass dst_rc,
642 RegisterClass src_rc> : MIMG <
644 (outs dst_rc:$vdata),
645 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
646 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
648 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
649 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
654 let hasPostISelHook = 1;
657 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
658 RegisterClass dst_rc,
660 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
661 MIMG_Mask<asm#"_V1", channels>;
662 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
663 MIMG_Mask<asm#"_V2", channels>;
664 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
665 MIMG_Mask<asm#"_V4", channels>;
668 multiclass MIMG_NoSampler <bits<7> op, string asm> {
669 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
670 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
671 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
672 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
675 class MIMG_Sampler_Helper <bits<7> op, string asm,
676 RegisterClass dst_rc,
677 RegisterClass src_rc> : MIMG <
679 (outs dst_rc:$vdata),
680 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
681 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
682 SReg_256:$srsrc, SReg_128:$ssamp),
683 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
684 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
688 let hasPostISelHook = 1;
691 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
692 RegisterClass dst_rc,
694 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
695 MIMG_Mask<asm#"_V1", channels>;
696 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
697 MIMG_Mask<asm#"_V2", channels>;
698 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
699 MIMG_Mask<asm#"_V4", channels>;
700 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
701 MIMG_Mask<asm#"_V8", channels>;
702 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
703 MIMG_Mask<asm#"_V16", channels>;
706 multiclass MIMG_Sampler <bits<7> op, string asm> {
707 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
708 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
709 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
710 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
713 //===----------------------------------------------------------------------===//
714 // Vector instruction mappings
715 //===----------------------------------------------------------------------===//
717 // Maps an opcode in e32 form to its e64 equivalent
718 def getVOPe64 : InstrMapping {
719 let FilterClass = "VOP";
720 let RowFields = ["OpName"];
721 let ColFields = ["Size"];
723 let ValueCols = [["8"]];
726 // Maps an original opcode to its commuted version
727 def getCommuteRev : InstrMapping {
728 let FilterClass = "VOP2_REV";
729 let RowFields = ["RevOp"];
730 let ColFields = ["IsOrig"];
732 let ValueCols = [["0"]];
735 def getMaskedMIMGOp : InstrMapping {
736 let FilterClass = "MIMG_Mask";
737 let RowFields = ["Op"];
738 let ColFields = ["Channels"];
740 let ValueCols = [["1"], ["2"], ["3"] ];
743 // Maps an commuted opcode to its original version
744 def getCommuteOrig : InstrMapping {
745 let FilterClass = "VOP2_REV";
746 let RowFields = ["RevOp"];
747 let ColFields = ["IsOrig"];
749 let ValueCols = [["1"]];
752 def isDS : InstrMapping {
753 let FilterClass = "DS";
754 let RowFields = ["Inst"];
755 let ColFields = ["Size"];
757 let ValueCols = [["8"]];
760 def getMCOpcode : InstrMapping {
761 let FilterClass = "SIMCInstr";
762 let RowFields = ["PseudoInstr"];
763 let ColFields = ["Subtarget"];
764 let KeyCol = [!cast<string>(SISubtarget.NONE)];
765 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
768 include "SIInstructions.td"