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 //===----------------------------------------------------------------------===//
151 //===----------------------------------------------------------------------===//
153 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
155 //===----------------------------------------------------------------------===//
156 // SI assembler operands
157 //===----------------------------------------------------------------------===//
164 include "SIInstrFormats.td"
166 //===----------------------------------------------------------------------===//
168 // SI Instruction multiclass helpers.
170 // Instructions with _32 take 32-bit operands.
171 // Instructions with _64 take 64-bit operands.
173 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
174 // encoding is the standard encoding, but instruction that make use of
175 // any of the instruction modifiers must use the 64-bit encoding.
177 // Instructions with _e32 use the 32-bit encoding.
178 // Instructions with _e64 use the 64-bit encoding.
180 //===----------------------------------------------------------------------===//
182 //===----------------------------------------------------------------------===//
184 //===----------------------------------------------------------------------===//
186 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
187 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
188 opName#" $dst, $src0", pattern
191 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
192 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
193 opName#" $dst, $src0", pattern
196 // 64-bit input, 32-bit output.
197 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
198 op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
199 opName#" $dst, $src0", pattern
202 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
203 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
204 opName#" $dst, $src0, $src1", pattern
207 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
208 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
209 opName#" $dst, $src0, $src1", pattern
212 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
213 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
214 opName#" $dst, $src0, $src1", pattern
218 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
219 string opName, PatLeaf cond> : SOPC <
220 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
221 opName#" $dst, $src0, $src1", []>;
223 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
224 : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
226 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
227 : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
229 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
230 op, (outs SReg_32:$dst), (ins i16imm:$src0),
231 opName#" $dst, $src0", pattern
234 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
235 op, (outs SReg_64:$dst), (ins i16imm:$src0),
236 opName#" $dst, $src0", pattern
239 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
240 RegisterClass dstClass> {
242 op, 1, (outs dstClass:$dst),
243 (ins baseClass:$sbase, u32imm:$offset),
244 asm#" $dst, $sbase, $offset", []
248 op, 0, (outs dstClass:$dst),
249 (ins baseClass:$sbase, SReg_32:$soff),
250 asm#" $dst, $sbase, $soff", []
254 //===----------------------------------------------------------------------===//
255 // Vector ALU classes
256 //===----------------------------------------------------------------------===//
258 class VOP <string opName> {
259 string OpName = opName;
262 class VOP2_REV <string revOp, bit isOrig> {
263 string RevOp = revOp;
267 class SIMCInstr <string pseudo, int subtarget> {
268 string PseudoInstr = pseudo;
269 int Subtarget = subtarget;
272 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
275 def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
276 SIMCInstr<OpName, SISubtarget.NONE> {
280 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
284 // This must always be right before the operand being input modified.
285 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
286 let PrintMethod = "printOperandAndMods";
289 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
290 string opName, list<dag> pattern> {
293 op, (outs drc:$dst), (ins src:$src0),
294 opName#"_e32 $dst, $src0", pattern
298 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
300 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
301 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
303 let src1 = SIOperand.ZERO;
304 let src2 = SIOperand.ZERO;
308 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
309 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
311 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
312 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
314 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
315 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
317 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
318 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
320 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
321 string opName, list<dag> pattern, string revOp> {
323 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
324 opName#"_e32 $dst, $src0, $src1", pattern
325 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
328 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
330 (ins InputMods:$src0_modifiers, arc:$src0,
331 InputMods:$src1_modifiers, arc:$src1,
332 i32imm:$clamp, i32imm:$omod),
333 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
334 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
335 let src2 = SIOperand.ZERO;
339 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
340 string revOp = opName>
341 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
343 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
344 string revOp = opName>
345 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
347 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
348 RegisterClass src0_rc, string revOp = opName> {
351 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
352 opName#"_e32 $dst, $src0, $src1", pattern
353 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
356 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
358 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
359 InputMods:$src1_modifiers, VSrc_32:$src1,
360 i32imm:$clamp, i32imm:$omod),
361 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
362 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
363 let src2 = SIOperand.ZERO;
364 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
365 can write it into any SGPR. We currently don't use the carry out,
366 so for now hardcode it to VCC as well */
367 let sdst = SIOperand.VCC;
371 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
372 string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
374 op, (ins arc:$src0, vrc:$src1),
375 opName#"_e32 $dst, $src0, $src1", []
377 let Defs = !if(defExec, [VCC, EXEC], [VCC]);
381 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
383 (ins InputMods:$src0_modifiers, arc:$src0,
384 InputMods:$src1_modifiers, arc:$src1,
385 InstFlag:$clamp, InstFlag:$omod),
386 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
387 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
388 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
391 let Defs = !if(defExec, [EXEC], []);
392 let src2 = SIOperand.ZERO;
393 let src2_modifiers = 0;
397 multiclass VOPC_32 <bits<8> op, string opName,
398 ValueType vt = untyped, PatLeaf cond = COND_NULL>
399 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
401 multiclass VOPC_64 <bits<8> op, string opName,
402 ValueType vt = untyped, PatLeaf cond = COND_NULL>
403 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
405 multiclass VOPCX_32 <bits<8> op, string opName,
406 ValueType vt = untyped, PatLeaf cond = COND_NULL>
407 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
409 multiclass VOPCX_64 <bits<8> op, string opName,
410 ValueType vt = untyped, PatLeaf cond = COND_NULL>
411 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
413 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
414 op, (outs VReg_32:$dst),
415 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
416 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
417 InstFlag:$clamp, InstFlag:$omod),
418 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
421 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
422 op, (outs VReg_64:$dst),
423 (ins VSrc_64:$src0, VSrc_32:$src1),
424 opName#" $dst, $src0, $src1", pattern
427 let src2 = SIOperand.ZERO;
428 let src0_modifiers = 0;
433 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
434 op, (outs VReg_64:$dst),
435 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
436 InputMods:$src1_modifiers, VSrc_64:$src1,
437 InputMods:$src2_modifiers, VSrc_64:$src2,
438 InstFlag:$clamp, InstFlag:$omod),
439 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
443 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
444 string opName, list<dag> pattern> : VOP3 <
445 op, (outs vrc:$dst0, SReg_64:$dst1),
446 (ins arc:$src0, arc:$src1, arc:$src2,
447 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
448 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
452 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
453 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
455 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
456 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
458 //===----------------------------------------------------------------------===//
459 // Vector I/O classes
460 //===----------------------------------------------------------------------===//
462 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
463 DS <op, outs, ins, asm, pat> {
466 // Single load interpret the 2 i8imm operands as a single i16 offset.
467 let offset0 = offset{7-0};
468 let offset1 = offset{15-8};
471 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
473 (outs regClass:$vdst),
474 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
475 asm#" $vdst, $addr, $offset, [M0]",
483 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
485 (outs regClass:$vdst),
486 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
487 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
495 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
498 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
499 asm#" $addr, $data0, $offset [M0]",
507 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
510 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
511 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
518 // 1 address, 1 data.
519 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
522 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
523 asm#" $vdst, $addr, $data0, $offset, [M0]",
531 // 1 address, 2 data.
532 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
535 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
536 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
542 // 1 address, 2 data.
543 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
546 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
547 asm#" $addr, $data0, $data1, $offset, [M0]",
553 // 1 address, 1 data.
554 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
557 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
558 asm#" $addr, $data0, $offset, [M0]",
566 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
569 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
570 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
571 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
572 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
573 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
579 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
580 ValueType load_vt = i32,
581 SDPatternOperator ld = null_frag> {
583 let lds = 0, mayLoad = 1 in {
587 let offen = 0, idxen = 0 in {
588 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
589 (ins SReg_128:$srsrc, VReg_32:$vaddr,
590 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
591 i1imm:$slc, i1imm:$tfe),
592 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
595 let offen = 1, idxen = 0, offset = 0 in {
596 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
597 (ins SReg_128:$srsrc, VReg_32:$vaddr,
598 SSrc_32:$soffset, i1imm:$glc, i1imm:$slc,
600 asm#" $vdata, $srsrc + $vaddr + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
603 let offen = 0, idxen = 1 in {
604 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
605 (ins SReg_128:$srsrc, VReg_32:$vaddr,
606 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
607 i1imm:$slc, i1imm:$tfe),
608 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
611 let offen = 1, idxen = 1 in {
612 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
613 (ins SReg_128:$srsrc, VReg_64:$vaddr,
614 SSrc_32:$soffset, i1imm:$glc,
615 i1imm:$slc, i1imm:$tfe),
616 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
620 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
621 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
622 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
623 asm#" $vdata, $srsrc + $vaddr + $offset",
624 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
625 i64:$vaddr, u16imm:$offset)))]>;
630 class MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
631 ValueType store_vt, SDPatternOperator st> :
632 MUBUF <op, (outs), (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr,
634 name#" $vdata, $srsrc + $vaddr + $offset",
635 [(st store_vt:$vdata, (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
648 let soffset = 128; // ZERO
651 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
653 (outs regClass:$dst),
654 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
655 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
656 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
657 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
658 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
664 class MIMG_Mask <string op, int channels> {
666 int Channels = channels;
669 class MIMG_NoSampler_Helper <bits<7> op, string asm,
670 RegisterClass dst_rc,
671 RegisterClass src_rc> : MIMG <
673 (outs dst_rc:$vdata),
674 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
675 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
677 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
678 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
683 let hasPostISelHook = 1;
686 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
687 RegisterClass dst_rc,
689 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
690 MIMG_Mask<asm#"_V1", channels>;
691 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
692 MIMG_Mask<asm#"_V2", channels>;
693 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
694 MIMG_Mask<asm#"_V4", channels>;
697 multiclass MIMG_NoSampler <bits<7> op, string asm> {
698 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
699 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
700 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
701 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
704 class MIMG_Sampler_Helper <bits<7> op, string asm,
705 RegisterClass dst_rc,
706 RegisterClass src_rc> : MIMG <
708 (outs dst_rc:$vdata),
709 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
710 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
711 SReg_256:$srsrc, SReg_128:$ssamp),
712 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
713 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
717 let hasPostISelHook = 1;
720 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
721 RegisterClass dst_rc,
723 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
724 MIMG_Mask<asm#"_V1", channels>;
725 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
726 MIMG_Mask<asm#"_V2", channels>;
727 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
728 MIMG_Mask<asm#"_V4", channels>;
729 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
730 MIMG_Mask<asm#"_V8", channels>;
731 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
732 MIMG_Mask<asm#"_V16", channels>;
735 multiclass MIMG_Sampler <bits<7> op, string asm> {
736 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
737 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
738 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
739 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
742 class MIMG_Gather_Helper <bits<7> op, string asm,
743 RegisterClass dst_rc,
744 RegisterClass src_rc> : MIMG <
746 (outs dst_rc:$vdata),
747 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
748 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
749 SReg_256:$srsrc, SReg_128:$ssamp),
750 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
751 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
756 // DMASK was repurposed for GATHER4. 4 components are always
757 // returned and DMASK works like a swizzle - it selects
758 // the component to fetch. The only useful DMASK values are
759 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
760 // (red,red,red,red) etc.) The ISA document doesn't mention
762 // Therefore, disable all code which updates DMASK by setting these two:
764 let hasPostISelHook = 0;
767 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
768 RegisterClass dst_rc,
770 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
771 MIMG_Mask<asm#"_V1", channels>;
772 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
773 MIMG_Mask<asm#"_V2", channels>;
774 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
775 MIMG_Mask<asm#"_V4", channels>;
776 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
777 MIMG_Mask<asm#"_V8", channels>;
778 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
779 MIMG_Mask<asm#"_V16", channels>;
782 multiclass MIMG_Gather <bits<7> op, string asm> {
783 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
784 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
785 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
786 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
789 //===----------------------------------------------------------------------===//
790 // Vector instruction mappings
791 //===----------------------------------------------------------------------===//
793 // Maps an opcode in e32 form to its e64 equivalent
794 def getVOPe64 : InstrMapping {
795 let FilterClass = "VOP";
796 let RowFields = ["OpName"];
797 let ColFields = ["Size"];
799 let ValueCols = [["8"]];
802 // Maps an original opcode to its commuted version
803 def getCommuteRev : InstrMapping {
804 let FilterClass = "VOP2_REV";
805 let RowFields = ["RevOp"];
806 let ColFields = ["IsOrig"];
808 let ValueCols = [["0"]];
811 def getMaskedMIMGOp : InstrMapping {
812 let FilterClass = "MIMG_Mask";
813 let RowFields = ["Op"];
814 let ColFields = ["Channels"];
816 let ValueCols = [["1"], ["2"], ["3"] ];
819 // Maps an commuted opcode to its original version
820 def getCommuteOrig : InstrMapping {
821 let FilterClass = "VOP2_REV";
822 let RowFields = ["RevOp"];
823 let ColFields = ["IsOrig"];
825 let ValueCols = [["1"]];
828 def isDS : InstrMapping {
829 let FilterClass = "DS";
830 let RowFields = ["Inst"];
831 let ColFields = ["Size"];
833 let ValueCols = [["8"]];
836 def getMCOpcode : InstrMapping {
837 let FilterClass = "SIMCInstr";
838 let RowFields = ["PseudoInstr"];
839 let ColFields = ["Subtarget"];
840 let KeyCol = [!cast<string>(SISubtarget.NONE)];
841 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
844 include "SIInstructions.td"