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 def SIconstdata_ptr : SDNode<
61 "AMDGPUISD::CONST_DATA_PTR", SDTypeProfile <1, 0, [SDTCisVT<0, i64>]>
64 // Transformation function, extract the lower 32bit of a 64bit immediate
65 def LO32 : SDNodeXForm<imm, [{
66 return CurDAG->getTargetConstant(N->getZExtValue() & 0xffffffff, MVT::i32);
69 def LO32f : SDNodeXForm<fpimm, [{
70 APInt V = N->getValueAPF().bitcastToAPInt().trunc(32);
71 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
74 // Transformation function, extract the upper 32bit of a 64bit immediate
75 def HI32 : SDNodeXForm<imm, [{
76 return CurDAG->getTargetConstant(N->getZExtValue() >> 32, MVT::i32);
79 def HI32f : SDNodeXForm<fpimm, [{
80 APInt V = N->getValueAPF().bitcastToAPInt().lshr(32).trunc(32);
81 return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32);
84 def IMM8bitDWORD : PatLeaf <(imm),
85 [{return (N->getZExtValue() & ~0x3FC) == 0;}]
88 def as_dword_i32imm : SDNodeXForm<imm, [{
89 return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32);
92 def as_i1imm : SDNodeXForm<imm, [{
93 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1);
96 def as_i8imm : SDNodeXForm<imm, [{
97 return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i8);
100 def as_i16imm : SDNodeXForm<imm, [{
101 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16);
104 def as_i32imm: SDNodeXForm<imm, [{
105 return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32);
108 def IMM8bit : PatLeaf <(imm),
109 [{return isUInt<8>(N->getZExtValue());}]
112 def IMM12bit : PatLeaf <(imm),
113 [{return isUInt<12>(N->getZExtValue());}]
116 def IMM16bit : PatLeaf <(imm),
117 [{return isUInt<16>(N->getZExtValue());}]
120 def IMM32bit : PatLeaf <(imm),
121 [{return isUInt<32>(N->getZExtValue());}]
124 def mubuf_vaddr_offset : PatFrag<
125 (ops node:$ptr, node:$offset, node:$imm_offset),
126 (add (add node:$ptr, node:$offset), node:$imm_offset)
129 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
130 return isInlineImmediate(N);
133 class SGPRImm <dag frag> : PatLeaf<frag, [{
134 if (TM.getSubtarget<AMDGPUSubtarget>().getGeneration() <
135 AMDGPUSubtarget::SOUTHERN_ISLANDS) {
138 const SIRegisterInfo *SIRI =
139 static_cast<const SIRegisterInfo*>(TM.getRegisterInfo());
140 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
142 if (SIRI->isSGPRClass(getOperandRegClass(*U, U.getOperandNo()))) {
149 //===----------------------------------------------------------------------===//
151 //===----------------------------------------------------------------------===//
153 def FRAMEri32 : Operand<iPTR> {
154 let MIOperandInfo = (ops i32:$ptr, i32imm:$index);
157 def sopp_brtarget : Operand<OtherVT> {
158 let EncoderMethod = "getSOPPBrEncoding";
159 let OperandType = "OPERAND_PCREL";
162 //===----------------------------------------------------------------------===//
164 //===----------------------------------------------------------------------===//
166 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
168 //===----------------------------------------------------------------------===//
169 // SI assembler operands
170 //===----------------------------------------------------------------------===//
177 include "SIInstrFormats.td"
179 //===----------------------------------------------------------------------===//
181 // SI Instruction multiclass helpers.
183 // Instructions with _32 take 32-bit operands.
184 // Instructions with _64 take 64-bit operands.
186 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
187 // encoding is the standard encoding, but instruction that make use of
188 // any of the instruction modifiers must use the 64-bit encoding.
190 // Instructions with _e32 use the 32-bit encoding.
191 // Instructions with _e64 use the 64-bit encoding.
193 //===----------------------------------------------------------------------===//
195 //===----------------------------------------------------------------------===//
197 //===----------------------------------------------------------------------===//
199 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
200 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
201 opName#" $dst, $src0", pattern
204 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
205 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
206 opName#" $dst, $src0", pattern
209 // 64-bit input, 32-bit output.
210 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
211 op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
212 opName#" $dst, $src0", pattern
215 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
216 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
217 opName#" $dst, $src0, $src1", pattern
220 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
221 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
222 opName#" $dst, $src0, $src1", pattern
225 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
226 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
227 opName#" $dst, $src0, $src1", pattern
231 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
232 string opName, PatLeaf cond> : SOPC <
233 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
234 opName#" $dst, $src0, $src1", []>;
236 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
237 : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
239 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
240 : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
242 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
243 op, (outs SReg_32:$dst), (ins i16imm:$src0),
244 opName#" $dst, $src0", pattern
247 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
248 op, (outs SReg_64:$dst), (ins i16imm:$src0),
249 opName#" $dst, $src0", pattern
252 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
253 RegisterClass dstClass> {
255 op, 1, (outs dstClass:$dst),
256 (ins baseClass:$sbase, u32imm:$offset),
257 asm#" $dst, $sbase, $offset", []
261 op, 0, (outs dstClass:$dst),
262 (ins baseClass:$sbase, SReg_32:$soff),
263 asm#" $dst, $sbase, $soff", []
267 //===----------------------------------------------------------------------===//
268 // Vector ALU classes
269 //===----------------------------------------------------------------------===//
271 class VOP <string opName> {
272 string OpName = opName;
275 class VOP2_REV <string revOp, bit isOrig> {
276 string RevOp = revOp;
280 class SIMCInstr <string pseudo, int subtarget> {
281 string PseudoInstr = pseudo;
282 int Subtarget = subtarget;
285 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
288 def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
289 SIMCInstr<OpName, SISubtarget.NONE> {
293 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
297 // This must always be right before the operand being input modified.
298 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
299 let PrintMethod = "printOperandAndMods";
302 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
303 string opName, list<dag> pattern> {
306 op, (outs drc:$dst), (ins src:$src0),
307 opName#"_e32 $dst, $src0", pattern
311 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
313 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
314 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
316 let src1 = SIOperand.ZERO;
317 let src2 = SIOperand.ZERO;
321 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
322 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
324 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
325 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
327 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
328 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
330 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
331 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
333 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
334 string opName, list<dag> pattern, string revOp> {
336 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
337 opName#"_e32 $dst, $src0, $src1", pattern
338 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
341 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
343 (ins InputMods:$src0_modifiers, arc:$src0,
344 InputMods:$src1_modifiers, arc:$src1,
345 i32imm:$clamp, i32imm:$omod),
346 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
347 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
348 let src2 = SIOperand.ZERO;
352 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
353 string revOp = opName>
354 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
356 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
357 string revOp = opName>
358 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
360 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
361 RegisterClass src0_rc, string revOp = opName> {
364 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
365 opName#"_e32 $dst, $src0, $src1", pattern
366 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
369 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
371 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
372 InputMods:$src1_modifiers, VSrc_32:$src1,
373 i32imm:$clamp, i32imm:$omod),
374 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
375 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
376 let src2 = SIOperand.ZERO;
377 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
378 can write it into any SGPR. We currently don't use the carry out,
379 so for now hardcode it to VCC as well */
380 let sdst = SIOperand.VCC;
384 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
385 string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
387 op, (ins arc:$src0, vrc:$src1),
388 opName#"_e32 $dst, $src0, $src1", []
390 let Defs = !if(defExec, [VCC, EXEC], [VCC]);
394 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
396 (ins InputMods:$src0_modifiers, arc:$src0,
397 InputMods:$src1_modifiers, arc:$src1,
398 InstFlag:$clamp, InstFlag:$omod),
399 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
400 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
401 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
404 let Defs = !if(defExec, [EXEC], []);
405 let src2 = SIOperand.ZERO;
406 let src2_modifiers = 0;
410 multiclass VOPC_32 <bits<8> op, string opName,
411 ValueType vt = untyped, PatLeaf cond = COND_NULL>
412 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
414 multiclass VOPC_64 <bits<8> op, string opName,
415 ValueType vt = untyped, PatLeaf cond = COND_NULL>
416 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
418 multiclass VOPCX_32 <bits<8> op, string opName,
419 ValueType vt = untyped, PatLeaf cond = COND_NULL>
420 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
422 multiclass VOPCX_64 <bits<8> op, string opName,
423 ValueType vt = untyped, PatLeaf cond = COND_NULL>
424 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
426 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
427 op, (outs VReg_32:$dst),
428 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
429 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
430 InstFlag:$clamp, InstFlag:$omod),
431 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
434 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
435 op, (outs VReg_64:$dst),
436 (ins VSrc_64:$src0, VSrc_32:$src1),
437 opName#" $dst, $src0, $src1", pattern
440 let src2 = SIOperand.ZERO;
441 let src0_modifiers = 0;
446 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
447 op, (outs VReg_64:$dst),
448 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
449 InputMods:$src1_modifiers, VSrc_64:$src1,
450 InputMods:$src2_modifiers, VSrc_64:$src2,
451 InstFlag:$clamp, InstFlag:$omod),
452 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
456 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
457 string opName, list<dag> pattern> : VOP3 <
458 op, (outs vrc:$dst0, SReg_64:$dst1),
459 (ins arc:$src0, arc:$src1, arc:$src2,
460 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
461 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
465 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
466 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
468 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
469 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
471 //===----------------------------------------------------------------------===//
472 // Vector I/O classes
473 //===----------------------------------------------------------------------===//
475 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
476 DS <op, outs, ins, asm, pat> {
479 // Single load interpret the 2 i8imm operands as a single i16 offset.
480 let offset0 = offset{7-0};
481 let offset1 = offset{15-8};
484 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
486 (outs regClass:$vdst),
487 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
488 asm#" $vdst, $addr, $offset, [M0]",
496 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
498 (outs regClass:$vdst),
499 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
500 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
508 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
511 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
512 asm#" $addr, $data0, $offset [M0]",
520 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
523 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
524 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
531 // 1 address, 1 data.
532 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
535 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
536 asm#" $vdst, $addr, $data0, $offset, [M0]",
544 // 1 address, 2 data.
545 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
548 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
549 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
555 // 1 address, 2 data.
556 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
559 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
560 asm#" $addr, $data0, $data1, $offset, [M0]",
566 // 1 address, 1 data.
567 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
570 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
571 asm#" $addr, $data0, $offset, [M0]",
579 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
582 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
583 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
584 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
585 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
586 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
592 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
593 ValueType load_vt = i32,
594 SDPatternOperator ld = null_frag> {
596 let lds = 0, mayLoad = 1 in {
600 let offen = 0, idxen = 0 in {
601 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
602 (ins SReg_128:$srsrc, VReg_32:$vaddr,
603 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
604 i1imm:$slc, i1imm:$tfe),
605 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
608 let offen = 1, idxen = 0, offset = 0 in {
609 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
610 (ins SReg_128:$srsrc, VReg_32:$vaddr,
611 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
613 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
616 let offen = 0, idxen = 1 in {
617 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
618 (ins SReg_128:$srsrc, VReg_32:$vaddr,
619 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
620 i1imm:$slc, i1imm:$tfe),
621 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
624 let offen = 1, idxen = 1 in {
625 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
626 (ins SReg_128:$srsrc, VReg_64:$vaddr,
627 SSrc_32:$soffset, i1imm:$glc,
628 i1imm:$slc, i1imm:$tfe),
629 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
633 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
634 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
635 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
636 asm#" $vdata, $srsrc + $vaddr + $offset",
637 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
638 i64:$vaddr, u16imm:$offset)))]>;
643 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
644 ValueType store_vt, SDPatternOperator st> :
645 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
647 name#" $vdata, $srsrc + $vaddr + $offset",
648 [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
661 let soffset = 128; // ZERO
664 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
666 (outs regClass:$dst),
667 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
668 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
669 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
670 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
671 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
677 class MIMG_Mask <string op, int channels> {
679 int Channels = channels;
682 class MIMG_NoSampler_Helper <bits<7> op, string asm,
683 RegisterClass dst_rc,
684 RegisterClass src_rc> : MIMG <
686 (outs dst_rc:$vdata),
687 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
688 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
690 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
691 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
696 let hasPostISelHook = 1;
699 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
700 RegisterClass dst_rc,
702 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
703 MIMG_Mask<asm#"_V1", channels>;
704 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
705 MIMG_Mask<asm#"_V2", channels>;
706 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
707 MIMG_Mask<asm#"_V4", channels>;
710 multiclass MIMG_NoSampler <bits<7> op, string asm> {
711 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
712 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
713 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
714 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
717 class MIMG_Sampler_Helper <bits<7> op, string asm,
718 RegisterClass dst_rc,
719 RegisterClass src_rc> : MIMG <
721 (outs dst_rc:$vdata),
722 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
723 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
724 SReg_256:$srsrc, SReg_128:$ssamp),
725 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
726 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
730 let hasPostISelHook = 1;
733 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
734 RegisterClass dst_rc,
736 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
737 MIMG_Mask<asm#"_V1", channels>;
738 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
739 MIMG_Mask<asm#"_V2", channels>;
740 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
741 MIMG_Mask<asm#"_V4", channels>;
742 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
743 MIMG_Mask<asm#"_V8", channels>;
744 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
745 MIMG_Mask<asm#"_V16", channels>;
748 multiclass MIMG_Sampler <bits<7> op, string asm> {
749 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
750 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
751 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
752 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
755 class MIMG_Gather_Helper <bits<7> op, string asm,
756 RegisterClass dst_rc,
757 RegisterClass src_rc> : MIMG <
759 (outs dst_rc:$vdata),
760 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
761 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
762 SReg_256:$srsrc, SReg_128:$ssamp),
763 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
764 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
769 // DMASK was repurposed for GATHER4. 4 components are always
770 // returned and DMASK works like a swizzle - it selects
771 // the component to fetch. The only useful DMASK values are
772 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
773 // (red,red,red,red) etc.) The ISA document doesn't mention
775 // Therefore, disable all code which updates DMASK by setting these two:
777 let hasPostISelHook = 0;
780 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
781 RegisterClass dst_rc,
783 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
784 MIMG_Mask<asm#"_V1", channels>;
785 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
786 MIMG_Mask<asm#"_V2", channels>;
787 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
788 MIMG_Mask<asm#"_V4", channels>;
789 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
790 MIMG_Mask<asm#"_V8", channels>;
791 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
792 MIMG_Mask<asm#"_V16", channels>;
795 multiclass MIMG_Gather <bits<7> op, string asm> {
796 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
797 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
798 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
799 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
802 //===----------------------------------------------------------------------===//
803 // Vector instruction mappings
804 //===----------------------------------------------------------------------===//
806 // Maps an opcode in e32 form to its e64 equivalent
807 def getVOPe64 : InstrMapping {
808 let FilterClass = "VOP";
809 let RowFields = ["OpName"];
810 let ColFields = ["Size"];
812 let ValueCols = [["8"]];
815 // Maps an original opcode to its commuted version
816 def getCommuteRev : InstrMapping {
817 let FilterClass = "VOP2_REV";
818 let RowFields = ["RevOp"];
819 let ColFields = ["IsOrig"];
821 let ValueCols = [["0"]];
824 def getMaskedMIMGOp : InstrMapping {
825 let FilterClass = "MIMG_Mask";
826 let RowFields = ["Op"];
827 let ColFields = ["Channels"];
829 let ValueCols = [["1"], ["2"], ["3"] ];
832 // Maps an commuted opcode to its original version
833 def getCommuteOrig : InstrMapping {
834 let FilterClass = "VOP2_REV";
835 let RowFields = ["RevOp"];
836 let ColFields = ["IsOrig"];
838 let ValueCols = [["1"]];
841 def isDS : InstrMapping {
842 let FilterClass = "DS";
843 let RowFields = ["Inst"];
844 let ColFields = ["Size"];
846 let ValueCols = [["8"]];
849 def getMCOpcode : InstrMapping {
850 let FilterClass = "SIMCInstr";
851 let RowFields = ["PseudoInstr"];
852 let ColFields = ["Subtarget"];
853 let KeyCol = [!cast<string>(SISubtarget.NONE)];
854 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
857 include "SIInstructions.td"