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 //===----------------------------------------------------------------------===//
147 //===----------------------------------------------------------------------===//
149 def FRAMEri32 : Operand<iPTR> {
150 let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
153 def sopp_brtarget : Operand<OtherVT> {
154 let EncoderMethod = "getSOPPBrEncoding";
155 let OperandType = "OPERAND_PCREL";
158 //===----------------------------------------------------------------------===//
160 //===----------------------------------------------------------------------===//
162 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
164 //===----------------------------------------------------------------------===//
165 // SI assembler operands
166 //===----------------------------------------------------------------------===//
173 include "SIInstrFormats.td"
175 //===----------------------------------------------------------------------===//
177 // SI Instruction multiclass helpers.
179 // Instructions with _32 take 32-bit operands.
180 // Instructions with _64 take 64-bit operands.
182 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
183 // encoding is the standard encoding, but instruction that make use of
184 // any of the instruction modifiers must use the 64-bit encoding.
186 // Instructions with _e32 use the 32-bit encoding.
187 // Instructions with _e64 use the 64-bit encoding.
189 //===----------------------------------------------------------------------===//
191 //===----------------------------------------------------------------------===//
193 //===----------------------------------------------------------------------===//
195 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
196 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
197 opName#" $dst, $src0", pattern
200 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
201 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
202 opName#" $dst, $src0", pattern
205 // 64-bit input, 32-bit output.
206 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
207 op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
208 opName#" $dst, $src0", pattern
211 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
212 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
213 opName#" $dst, $src0, $src1", pattern
216 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
217 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
218 opName#" $dst, $src0, $src1", pattern
221 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
222 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
223 opName#" $dst, $src0, $src1", pattern
227 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
228 string opName, PatLeaf cond> : SOPC <
229 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
230 opName#" $dst, $src0, $src1", []>;
232 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
233 : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
235 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
236 : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
238 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
239 op, (outs SReg_32:$dst), (ins i16imm:$src0),
240 opName#" $dst, $src0", pattern
243 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
244 op, (outs SReg_64:$dst), (ins i16imm:$src0),
245 opName#" $dst, $src0", pattern
248 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
249 RegisterClass dstClass> {
251 op, 1, (outs dstClass:$dst),
252 (ins baseClass:$sbase, u32imm:$offset),
253 asm#" $dst, $sbase, $offset", []
257 op, 0, (outs dstClass:$dst),
258 (ins baseClass:$sbase, SReg_32:$soff),
259 asm#" $dst, $sbase, $soff", []
263 //===----------------------------------------------------------------------===//
264 // Vector ALU classes
265 //===----------------------------------------------------------------------===//
267 class VOP <string opName> {
268 string OpName = opName;
271 class VOP2_REV <string revOp, bit isOrig> {
272 string RevOp = revOp;
276 class SIMCInstr <string pseudo, int subtarget> {
277 string PseudoInstr = pseudo;
278 int Subtarget = subtarget;
281 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
284 def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
285 SIMCInstr<OpName, SISubtarget.NONE> {
289 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
293 // This must always be right before the operand being input modified.
294 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
295 let PrintMethod = "printOperandAndMods";
298 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
299 string opName, list<dag> pattern> {
302 op, (outs drc:$dst), (ins src:$src0),
303 opName#"_e32 $dst, $src0", pattern
307 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
309 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
310 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
312 let src1 = SIOperand.ZERO;
313 let src2 = SIOperand.ZERO;
317 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
318 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
320 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
321 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
323 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
324 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
326 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
327 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
329 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
330 string opName, list<dag> pattern, string revOp> {
332 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
333 opName#"_e32 $dst, $src0, $src1", pattern
334 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
337 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
339 (ins InputMods:$src0_modifiers, arc:$src0,
340 InputMods:$src1_modifiers, arc:$src1,
341 i32imm:$clamp, i32imm:$omod),
342 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
343 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
344 let src2 = SIOperand.ZERO;
348 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
349 string revOp = opName>
350 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
352 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
353 string revOp = opName>
354 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
356 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
357 RegisterClass src0_rc, string revOp = opName> {
360 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
361 opName#"_e32 $dst, $src0, $src1", pattern
362 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
365 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
367 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
368 InputMods:$src1_modifiers, VSrc_32:$src1,
369 i32imm:$clamp, i32imm:$omod),
370 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
371 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
372 let src2 = SIOperand.ZERO;
373 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
374 can write it into any SGPR. We currently don't use the carry out,
375 so for now hardcode it to VCC as well */
376 let sdst = SIOperand.VCC;
380 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
381 string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
383 op, (ins arc:$src0, vrc:$src1),
384 opName#"_e32 $dst, $src0, $src1", []
386 let Defs = !if(defExec, [VCC, EXEC], [VCC]);
390 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
392 (ins InputMods:$src0_modifiers, arc:$src0,
393 InputMods:$src1_modifiers, arc:$src1,
394 InstFlag:$clamp, InstFlag:$omod),
395 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
396 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
397 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
400 let Defs = !if(defExec, [EXEC], []);
401 let src2 = SIOperand.ZERO;
402 let src2_modifiers = 0;
406 multiclass VOPC_32 <bits<8> op, string opName,
407 ValueType vt = untyped, PatLeaf cond = COND_NULL>
408 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
410 multiclass VOPC_64 <bits<8> op, string opName,
411 ValueType vt = untyped, PatLeaf cond = COND_NULL>
412 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
414 multiclass VOPCX_32 <bits<8> op, string opName,
415 ValueType vt = untyped, PatLeaf cond = COND_NULL>
416 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
418 multiclass VOPCX_64 <bits<8> op, string opName,
419 ValueType vt = untyped, PatLeaf cond = COND_NULL>
420 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
422 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
423 op, (outs VReg_32:$dst),
424 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
425 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
426 InstFlag:$clamp, InstFlag:$omod),
427 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
430 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
431 op, (outs VReg_64:$dst),
432 (ins VSrc_64:$src0, VSrc_32:$src1),
433 opName#" $dst, $src0, $src1", pattern
436 let src2 = SIOperand.ZERO;
437 let src0_modifiers = 0;
442 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
443 op, (outs VReg_64:$dst),
444 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
445 InputMods:$src1_modifiers, VSrc_64:$src1,
446 InputMods:$src2_modifiers, VSrc_64:$src2,
447 InstFlag:$clamp, InstFlag:$omod),
448 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
452 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
453 string opName, list<dag> pattern> : VOP3 <
454 op, (outs vrc:$dst0, SReg_64:$dst1),
455 (ins arc:$src0, arc:$src1, arc:$src2,
456 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
457 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
461 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
462 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
464 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
465 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
467 //===----------------------------------------------------------------------===//
468 // Vector I/O classes
469 //===----------------------------------------------------------------------===//
471 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
472 DS <op, outs, ins, asm, pat> {
475 // Single load interpret the 2 i8imm operands as a single i16 offset.
476 let offset0 = offset{7-0};
477 let offset1 = offset{15-8};
480 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
482 (outs regClass:$vdst),
483 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
484 asm#" $vdst, $addr, $offset, [M0]",
492 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
494 (outs regClass:$vdst),
495 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
496 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
504 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
507 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
508 asm#" $addr, $data0, $offset [M0]",
516 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
519 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
520 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
527 // 1 address, 1 data.
528 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
531 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
532 asm#" $vdst, $addr, $data0, $offset, [M0]",
540 // 1 address, 2 data.
541 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
544 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
545 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
551 // 1 address, 2 data.
552 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
555 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
556 asm#" $addr, $data0, $data1, $offset, [M0]",
562 // 1 address, 1 data.
563 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
566 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
567 asm#" $addr, $data0, $offset, [M0]",
575 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
578 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
579 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
580 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
581 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
582 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
588 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
589 ValueType load_vt = i32,
590 SDPatternOperator ld = null_frag> {
592 let lds = 0, mayLoad = 1 in {
596 let offen = 0, idxen = 0 in {
597 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
598 (ins SReg_128:$srsrc, VReg_32:$vaddr,
599 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
600 i1imm:$slc, i1imm:$tfe),
601 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
604 let offen = 1, idxen = 0, offset = 0 in {
605 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
606 (ins SReg_128:$srsrc, VReg_32:$vaddr,
607 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
609 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
612 let offen = 0, idxen = 1 in {
613 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
614 (ins SReg_128:$srsrc, VReg_32:$vaddr,
615 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
616 i1imm:$slc, i1imm:$tfe),
617 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
620 let offen = 1, idxen = 1 in {
621 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
622 (ins SReg_128:$srsrc, VReg_64:$vaddr,
623 SSrc_32:$soffset, i1imm:$glc,
624 i1imm:$slc, i1imm:$tfe),
625 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
629 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
630 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
631 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
632 asm#" $vdata, $srsrc + $vaddr + $offset",
633 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
634 i64:$vaddr, u16imm:$offset)))]>;
639 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
640 ValueType store_vt, SDPatternOperator st> :
641 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
643 name#" $vdata, $srsrc + $vaddr + $offset",
644 [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
657 let soffset = 128; // ZERO
660 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
662 (outs regClass:$dst),
663 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
664 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
665 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
666 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
667 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
673 class MIMG_Mask <string op, int channels> {
675 int Channels = channels;
678 class MIMG_NoSampler_Helper <bits<7> op, string asm,
679 RegisterClass dst_rc,
680 RegisterClass src_rc> : MIMG <
682 (outs dst_rc:$vdata),
683 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
684 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
686 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
687 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
692 let hasPostISelHook = 1;
695 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
696 RegisterClass dst_rc,
698 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
699 MIMG_Mask<asm#"_V1", channels>;
700 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
701 MIMG_Mask<asm#"_V2", channels>;
702 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
703 MIMG_Mask<asm#"_V4", channels>;
706 multiclass MIMG_NoSampler <bits<7> op, string asm> {
707 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
708 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
709 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
710 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
713 class MIMG_Sampler_Helper <bits<7> op, string asm,
714 RegisterClass dst_rc,
715 RegisterClass src_rc> : MIMG <
717 (outs dst_rc:$vdata),
718 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
719 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
720 SReg_256:$srsrc, SReg_128:$ssamp),
721 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
722 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
726 let hasPostISelHook = 1;
729 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
730 RegisterClass dst_rc,
732 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
733 MIMG_Mask<asm#"_V1", channels>;
734 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
735 MIMG_Mask<asm#"_V2", channels>;
736 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
737 MIMG_Mask<asm#"_V4", channels>;
738 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
739 MIMG_Mask<asm#"_V8", channels>;
740 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
741 MIMG_Mask<asm#"_V16", channels>;
744 multiclass MIMG_Sampler <bits<7> op, string asm> {
745 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
746 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
747 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
748 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
751 class MIMG_Gather_Helper <bits<7> op, string asm,
752 RegisterClass dst_rc,
753 RegisterClass src_rc> : MIMG <
755 (outs dst_rc:$vdata),
756 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
757 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
758 SReg_256:$srsrc, SReg_128:$ssamp),
759 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
760 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
765 // DMASK was repurposed for GATHER4. 4 components are always
766 // returned and DMASK works like a swizzle - it selects
767 // the component to fetch. The only useful DMASK values are
768 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
769 // (red,red,red,red) etc.) The ISA document doesn't mention
771 // Therefore, disable all code which updates DMASK by setting these two:
773 let hasPostISelHook = 0;
776 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
777 RegisterClass dst_rc,
779 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
780 MIMG_Mask<asm#"_V1", channels>;
781 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
782 MIMG_Mask<asm#"_V2", channels>;
783 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
784 MIMG_Mask<asm#"_V4", channels>;
785 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
786 MIMG_Mask<asm#"_V8", channels>;
787 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
788 MIMG_Mask<asm#"_V16", channels>;
791 multiclass MIMG_Gather <bits<7> op, string asm> {
792 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
793 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
794 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
795 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
798 //===----------------------------------------------------------------------===//
799 // Vector instruction mappings
800 //===----------------------------------------------------------------------===//
802 // Maps an opcode in e32 form to its e64 equivalent
803 def getVOPe64 : InstrMapping {
804 let FilterClass = "VOP";
805 let RowFields = ["OpName"];
806 let ColFields = ["Size"];
808 let ValueCols = [["8"]];
811 // Maps an original opcode to its commuted version
812 def getCommuteRev : InstrMapping {
813 let FilterClass = "VOP2_REV";
814 let RowFields = ["RevOp"];
815 let ColFields = ["IsOrig"];
817 let ValueCols = [["0"]];
820 def getMaskedMIMGOp : InstrMapping {
821 let FilterClass = "MIMG_Mask";
822 let RowFields = ["Op"];
823 let ColFields = ["Channels"];
825 let ValueCols = [["1"], ["2"], ["3"] ];
828 // Maps an commuted opcode to its original version
829 def getCommuteOrig : InstrMapping {
830 let FilterClass = "VOP2_REV";
831 let RowFields = ["RevOp"];
832 let ColFields = ["IsOrig"];
834 let ValueCols = [["1"]];
837 def isDS : InstrMapping {
838 let FilterClass = "DS";
839 let RowFields = ["Inst"];
840 let ColFields = ["Size"];
842 let ValueCols = [["8"]];
845 def getMCOpcode : InstrMapping {
846 let FilterClass = "SIMCInstr";
847 let RowFields = ["PseudoInstr"];
848 let ColFields = ["Subtarget"];
849 let KeyCol = [!cast<string>(SISubtarget.NONE)];
850 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
853 include "SIInstructions.td"