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 MUBUFAddr32 : ComplexPattern<i64, 9, "SelectMUBUFAddr32">;
167 def MUBUFAddr64 : ComplexPattern<i64, 3, "SelectMUBUFAddr64">;
168 def MUBUFScratch : ComplexPattern<i64, 4, "SelectMUBUFScratch">;
170 //===----------------------------------------------------------------------===//
171 // SI assembler operands
172 //===----------------------------------------------------------------------===//
179 include "SIInstrFormats.td"
181 //===----------------------------------------------------------------------===//
183 // SI Instruction multiclass helpers.
185 // Instructions with _32 take 32-bit operands.
186 // Instructions with _64 take 64-bit operands.
188 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
189 // encoding is the standard encoding, but instruction that make use of
190 // any of the instruction modifiers must use the 64-bit encoding.
192 // Instructions with _e32 use the 32-bit encoding.
193 // Instructions with _e64 use the 64-bit encoding.
195 //===----------------------------------------------------------------------===//
197 //===----------------------------------------------------------------------===//
199 //===----------------------------------------------------------------------===//
201 class SOP1_32 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
202 op, (outs SReg_32:$dst), (ins SSrc_32:$src0),
203 opName#" $dst, $src0", pattern
206 class SOP1_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
207 op, (outs SReg_64:$dst), (ins SSrc_64:$src0),
208 opName#" $dst, $src0", pattern
211 // 64-bit input, 32-bit output.
212 class SOP1_32_64 <bits<8> op, string opName, list<dag> pattern> : SOP1 <
213 op, (outs SReg_32:$dst), (ins SSrc_64:$src0),
214 opName#" $dst, $src0", pattern
217 class SOP2_32 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
218 op, (outs SReg_32:$dst), (ins SSrc_32:$src0, SSrc_32:$src1),
219 opName#" $dst, $src0, $src1", pattern
222 class SOP2_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
223 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_64:$src1),
224 opName#" $dst, $src0, $src1", pattern
227 class SOP2_SHIFT_64 <bits<7> op, string opName, list<dag> pattern> : SOP2 <
228 op, (outs SReg_64:$dst), (ins SSrc_64:$src0, SSrc_32:$src1),
229 opName#" $dst, $src0, $src1", pattern
233 class SOPC_Helper <bits<7> op, RegisterClass rc, ValueType vt,
234 string opName, PatLeaf cond> : SOPC <
235 op, (outs SCCReg:$dst), (ins rc:$src0, rc:$src1),
236 opName#" $dst, $src0, $src1", []>;
238 class SOPC_32<bits<7> op, string opName, PatLeaf cond = COND_NULL>
239 : SOPC_Helper<op, SSrc_32, i32, opName, cond>;
241 class SOPC_64<bits<7> op, string opName, PatLeaf cond = COND_NULL>
242 : SOPC_Helper<op, SSrc_64, i64, opName, cond>;
244 class SOPK_32 <bits<5> op, string opName, list<dag> pattern> : SOPK <
245 op, (outs SReg_32:$dst), (ins i16imm:$src0),
246 opName#" $dst, $src0", pattern
249 class SOPK_64 <bits<5> op, string opName, list<dag> pattern> : SOPK <
250 op, (outs SReg_64:$dst), (ins i16imm:$src0),
251 opName#" $dst, $src0", pattern
254 multiclass SMRD_Helper <bits<5> op, string asm, RegisterClass baseClass,
255 RegisterClass dstClass> {
257 op, 1, (outs dstClass:$dst),
258 (ins baseClass:$sbase, u32imm:$offset),
259 asm#" $dst, $sbase, $offset", []
263 op, 0, (outs dstClass:$dst),
264 (ins baseClass:$sbase, SReg_32:$soff),
265 asm#" $dst, $sbase, $soff", []
269 //===----------------------------------------------------------------------===//
270 // Vector ALU classes
271 //===----------------------------------------------------------------------===//
273 class VOP <string opName> {
274 string OpName = opName;
277 class VOP2_REV <string revOp, bit isOrig> {
278 string RevOp = revOp;
282 class SIMCInstr <string pseudo, int subtarget> {
283 string PseudoInstr = pseudo;
284 int Subtarget = subtarget;
287 class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
288 VOP3Common <outs, ins, "", pattern>,
290 SIMCInstr<opName, SISubtarget.NONE> {
294 class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
295 VOP3 <op, outs, ins, asm, []>,
296 SIMCInstr<opName, SISubtarget.SI>;
298 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
301 def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
303 def _si : VOP3_Real_si <op, outs, ins, asm, opName>;
307 multiclass VOP3_1_m <bits<8> op, dag outs, dag ins, string asm,
308 list<dag> pattern, string opName> {
310 def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
312 let src1 = 0, src1_modifiers = 0, src2 = 0, src2_modifiers = 0 in {
314 def _si : VOP3_Real_si <
315 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
316 outs, ins, asm, opName
319 } // src1 = 0, src1_modifiers = 0, src2 = 0, src2_modifiers = 0
322 multiclass VOP3_2_m <bits<6> op, dag outs, dag ins, string asm,
323 list<dag> pattern, string opName, string revOp> {
325 def "" : VOP3_Pseudo <outs, ins, pattern, opName>;
327 let src2 = 0, src2_modifiers = 0 in {
329 def _si : VOP3_Real_si <
330 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
331 outs, ins, asm, opName>,
332 VOP2_REV<revOp#"_e64", !eq(revOp, opName)>;
334 } // src2 = 0, src2_modifiers = 0
337 // This must always be right before the operand being input modified.
338 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
339 let PrintMethod = "printOperandAndMods";
342 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
343 string opName, list<dag> pattern> {
346 op, (outs drc:$dst), (ins src:$src0),
347 opName#"_e32 $dst, $src0", pattern
350 defm _e64 : VOP3_1_m <
353 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
354 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", [], opName>;
357 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
358 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
360 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
361 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
363 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
364 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
366 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
367 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
369 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
370 string opName, list<dag> pattern, string revOp> {
372 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
373 opName#"_e32 $dst, $src0, $src1", pattern
374 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
376 defm _e64 : VOP3_2_m <
379 (ins InputMods:$src0_modifiers, arc:$src0,
380 InputMods:$src1_modifiers, arc:$src1,
381 i32imm:$clamp, i32imm:$omod),
382 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", [],
386 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
387 string revOp = opName>
388 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
390 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
391 string revOp = opName>
392 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
394 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
395 RegisterClass src0_rc, string revOp = opName> {
398 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
399 opName#"_e32 $dst, $src0, $src1", pattern
400 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
403 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
405 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
406 InputMods:$src1_modifiers, VSrc_32:$src1,
407 i32imm:$clamp, i32imm:$omod),
408 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
409 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
411 let src2_modifiers = 0;
412 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
413 can write it into any SGPR. We currently don't use the carry out,
414 so for now hardcode it to VCC as well */
415 let sdst = SIOperand.VCC;
419 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
420 string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
422 op, (ins arc:$src0, vrc:$src1),
423 opName#"_e32 $dst, $src0, $src1", []
425 let Defs = !if(defExec, [EXEC], []);
429 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
431 (ins InputMods:$src0_modifiers, arc:$src0,
432 InputMods:$src1_modifiers, arc:$src1,
433 InstFlag:$clamp, InstFlag:$omod),
434 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
435 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
436 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
439 let Defs = !if(defExec, [EXEC], []);
441 let src2_modifiers = 0;
445 multiclass VOPC_32 <bits<8> op, string opName,
446 ValueType vt = untyped, PatLeaf cond = COND_NULL>
447 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
449 multiclass VOPC_64 <bits<8> op, string opName,
450 ValueType vt = untyped, PatLeaf cond = COND_NULL>
451 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
453 multiclass VOPCX_32 <bits<8> op, string opName,
454 ValueType vt = untyped, PatLeaf cond = COND_NULL>
455 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
457 multiclass VOPCX_64 <bits<8> op, string opName,
458 ValueType vt = untyped, PatLeaf cond = COND_NULL>
459 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
461 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
462 op, (outs VReg_32:$dst),
463 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
464 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
465 InstFlag:$clamp, InstFlag:$omod),
466 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
469 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
470 op, (outs VReg_64:$dst),
471 (ins VSrc_64:$src0, VSrc_32:$src1),
472 opName#" $dst, $src0, $src1", pattern
476 let src2_modifiers = 0;
477 let src0_modifiers = 0;
482 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
483 op, (outs VReg_64:$dst),
484 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
485 InputMods:$src1_modifiers, VSrc_64:$src1,
486 InputMods:$src2_modifiers, VSrc_64:$src2,
487 InstFlag:$clamp, InstFlag:$omod),
488 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
492 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
493 string opName, list<dag> pattern> : VOP3 <
494 op, (outs vrc:$dst0, SReg_64:$dst1),
495 (ins arc:$src0, arc:$src1, arc:$src2,
496 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
497 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
501 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
502 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
504 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
505 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
507 //===----------------------------------------------------------------------===//
508 // Vector I/O classes
509 //===----------------------------------------------------------------------===//
511 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
512 DS <op, outs, ins, asm, pat> {
515 // Single load interpret the 2 i8imm operands as a single i16 offset.
516 let offset0 = offset{7-0};
517 let offset1 = offset{15-8};
520 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
522 (outs regClass:$vdst),
523 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
524 asm#" $vdst, $addr, $offset, [M0]",
532 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
534 (outs regClass:$vdst),
535 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
536 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
544 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
547 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
548 asm#" $addr, $data0, $offset [M0]",
556 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
559 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
560 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
567 // 1 address, 1 data.
568 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
571 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
572 asm#" $vdst, $addr, $data0, $offset, [M0]",
580 // 1 address, 2 data.
581 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
584 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
585 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
591 // 1 address, 2 data.
592 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
595 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
596 asm#" $addr, $data0, $data1, $offset, [M0]",
602 // 1 address, 1 data.
603 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
606 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
607 asm#" $addr, $data0, $offset, [M0]",
615 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
618 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
619 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
620 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
621 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
622 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
628 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
629 ValueType load_vt = i32,
630 SDPatternOperator ld = null_frag> {
632 let lds = 0, mayLoad = 1 in {
636 let offen = 0, idxen = 0, vaddr = 0 in {
637 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
638 (ins SReg_128:$srsrc,
639 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
640 i1imm:$slc, i1imm:$tfe),
641 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
644 let offen = 1, idxen = 0 in {
645 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
646 (ins SReg_128:$srsrc, VReg_32:$vaddr,
647 SSrc_32:$soffset, u16imm:$offset, i1imm:$glc, i1imm:$slc,
649 asm#" $vdata, $srsrc + $vaddr + $soffset + $offset, glc=$glc, slc=$slc, tfe=$tfe", []>;
652 let offen = 0, idxen = 1 in {
653 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
654 (ins SReg_128:$srsrc, VReg_32:$vaddr,
655 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
656 i1imm:$slc, i1imm:$tfe),
657 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
660 let offen = 1, idxen = 1 in {
661 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
662 (ins SReg_128:$srsrc, VReg_64:$vaddr,
663 SSrc_32:$soffset, i1imm:$glc,
664 i1imm:$slc, i1imm:$tfe),
665 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
669 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
670 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
671 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
672 asm#" $vdata, $srsrc + $vaddr + $offset",
673 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
674 i64:$vaddr, u16imm:$offset)))]>;
679 multiclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
680 ValueType store_vt, SDPatternOperator st> {
684 (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_32:$vaddr, SSrc_32:$soffset,
685 u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$slc,
687 name#" $vdata, $srsrc, $vaddr, $soffset, $offset $offen $idxen $glc $slc $tfe",
693 def _ADDR64 : MUBUF <
695 (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
696 name#" $vdata, $srsrc + $vaddr + $offset",
697 [(st store_vt:$vdata,
698 (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
711 let soffset = 128; // ZERO
715 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
717 (outs regClass:$dst),
718 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
719 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
720 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
721 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
722 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
728 class MIMG_Mask <string op, int channels> {
730 int Channels = channels;
733 class MIMG_NoSampler_Helper <bits<7> op, string asm,
734 RegisterClass dst_rc,
735 RegisterClass src_rc> : MIMG <
737 (outs dst_rc:$vdata),
738 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
739 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
741 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
742 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
747 let hasPostISelHook = 1;
750 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
751 RegisterClass dst_rc,
753 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
754 MIMG_Mask<asm#"_V1", channels>;
755 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
756 MIMG_Mask<asm#"_V2", channels>;
757 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
758 MIMG_Mask<asm#"_V4", channels>;
761 multiclass MIMG_NoSampler <bits<7> op, string asm> {
762 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
763 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
764 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
765 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
768 class MIMG_Sampler_Helper <bits<7> op, string asm,
769 RegisterClass dst_rc,
770 RegisterClass src_rc> : MIMG <
772 (outs dst_rc:$vdata),
773 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
774 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
775 SReg_256:$srsrc, SReg_128:$ssamp),
776 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
777 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
781 let hasPostISelHook = 1;
784 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
785 RegisterClass dst_rc,
787 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
788 MIMG_Mask<asm#"_V1", channels>;
789 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
790 MIMG_Mask<asm#"_V2", channels>;
791 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
792 MIMG_Mask<asm#"_V4", channels>;
793 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
794 MIMG_Mask<asm#"_V8", channels>;
795 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
796 MIMG_Mask<asm#"_V16", channels>;
799 multiclass MIMG_Sampler <bits<7> op, string asm> {
800 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
801 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
802 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
803 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
806 class MIMG_Gather_Helper <bits<7> op, string asm,
807 RegisterClass dst_rc,
808 RegisterClass src_rc> : MIMG <
810 (outs dst_rc:$vdata),
811 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
812 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
813 SReg_256:$srsrc, SReg_128:$ssamp),
814 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
815 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
820 // DMASK was repurposed for GATHER4. 4 components are always
821 // returned and DMASK works like a swizzle - it selects
822 // the component to fetch. The only useful DMASK values are
823 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
824 // (red,red,red,red) etc.) The ISA document doesn't mention
826 // Therefore, disable all code which updates DMASK by setting these two:
828 let hasPostISelHook = 0;
831 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
832 RegisterClass dst_rc,
834 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
835 MIMG_Mask<asm#"_V1", channels>;
836 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
837 MIMG_Mask<asm#"_V2", channels>;
838 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
839 MIMG_Mask<asm#"_V4", channels>;
840 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
841 MIMG_Mask<asm#"_V8", channels>;
842 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
843 MIMG_Mask<asm#"_V16", channels>;
846 multiclass MIMG_Gather <bits<7> op, string asm> {
847 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
848 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
849 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
850 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
853 //===----------------------------------------------------------------------===//
854 // Vector instruction mappings
855 //===----------------------------------------------------------------------===//
857 // Maps an opcode in e32 form to its e64 equivalent
858 def getVOPe64 : InstrMapping {
859 let FilterClass = "VOP";
860 let RowFields = ["OpName"];
861 let ColFields = ["Size"];
863 let ValueCols = [["8"]];
866 // Maps an opcode in e64 form to its e32 equivalent
867 def getVOPe32 : InstrMapping {
868 let FilterClass = "VOP";
869 let RowFields = ["OpName"];
870 let ColFields = ["Size"];
872 let ValueCols = [["4"]];
875 // Maps an original opcode to its commuted version
876 def getCommuteRev : InstrMapping {
877 let FilterClass = "VOP2_REV";
878 let RowFields = ["RevOp"];
879 let ColFields = ["IsOrig"];
881 let ValueCols = [["0"]];
884 def getMaskedMIMGOp : InstrMapping {
885 let FilterClass = "MIMG_Mask";
886 let RowFields = ["Op"];
887 let ColFields = ["Channels"];
889 let ValueCols = [["1"], ["2"], ["3"] ];
892 // Maps an commuted opcode to its original version
893 def getCommuteOrig : InstrMapping {
894 let FilterClass = "VOP2_REV";
895 let RowFields = ["RevOp"];
896 let ColFields = ["IsOrig"];
898 let ValueCols = [["1"]];
901 def isDS : InstrMapping {
902 let FilterClass = "DS";
903 let RowFields = ["Inst"];
904 let ColFields = ["Size"];
906 let ValueCols = [["8"]];
909 def getMCOpcode : InstrMapping {
910 let FilterClass = "SIMCInstr";
911 let RowFields = ["PseudoInstr"];
912 let ColFields = ["Subtarget"];
913 let KeyCol = [!cast<string>(SISubtarget.NONE)];
914 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
917 include "SIInstructions.td"