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
437 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
438 string opName, list<dag> pattern> : VOP3 <
439 op, (outs vrc:$dst0, SReg_64:$dst1),
440 (ins arc:$src0, arc:$src1, arc:$src2,
441 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
442 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
446 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
447 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
449 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
450 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
452 //===----------------------------------------------------------------------===//
453 // Vector I/O classes
454 //===----------------------------------------------------------------------===//
456 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
457 DS <op, outs, ins, asm, pat> {
460 // Single load interpret the 2 i8imm operands as a single i16 offset.
461 let offset0 = offset{7-0};
462 let offset1 = offset{15-8};
465 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
467 (outs regClass:$vdst),
468 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
469 asm#" $vdst, $addr, $offset, [M0]",
477 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
479 (outs regClass:$vdst),
480 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
481 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
489 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
492 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
493 asm#" $addr, $data0, $offset [M0]",
501 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
504 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
505 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
512 // 1 address, 1 data.
513 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
516 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
517 asm#" $vdst, $addr, $data0, $offset, [M0]",
525 // 1 address, 2 data.
526 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
529 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
530 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
536 // 1 address, 2 data.
537 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
540 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
541 asm#" $addr, $data0, $data1, $offset, [M0]",
547 // 1 address, 1 data.
548 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
551 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
552 asm#" $addr, $data0, $offset, [M0]",
560 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
563 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
564 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
565 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
566 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
567 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
573 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass> {
575 let lds = 0, mayLoad = 1 in {
579 let offen = 0, idxen = 0 in {
580 def _OFFSET : 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 + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
587 let offen = 1, idxen = 0, offset = 0 in {
588 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
589 (ins SReg_128:$srsrc, VReg_32:$vaddr,
590 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
592 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
595 let offen = 0, idxen = 1 in {
596 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
597 (ins SReg_128:$srsrc, VReg_32:$vaddr,
598 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
599 i1imm:$slc, i1imm:$tfe),
600 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
603 let offen = 1, idxen = 1 in {
604 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
605 (ins SReg_128:$srsrc, VReg_64:$vaddr,
606 SSrc_32:$soffset, i1imm:$glc,
607 i1imm:$slc, i1imm:$tfe),
608 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
612 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
613 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
614 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
615 asm#" $vdata, $srsrc + $vaddr + $offset", []>;
620 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass> :
621 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
623 name#" $vdata, $srsrc + $vaddr + $offset",
637 let soffset = 128; // ZERO
640 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
642 (outs regClass:$dst),
643 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
644 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
645 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
646 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
647 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
653 class MIMG_Mask <string op, int channels> {
655 int Channels = channels;
658 class MIMG_NoSampler_Helper <bits<7> op, string asm,
659 RegisterClass dst_rc,
660 RegisterClass src_rc> : MIMG <
662 (outs dst_rc:$vdata),
663 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
664 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
666 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
667 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
672 let hasPostISelHook = 1;
675 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
676 RegisterClass dst_rc,
678 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
679 MIMG_Mask<asm#"_V1", channels>;
680 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
681 MIMG_Mask<asm#"_V2", channels>;
682 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
683 MIMG_Mask<asm#"_V4", channels>;
686 multiclass MIMG_NoSampler <bits<7> op, string asm> {
687 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
688 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
689 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
690 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
693 class MIMG_Sampler_Helper <bits<7> op, string asm,
694 RegisterClass dst_rc,
695 RegisterClass src_rc> : MIMG <
697 (outs dst_rc:$vdata),
698 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
699 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
700 SReg_256:$srsrc, SReg_128:$ssamp),
701 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
702 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
706 let hasPostISelHook = 1;
709 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
710 RegisterClass dst_rc,
712 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
713 MIMG_Mask<asm#"_V1", channels>;
714 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
715 MIMG_Mask<asm#"_V2", channels>;
716 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
717 MIMG_Mask<asm#"_V4", channels>;
718 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
719 MIMG_Mask<asm#"_V8", channels>;
720 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
721 MIMG_Mask<asm#"_V16", channels>;
724 multiclass MIMG_Sampler <bits<7> op, string asm> {
725 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
726 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
727 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
728 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
731 class MIMG_Gather_Helper <bits<7> op, string asm,
732 RegisterClass dst_rc,
733 RegisterClass src_rc> : MIMG <
735 (outs dst_rc:$vdata),
736 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
737 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
738 SReg_256:$srsrc, SReg_128:$ssamp),
739 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
740 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
745 // DMASK was repurposed for GATHER4. 4 components are always
746 // returned and DMASK works like a swizzle - it selects
747 // the component to fetch. The only useful DMASK values are
748 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
749 // (red,red,red,red) etc.) The ISA document doesn't mention
751 // Therefore, disable all code which updates DMASK by setting these two:
753 let hasPostISelHook = 0;
756 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
757 RegisterClass dst_rc,
759 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
760 MIMG_Mask<asm#"_V1", channels>;
761 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
762 MIMG_Mask<asm#"_V2", channels>;
763 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
764 MIMG_Mask<asm#"_V4", channels>;
765 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
766 MIMG_Mask<asm#"_V8", channels>;
767 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
768 MIMG_Mask<asm#"_V16", channels>;
771 multiclass MIMG_Gather <bits<7> op, string asm> {
772 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
773 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
774 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
775 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
778 //===----------------------------------------------------------------------===//
779 // Vector instruction mappings
780 //===----------------------------------------------------------------------===//
782 // Maps an opcode in e32 form to its e64 equivalent
783 def getVOPe64 : InstrMapping {
784 let FilterClass = "VOP";
785 let RowFields = ["OpName"];
786 let ColFields = ["Size"];
788 let ValueCols = [["8"]];
791 // Maps an original opcode to its commuted version
792 def getCommuteRev : InstrMapping {
793 let FilterClass = "VOP2_REV";
794 let RowFields = ["RevOp"];
795 let ColFields = ["IsOrig"];
797 let ValueCols = [["0"]];
800 def getMaskedMIMGOp : InstrMapping {
801 let FilterClass = "MIMG_Mask";
802 let RowFields = ["Op"];
803 let ColFields = ["Channels"];
805 let ValueCols = [["1"], ["2"], ["3"] ];
808 // Maps an commuted opcode to its original version
809 def getCommuteOrig : InstrMapping {
810 let FilterClass = "VOP2_REV";
811 let RowFields = ["RevOp"];
812 let ColFields = ["IsOrig"];
814 let ValueCols = [["1"]];
817 def isDS : InstrMapping {
818 let FilterClass = "DS";
819 let RowFields = ["Inst"];
820 let ColFields = ["Size"];
822 let ValueCols = [["8"]];
825 def getMCOpcode : InstrMapping {
826 let FilterClass = "SIMCInstr";
827 let RowFields = ["PseudoInstr"];
828 let ColFields = ["Subtarget"];
829 let KeyCol = [!cast<string>(SISubtarget.NONE)];
830 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
833 include "SIInstructions.td"