1*1db9f3b2SDimitry Andric//===-- DSDIRInstructions.td - LDS/VDS Direct Instruction Definitions -----===//
2*1db9f3b2SDimitry Andric//
3*1db9f3b2SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*1db9f3b2SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*1db9f3b2SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*1db9f3b2SDimitry Andric//
7*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
8*1db9f3b2SDimitry Andric
9*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
10*1db9f3b2SDimitry Andric// LDSDIR/VDSDIR encoding (LDSDIR is gfx11, VDSDIR is gfx12+)
11*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
12*1db9f3b2SDimitry Andric
13*1db9f3b2SDimitry Andricclass LDSDIRe<bits<2> op, bit is_direct> : Enc32 {
14*1db9f3b2SDimitry Andric  // encoding fields
15*1db9f3b2SDimitry Andric  bits<2> attrchan;
16*1db9f3b2SDimitry Andric  bits<6> attr;
17*1db9f3b2SDimitry Andric  bits<4> waitvdst;
18*1db9f3b2SDimitry Andric  bits<8> vdst;
19*1db9f3b2SDimitry Andric
20*1db9f3b2SDimitry Andric  // encoding
21*1db9f3b2SDimitry Andric  let Inst{31-24} = 0xce; // encoding
22*1db9f3b2SDimitry Andric  let Inst{23-22} = 0x0; // reserved
23*1db9f3b2SDimitry Andric  let Inst{21-20} = op;
24*1db9f3b2SDimitry Andric  let Inst{19-16} = waitvdst;
25*1db9f3b2SDimitry Andric  let Inst{15-10} = !if(is_direct, ?, attr);
26*1db9f3b2SDimitry Andric  let Inst{9-8} = !if(is_direct, ?, attrchan);
27*1db9f3b2SDimitry Andric  let Inst{7-0} = vdst;
28*1db9f3b2SDimitry Andric}
29*1db9f3b2SDimitry Andric
30*1db9f3b2SDimitry Andricclass VDSDIRe<bits<2> op, bit is_direct> : Enc32 {
31*1db9f3b2SDimitry Andric  // encoding fields
32*1db9f3b2SDimitry Andric  bits<2> attrchan;
33*1db9f3b2SDimitry Andric  bits<6> attr;
34*1db9f3b2SDimitry Andric  bits<4> waitvdst;
35*1db9f3b2SDimitry Andric  bits<8> vdst;
36*1db9f3b2SDimitry Andric  bits<1> waitvsrc;
37*1db9f3b2SDimitry Andric
38*1db9f3b2SDimitry Andric  // encoding
39*1db9f3b2SDimitry Andric  let Inst{31-24} = 0xce; // encoding
40*1db9f3b2SDimitry Andric  let Inst{23} = waitvsrc;
41*1db9f3b2SDimitry Andric  let Inst{22} = 0x0; // reserved
42*1db9f3b2SDimitry Andric  let Inst{21-20} = op;
43*1db9f3b2SDimitry Andric  let Inst{19-16} = waitvdst;
44*1db9f3b2SDimitry Andric  let Inst{15-10} = !if(is_direct, ?, attr);
45*1db9f3b2SDimitry Andric  let Inst{9-8} = !if(is_direct, ?, attrchan);
46*1db9f3b2SDimitry Andric  let Inst{7-0} = vdst;
47*1db9f3b2SDimitry Andric}
48*1db9f3b2SDimitry Andric
49*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
50*1db9f3b2SDimitry Andric// LDSDIR/VDSDIR Classes
51*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
52*1db9f3b2SDimitry Andric
53*1db9f3b2SDimitry Andricclass LDSDIR_getIns<bit direct> {
54*1db9f3b2SDimitry Andric  dag ret = !if(direct,
55*1db9f3b2SDimitry Andric    (ins wait_vdst:$waitvdst),
56*1db9f3b2SDimitry Andric    (ins InterpAttr:$attr, InterpAttrChan:$attrchan, wait_vdst:$waitvdst)
57*1db9f3b2SDimitry Andric  );
58*1db9f3b2SDimitry Andric}
59*1db9f3b2SDimitry Andric
60*1db9f3b2SDimitry Andricclass VDSDIR_getIns<bit direct> {
61*1db9f3b2SDimitry Andric  dag ret = !if(direct,
62*1db9f3b2SDimitry Andric    (ins wait_va_vdst:$waitvdst, wait_va_vsrc:$waitvsrc),
63*1db9f3b2SDimitry Andric    (ins InterpAttr:$attr, InterpAttrChan:$attrchan, wait_va_vdst:$waitvdst,
64*1db9f3b2SDimitry Andric         wait_va_vsrc:$waitvsrc)
65*1db9f3b2SDimitry Andric  );
66*1db9f3b2SDimitry Andric}
67*1db9f3b2SDimitry Andric
68*1db9f3b2SDimitry Andricclass DSDIR_Common<string opName, string asm = "", dag ins, bit direct> :
69*1db9f3b2SDimitry Andric  InstSI<(outs VGPR_32:$vdst), ins, asm> {
70*1db9f3b2SDimitry Andric  let LDSDIR = 1;
71*1db9f3b2SDimitry Andric  let EXP_CNT = 1;
72*1db9f3b2SDimitry Andric
73*1db9f3b2SDimitry Andric  let hasSideEffects = 0;
74*1db9f3b2SDimitry Andric  let mayLoad = 1;
75*1db9f3b2SDimitry Andric  let mayStore = 0;
76*1db9f3b2SDimitry Andric  let maybeAtomic = 0;
77*1db9f3b2SDimitry Andric
78*1db9f3b2SDimitry Andric  string Mnemonic = opName;
79*1db9f3b2SDimitry Andric  let UseNamedOperandTable = 1;
80*1db9f3b2SDimitry Andric
81*1db9f3b2SDimitry Andric  let Uses = [M0, EXEC];
82*1db9f3b2SDimitry Andric  let DisableWQM = 0;
83*1db9f3b2SDimitry Andric  let SchedRW = [WriteLDS];
84*1db9f3b2SDimitry Andric
85*1db9f3b2SDimitry Andric  bit is_direct;
86*1db9f3b2SDimitry Andric  let is_direct = direct;
87*1db9f3b2SDimitry Andric}
88*1db9f3b2SDimitry Andric
89*1db9f3b2SDimitry Andricclass DSDIR_Pseudo<string opName, dag ins, bit direct> :
90*1db9f3b2SDimitry Andric  DSDIR_Common<opName, "", ins, direct>,
91*1db9f3b2SDimitry Andric  SIMCInstr<opName, SIEncodingFamily.NONE> {
92*1db9f3b2SDimitry Andric  let isPseudo = 1;
93*1db9f3b2SDimitry Andric  let isCodeGenOnly = 1;
94*1db9f3b2SDimitry Andric}
95*1db9f3b2SDimitry Andric
96*1db9f3b2SDimitry Andricclass LDSDIR_getAsm<bit direct> {
97*1db9f3b2SDimitry Andric  string ret = !if(direct,
98*1db9f3b2SDimitry Andric    " $vdst$waitvdst",
99*1db9f3b2SDimitry Andric    " $vdst, $attr$attrchan$waitvdst"
100*1db9f3b2SDimitry Andric  );
101*1db9f3b2SDimitry Andric}
102*1db9f3b2SDimitry Andric
103*1db9f3b2SDimitry Andricclass VDSDIR_getAsm<bit direct> {
104*1db9f3b2SDimitry Andric  string ret = !if(direct,
105*1db9f3b2SDimitry Andric    " $vdst$waitvdst$waitvsrc",
106*1db9f3b2SDimitry Andric    " $vdst, $attr$attrchan$waitvdst$waitvsrc"
107*1db9f3b2SDimitry Andric  );
108*1db9f3b2SDimitry Andric}
109*1db9f3b2SDimitry Andric
110*1db9f3b2SDimitry Andricclass DSDIR_Real<DSDIR_Pseudo lds, dag ins, string asm, int subtarget> :
111*1db9f3b2SDimitry Andric  DSDIR_Common<lds.Mnemonic,
112*1db9f3b2SDimitry Andric               lds.Mnemonic # asm,
113*1db9f3b2SDimitry Andric               ins,
114*1db9f3b2SDimitry Andric               lds.is_direct>,
115*1db9f3b2SDimitry Andric  SIMCInstr <lds.Mnemonic, subtarget> {
116*1db9f3b2SDimitry Andric  let isPseudo = 0;
117*1db9f3b2SDimitry Andric  let isCodeGenOnly = 0;
118*1db9f3b2SDimitry Andric}
119*1db9f3b2SDimitry Andric
120*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
121*1db9f3b2SDimitry Andric// LDS/VDS Direct Instructions
122*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
123*1db9f3b2SDimitry Andric
124*1db9f3b2SDimitry Andriclet SubtargetPredicate = isGFX11Only in {
125*1db9f3b2SDimitry Andric
126*1db9f3b2SDimitry Andricdef LDS_DIRECT_LOAD : DSDIR_Pseudo<"lds_direct_load", LDSDIR_getIns<1>.ret, 1>;
127*1db9f3b2SDimitry Andricdef LDS_PARAM_LOAD : DSDIR_Pseudo<"lds_param_load", LDSDIR_getIns<0>.ret, 0>;
128*1db9f3b2SDimitry Andric
129*1db9f3b2SDimitry Andricdef : GCNPat <
130*1db9f3b2SDimitry Andric  (f32 (int_amdgcn_lds_direct_load M0)),
131*1db9f3b2SDimitry Andric  (LDS_DIRECT_LOAD 0)
132*1db9f3b2SDimitry Andric>;
133*1db9f3b2SDimitry Andric
134*1db9f3b2SDimitry Andricdef : GCNPat <
135*1db9f3b2SDimitry Andric  (f32 (int_amdgcn_lds_param_load timm:$attrchan, timm:$attr, M0)),
136*1db9f3b2SDimitry Andric  (LDS_PARAM_LOAD timm:$attr, timm:$attrchan, 0)
137*1db9f3b2SDimitry Andric>;
138*1db9f3b2SDimitry Andric
139*1db9f3b2SDimitry Andric} // End SubtargetPredicate = isGFX11Only
140*1db9f3b2SDimitry Andric
141*1db9f3b2SDimitry Andriclet SubtargetPredicate = isGFX12Plus in {
142*1db9f3b2SDimitry Andric
143*1db9f3b2SDimitry Andricdef DS_DIRECT_LOAD : DSDIR_Pseudo<"ds_direct_load", VDSDIR_getIns<1>.ret, 1>;
144*1db9f3b2SDimitry Andricdef DS_PARAM_LOAD : DSDIR_Pseudo<"ds_param_load", VDSDIR_getIns<0>.ret, 0>;
145*1db9f3b2SDimitry Andric
146*1db9f3b2SDimitry Andricdef : GCNPat <
147*1db9f3b2SDimitry Andric  (f32 (int_amdgcn_lds_direct_load M0)),
148*1db9f3b2SDimitry Andric  (DS_DIRECT_LOAD 0, 1)
149*1db9f3b2SDimitry Andric>;
150*1db9f3b2SDimitry Andric
151*1db9f3b2SDimitry Andricdef : GCNPat <
152*1db9f3b2SDimitry Andric  (f32 (int_amdgcn_lds_param_load timm:$attrchan, timm:$attr, M0)),
153*1db9f3b2SDimitry Andric  (DS_PARAM_LOAD timm:$attr, timm:$attrchan, 0, 1)
154*1db9f3b2SDimitry Andric>;
155*1db9f3b2SDimitry Andric
156*1db9f3b2SDimitry Andric} // End SubtargetPredicate = isGFX12Only
157*1db9f3b2SDimitry Andric
158*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
159*1db9f3b2SDimitry Andric// GFX11
160*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
161*1db9f3b2SDimitry Andric
162*1db9f3b2SDimitry Andricmulticlass DSDIR_Real_gfx11<bits<2> op,
163*1db9f3b2SDimitry Andric                            DSDIR_Pseudo lds = !cast<DSDIR_Pseudo>(NAME)> {
164*1db9f3b2SDimitry Andric  def _gfx11 : DSDIR_Real<lds, lds.InOperandList,
165*1db9f3b2SDimitry Andric                          LDSDIR_getAsm<lds.is_direct>.ret,
166*1db9f3b2SDimitry Andric                          SIEncodingFamily.GFX11>,
167*1db9f3b2SDimitry Andric               LDSDIRe<op, lds.is_direct> {
168*1db9f3b2SDimitry Andric    let AssemblerPredicate = isGFX11Only;
169*1db9f3b2SDimitry Andric    let DecoderNamespace = "GFX11";
170*1db9f3b2SDimitry Andric  }
171*1db9f3b2SDimitry Andric}
172*1db9f3b2SDimitry Andric
173*1db9f3b2SDimitry Andricdefm LDS_PARAM_LOAD : DSDIR_Real_gfx11<0x0>;
174*1db9f3b2SDimitry Andricdefm LDS_DIRECT_LOAD : DSDIR_Real_gfx11<0x1>;
175*1db9f3b2SDimitry Andric
176*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
177*1db9f3b2SDimitry Andric// GFX12+
178*1db9f3b2SDimitry Andric//===----------------------------------------------------------------------===//
179*1db9f3b2SDimitry Andric
180*1db9f3b2SDimitry Andricmulticlass DSDIR_Real_gfx12<bits<2> op,
181*1db9f3b2SDimitry Andric                            DSDIR_Pseudo lds = !cast<DSDIR_Pseudo>(NAME)> {
182*1db9f3b2SDimitry Andric  def _gfx12 : DSDIR_Real<lds, lds.InOperandList,
183*1db9f3b2SDimitry Andric                          VDSDIR_getAsm<lds.is_direct>.ret,
184*1db9f3b2SDimitry Andric                          SIEncodingFamily.GFX12>,
185*1db9f3b2SDimitry Andric               VDSDIRe<op, lds.is_direct> {
186*1db9f3b2SDimitry Andric    let AssemblerPredicate = isGFX12Plus;
187*1db9f3b2SDimitry Andric    let DecoderNamespace = "GFX12";
188*1db9f3b2SDimitry Andric  }
189*1db9f3b2SDimitry Andric}
190*1db9f3b2SDimitry Andric
191*1db9f3b2SDimitry Andricdefm DS_PARAM_LOAD : DSDIR_Real_gfx12<0x0>;
192*1db9f3b2SDimitry Andricdefm DS_DIRECT_LOAD : DSDIR_Real_gfx12<0x1>;
193