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 multiclass VOP3_m <bits<9> op, dag outs, dag ins, string asm, list<dag> pattern,
290 def "" : VOP3Common <outs, ins, "", pattern>, VOP <opName>,
291 SIMCInstr<OpName, SISubtarget.NONE> {
295 def _si : VOP3 <op, outs, ins, asm, []>, SIMCInstr<opName, SISubtarget.SI>;
299 // This must always be right before the operand being input modified.
300 def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
301 let PrintMethod = "printOperandAndMods";
304 multiclass VOP1_Helper <bits<8> op, RegisterClass drc, RegisterClass src,
305 string opName, list<dag> pattern> {
308 op, (outs drc:$dst), (ins src:$src0),
309 opName#"_e32 $dst, $src0", pattern
313 {1, 1, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
315 (ins InputMods:$src0_modifiers, src:$src0, i32imm:$clamp, i32imm:$omod),
316 opName#"_e64 $dst, $src0_modifiers, $clamp, $omod", []
318 let src1 = SIOperand.ZERO;
319 let src2 = SIOperand.ZERO;
323 multiclass VOP1_32 <bits<8> op, string opName, list<dag> pattern>
324 : VOP1_Helper <op, VReg_32, VSrc_32, opName, pattern>;
326 multiclass VOP1_64 <bits<8> op, string opName, list<dag> pattern>
327 : VOP1_Helper <op, VReg_64, VSrc_64, opName, pattern>;
329 multiclass VOP1_32_64 <bits<8> op, string opName, list<dag> pattern>
330 : VOP1_Helper <op, VReg_32, VSrc_64, opName, pattern>;
332 multiclass VOP1_64_32 <bits<8> op, string opName, list<dag> pattern>
333 : VOP1_Helper <op, VReg_64, VSrc_32, opName, pattern>;
335 multiclass VOP2_Helper <bits<6> op, RegisterClass vrc, RegisterClass arc,
336 string opName, list<dag> pattern, string revOp> {
338 op, (outs vrc:$dst), (ins arc:$src0, vrc:$src1),
339 opName#"_e32 $dst, $src0, $src1", pattern
340 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
343 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
345 (ins InputMods:$src0_modifiers, arc:$src0,
346 InputMods:$src1_modifiers, arc:$src1,
347 i32imm:$clamp, i32imm:$omod),
348 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
349 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
350 let src2 = SIOperand.ZERO;
354 multiclass VOP2_32 <bits<6> op, string opName, list<dag> pattern,
355 string revOp = opName>
356 : VOP2_Helper <op, VReg_32, VSrc_32, opName, pattern, revOp>;
358 multiclass VOP2_64 <bits<6> op, string opName, list<dag> pattern,
359 string revOp = opName>
360 : VOP2_Helper <op, VReg_64, VSrc_64, opName, pattern, revOp>;
362 multiclass VOP2b_32 <bits<6> op, string opName, list<dag> pattern,
363 RegisterClass src0_rc, string revOp = opName> {
366 op, (outs VReg_32:$dst), (ins src0_rc:$src0, VReg_32:$src1),
367 opName#"_e32 $dst, $src0, $src1", pattern
368 >, VOP <opName>, VOP2_REV<revOp#"_e32", !eq(revOp, opName)>;
371 {1, 0, 0, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
373 (ins InputMods: $src0_modifiers, VSrc_32:$src0,
374 InputMods:$src1_modifiers, VSrc_32:$src1,
375 i32imm:$clamp, i32imm:$omod),
376 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod", []
377 >, VOP <opName>, VOP2_REV<revOp#"_e64", !eq(revOp, opName)> {
378 let src2 = SIOperand.ZERO;
379 /* the VOP2 variant puts the carry out into VCC, the VOP3 variant
380 can write it into any SGPR. We currently don't use the carry out,
381 so for now hardcode it to VCC as well */
382 let sdst = SIOperand.VCC;
386 multiclass VOPC_Helper <bits<8> op, RegisterClass vrc, RegisterClass arc,
387 string opName, ValueType vt, PatLeaf cond, bit defExec = 0> {
389 op, (ins arc:$src0, vrc:$src1),
390 opName#"_e32 $dst, $src0, $src1", []
392 let Defs = !if(defExec, [EXEC], []);
396 {0, op{7}, op{6}, op{5}, op{4}, op{3}, op{2}, op{1}, op{0}},
398 (ins InputMods:$src0_modifiers, arc:$src0,
399 InputMods:$src1_modifiers, arc:$src1,
400 InstFlag:$clamp, InstFlag:$omod),
401 opName#"_e64 $dst, $src0_modifiers, $src1_modifiers, $clamp, $omod",
402 !if(!eq(!cast<string>(cond), "COND_NULL"), []<dag>,
403 [(set SReg_64:$dst, (i1 (setcc (vt arc:$src0), arc:$src1, cond)))]
406 let Defs = !if(defExec, [EXEC], []);
407 let src2 = SIOperand.ZERO;
408 let src2_modifiers = 0;
412 multiclass VOPC_32 <bits<8> op, string opName,
413 ValueType vt = untyped, PatLeaf cond = COND_NULL>
414 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond>;
416 multiclass VOPC_64 <bits<8> op, string opName,
417 ValueType vt = untyped, PatLeaf cond = COND_NULL>
418 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond>;
420 multiclass VOPCX_32 <bits<8> op, string opName,
421 ValueType vt = untyped, PatLeaf cond = COND_NULL>
422 : VOPC_Helper <op, VReg_32, VSrc_32, opName, vt, cond, 1>;
424 multiclass VOPCX_64 <bits<8> op, string opName,
425 ValueType vt = untyped, PatLeaf cond = COND_NULL>
426 : VOPC_Helper <op, VReg_64, VSrc_64, opName, vt, cond, 1>;
428 multiclass VOP3_32 <bits<9> op, string opName, list<dag> pattern> : VOP3_m <
429 op, (outs VReg_32:$dst),
430 (ins InputMods: $src0_modifiers, VSrc_32:$src0, InputMods:$src1_modifiers,
431 VSrc_32:$src1, InputMods:$src2_modifiers, VSrc_32:$src2,
432 InstFlag:$clamp, InstFlag:$omod),
433 opName#" $dst, $src0_modifiers, $src1, $src2, $clamp, $omod", pattern, opName
436 class VOP3_64_32 <bits <9> op, string opName, list<dag> pattern> : VOP3 <
437 op, (outs VReg_64:$dst),
438 (ins VSrc_64:$src0, VSrc_32:$src1),
439 opName#" $dst, $src0, $src1", pattern
442 let src2 = SIOperand.ZERO;
443 let src0_modifiers = 0;
448 class VOP3_64 <bits<9> op, string opName, list<dag> pattern> : VOP3 <
449 op, (outs VReg_64:$dst),
450 (ins InputMods:$src0_modifiers, VSrc_64:$src0,
451 InputMods:$src1_modifiers, VSrc_64:$src1,
452 InputMods:$src2_modifiers, VSrc_64:$src2,
453 InstFlag:$clamp, InstFlag:$omod),
454 opName#" $dst, $src0_modifiers, $src1_modifiers, $src2_modifiers, $clamp, $omod", pattern
458 class VOP3b_Helper <bits<9> op, RegisterClass vrc, RegisterClass arc,
459 string opName, list<dag> pattern> : VOP3 <
460 op, (outs vrc:$dst0, SReg_64:$dst1),
461 (ins arc:$src0, arc:$src1, arc:$src2,
462 InstFlag:$abs, InstFlag:$clamp, InstFlag:$omod, InstFlag:$neg),
463 opName#" $dst0, $dst1, $src0, $src1, $src2, $abs, $clamp, $omod, $neg", pattern
467 class VOP3b_64 <bits<9> op, string opName, list<dag> pattern> :
468 VOP3b_Helper <op, VReg_64, VSrc_64, opName, pattern>;
470 class VOP3b_32 <bits<9> op, string opName, list<dag> pattern> :
471 VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>;
473 //===----------------------------------------------------------------------===//
474 // Vector I/O classes
475 //===----------------------------------------------------------------------===//
477 class DS_1A <bits<8> op, dag outs, dag ins, string asm, list<dag> pat> :
478 DS <op, outs, ins, asm, pat> {
481 // Single load interpret the 2 i8imm operands as a single i16 offset.
482 let offset0 = offset{7-0};
483 let offset1 = offset{15-8};
486 class DS_Load_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
488 (outs regClass:$vdst),
489 (ins i1imm:$gds, VReg_32:$addr, u16imm:$offset),
490 asm#" $vdst, $addr, $offset, [M0]",
498 class DS_Load2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS <
500 (outs regClass:$vdst),
501 (ins i1imm:$gds, VReg_32:$addr, u8imm:$offset0, u8imm:$offset1),
502 asm#" $gds, $vdst, $addr, $offset0, $offset1, [M0]",
510 class DS_Store_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
513 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u16imm:$offset),
514 asm#" $addr, $data0, $offset [M0]",
522 class DS_Store2_Helper <bits<8> op, string asm, RegisterClass regClass> : DS_1A <
525 (ins i1imm:$gds, VReg_32:$addr, regClass:$data0, u8imm:$offset0, u8imm:$offset1),
526 asm#" $addr, $data0, $data1, $offset0, $offset1 [M0]",
533 // 1 address, 1 data.
534 class DS_1A1D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
537 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
538 asm#" $vdst, $addr, $data0, $offset, [M0]",
546 // 1 address, 2 data.
547 class DS_1A2D_RET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
550 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
551 asm#" $vdst, $addr, $data0, $data1, $offset, [M0]",
557 // 1 address, 2 data.
558 class DS_1A2D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
561 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, rc:$data1, u16imm:$offset),
562 asm#" $addr, $data0, $data1, $offset, [M0]",
568 // 1 address, 1 data.
569 class DS_1A1D_NORET <bits<8> op, string asm, RegisterClass rc> : DS_1A <
572 (ins i1imm:$gds, VReg_32:$addr, rc:$data0, u16imm:$offset),
573 asm#" $addr, $data0, $offset, [M0]",
581 class MTBUF_Store_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
584 (ins regClass:$vdata, u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc,
585 i1imm:$addr64, i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr,
586 SReg_128:$srsrc, i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
587 asm#" $vdata, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
588 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
594 multiclass MUBUF_Load_Helper <bits<7> op, string asm, RegisterClass regClass,
595 ValueType load_vt = i32,
596 SDPatternOperator ld = null_frag> {
598 let lds = 0, mayLoad = 1 in {
602 let offen = 0, idxen = 0, vaddr = 0 in {
603 def _OFFSET : MUBUF <op, (outs regClass:$vdata),
604 (ins SReg_128:$srsrc,
605 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
606 i1imm:$slc, i1imm:$tfe),
607 asm#" $vdata, $srsrc + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
610 let offen = 1, idxen = 0 in {
611 def _OFFEN : MUBUF <op, (outs regClass:$vdata),
612 (ins SReg_128:$srsrc, VReg_32:$vaddr,
613 SSrc_32:$soffset, u16imm:$offset, i1imm:$glc, i1imm:$slc,
615 asm#" $vdata, $srsrc + $vaddr + $soffset + $offset, glc=$glc, slc=$slc, tfe=$tfe", []>;
618 let offen = 0, idxen = 1 in {
619 def _IDXEN : MUBUF <op, (outs regClass:$vdata),
620 (ins SReg_128:$srsrc, VReg_32:$vaddr,
621 u16imm:$offset, SSrc_32:$soffset, i1imm:$glc,
622 i1imm:$slc, i1imm:$tfe),
623 asm#" $vdata, $srsrc[$vaddr] + $offset + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
626 let offen = 1, idxen = 1 in {
627 def _BOTHEN : MUBUF <op, (outs regClass:$vdata),
628 (ins SReg_128:$srsrc, VReg_64:$vaddr,
629 SSrc_32:$soffset, i1imm:$glc,
630 i1imm:$slc, i1imm:$tfe),
631 asm#" $vdata, $srsrc[$vaddr[0]] + $vaddr[1] + $soffset, glc=$glc, slc=$slc, tfe=$tfe", []>;
635 let offen = 0, idxen = 0, addr64 = 1, glc = 0, slc = 0, tfe = 0, soffset = 128 /* ZERO */ in {
636 def _ADDR64 : MUBUF <op, (outs regClass:$vdata),
637 (ins SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
638 asm#" $vdata, $srsrc + $vaddr + $offset",
639 [(set load_vt:$vdata, (ld (MUBUFAddr64 v4i32:$srsrc,
640 i64:$vaddr, u16imm:$offset)))]>;
645 multiclass MUBUF_Store_Helper <bits<7> op, string name, RegisterClass vdataClass,
646 ValueType store_vt, SDPatternOperator st> {
650 (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_32:$vaddr, SSrc_32:$soffset,
651 u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$slc,
653 name#" $vdata, $srsrc, $vaddr, $soffset, $offset $offen $idxen $glc $slc $tfe",
659 def _ADDR64 : MUBUF <
661 (ins vdataClass:$vdata, SReg_128:$srsrc, VReg_64:$vaddr, u16imm:$offset),
662 name#" $vdata, $srsrc + $vaddr + $offset",
663 [(st store_vt:$vdata,
664 (MUBUFAddr64 v4i32:$srsrc, i64:$vaddr, u16imm:$offset))]> {
677 let soffset = 128; // ZERO
681 class MTBUF_Load_Helper <bits<3> op, string asm, RegisterClass regClass> : MTBUF <
683 (outs regClass:$dst),
684 (ins u16imm:$offset, i1imm:$offen, i1imm:$idxen, i1imm:$glc, i1imm:$addr64,
685 i8imm:$dfmt, i8imm:$nfmt, VReg_32:$vaddr, SReg_128:$srsrc,
686 i1imm:$slc, i1imm:$tfe, SSrc_32:$soffset),
687 asm#" $dst, $offset, $offen, $idxen, $glc, $addr64, $dfmt,"
688 #" $nfmt, $vaddr, $srsrc, $slc, $tfe, $soffset",
694 class MIMG_Mask <string op, int channels> {
696 int Channels = channels;
699 class MIMG_NoSampler_Helper <bits<7> op, string asm,
700 RegisterClass dst_rc,
701 RegisterClass src_rc> : MIMG <
703 (outs dst_rc:$vdata),
704 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
705 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
707 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
708 #" $tfe, $lwe, $slc, $vaddr, $srsrc",
713 let hasPostISelHook = 1;
716 multiclass MIMG_NoSampler_Src_Helper <bits<7> op, string asm,
717 RegisterClass dst_rc,
719 def _V1 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_32>,
720 MIMG_Mask<asm#"_V1", channels>;
721 def _V2 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_64>,
722 MIMG_Mask<asm#"_V2", channels>;
723 def _V4 : MIMG_NoSampler_Helper <op, asm, dst_rc, VReg_128>,
724 MIMG_Mask<asm#"_V4", channels>;
727 multiclass MIMG_NoSampler <bits<7> op, string asm> {
728 defm _V1 : MIMG_NoSampler_Src_Helper <op, asm, VReg_32, 1>;
729 defm _V2 : MIMG_NoSampler_Src_Helper <op, asm, VReg_64, 2>;
730 defm _V3 : MIMG_NoSampler_Src_Helper <op, asm, VReg_96, 3>;
731 defm _V4 : MIMG_NoSampler_Src_Helper <op, asm, VReg_128, 4>;
734 class MIMG_Sampler_Helper <bits<7> op, string asm,
735 RegisterClass dst_rc,
736 RegisterClass src_rc> : MIMG <
738 (outs dst_rc:$vdata),
739 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
740 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
741 SReg_256:$srsrc, SReg_128:$ssamp),
742 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
743 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
747 let hasPostISelHook = 1;
750 multiclass MIMG_Sampler_Src_Helper <bits<7> op, string asm,
751 RegisterClass dst_rc,
753 def _V1 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_32>,
754 MIMG_Mask<asm#"_V1", channels>;
755 def _V2 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_64>,
756 MIMG_Mask<asm#"_V2", channels>;
757 def _V4 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_128>,
758 MIMG_Mask<asm#"_V4", channels>;
759 def _V8 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_256>,
760 MIMG_Mask<asm#"_V8", channels>;
761 def _V16 : MIMG_Sampler_Helper <op, asm, dst_rc, VReg_512>,
762 MIMG_Mask<asm#"_V16", channels>;
765 multiclass MIMG_Sampler <bits<7> op, string asm> {
766 defm _V1 : MIMG_Sampler_Src_Helper<op, asm, VReg_32, 1>;
767 defm _V2 : MIMG_Sampler_Src_Helper<op, asm, VReg_64, 2>;
768 defm _V3 : MIMG_Sampler_Src_Helper<op, asm, VReg_96, 3>;
769 defm _V4 : MIMG_Sampler_Src_Helper<op, asm, VReg_128, 4>;
772 class MIMG_Gather_Helper <bits<7> op, string asm,
773 RegisterClass dst_rc,
774 RegisterClass src_rc> : MIMG <
776 (outs dst_rc:$vdata),
777 (ins i32imm:$dmask, i1imm:$unorm, i1imm:$glc, i1imm:$da, i1imm:$r128,
778 i1imm:$tfe, i1imm:$lwe, i1imm:$slc, src_rc:$vaddr,
779 SReg_256:$srsrc, SReg_128:$ssamp),
780 asm#" $vdata, $dmask, $unorm, $glc, $da, $r128,"
781 #" $tfe, $lwe, $slc, $vaddr, $srsrc, $ssamp",
786 // DMASK was repurposed for GATHER4. 4 components are always
787 // returned and DMASK works like a swizzle - it selects
788 // the component to fetch. The only useful DMASK values are
789 // 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
790 // (red,red,red,red) etc.) The ISA document doesn't mention
792 // Therefore, disable all code which updates DMASK by setting these two:
794 let hasPostISelHook = 0;
797 multiclass MIMG_Gather_Src_Helper <bits<7> op, string asm,
798 RegisterClass dst_rc,
800 def _V1 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_32>,
801 MIMG_Mask<asm#"_V1", channels>;
802 def _V2 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_64>,
803 MIMG_Mask<asm#"_V2", channels>;
804 def _V4 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_128>,
805 MIMG_Mask<asm#"_V4", channels>;
806 def _V8 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_256>,
807 MIMG_Mask<asm#"_V8", channels>;
808 def _V16 : MIMG_Gather_Helper <op, asm, dst_rc, VReg_512>,
809 MIMG_Mask<asm#"_V16", channels>;
812 multiclass MIMG_Gather <bits<7> op, string asm> {
813 defm _V1 : MIMG_Gather_Src_Helper<op, asm, VReg_32, 1>;
814 defm _V2 : MIMG_Gather_Src_Helper<op, asm, VReg_64, 2>;
815 defm _V3 : MIMG_Gather_Src_Helper<op, asm, VReg_96, 3>;
816 defm _V4 : MIMG_Gather_Src_Helper<op, asm, VReg_128, 4>;
819 //===----------------------------------------------------------------------===//
820 // Vector instruction mappings
821 //===----------------------------------------------------------------------===//
823 // Maps an opcode in e32 form to its e64 equivalent
824 def getVOPe64 : InstrMapping {
825 let FilterClass = "VOP";
826 let RowFields = ["OpName"];
827 let ColFields = ["Size"];
829 let ValueCols = [["8"]];
832 // Maps an opcode in e64 form to its e32 equivalent
833 def getVOPe32 : InstrMapping {
834 let FilterClass = "VOP";
835 let RowFields = ["OpName"];
836 let ColFields = ["Size"];
838 let ValueCols = [["4"]];
841 // Maps an original opcode to its commuted version
842 def getCommuteRev : InstrMapping {
843 let FilterClass = "VOP2_REV";
844 let RowFields = ["RevOp"];
845 let ColFields = ["IsOrig"];
847 let ValueCols = [["0"]];
850 def getMaskedMIMGOp : InstrMapping {
851 let FilterClass = "MIMG_Mask";
852 let RowFields = ["Op"];
853 let ColFields = ["Channels"];
855 let ValueCols = [["1"], ["2"], ["3"] ];
858 // Maps an commuted opcode to its original version
859 def getCommuteOrig : InstrMapping {
860 let FilterClass = "VOP2_REV";
861 let RowFields = ["RevOp"];
862 let ColFields = ["IsOrig"];
864 let ValueCols = [["1"]];
867 def isDS : InstrMapping {
868 let FilterClass = "DS";
869 let RowFields = ["Inst"];
870 let ColFields = ["Size"];
872 let ValueCols = [["8"]];
875 def getMCOpcode : InstrMapping {
876 let FilterClass = "SIMCInstr";
877 let RowFields = ["PseudoInstr"];
878 let ColFields = ["Subtarget"];
879 let KeyCol = [!cast<string>(SISubtarget.NONE)];
880 let ValueCols = [[!cast<string>(SISubtarget.SI)]];
883 include "SIInstructions.td"