Skip to content

Commit 82e33d6

Browse files
authored
[AMDGPU] Add VDSDIR instructions for GFX12 (#75197)
1 parent 329ba52 commit 82e33d6

File tree

12 files changed

+679
-150
lines changed

12 files changed

+679
-150
lines changed

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ class AMDGPUOperand : public MCParsedAsmOperand {
166166
ImmTyEndpgm,
167167
ImmTyWaitVDST,
168168
ImmTyWaitEXP,
169+
ImmTyWaitVAVDst,
170+
ImmTyWaitVMVSrc,
169171
};
170172

171173
// Immediate operand kind.
@@ -909,6 +911,8 @@ class AMDGPUOperand : public MCParsedAsmOperand {
909911
bool isEndpgm() const;
910912
bool isWaitVDST() const;
911913
bool isWaitEXP() const;
914+
bool isWaitVAVDst() const;
915+
bool isWaitVMVSrc() const;
912916

913917
auto getPredicate(std::function<bool(const AMDGPUOperand &Op)> P) const {
914918
return std::bind(P, *this);
@@ -1029,6 +1033,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
10291033
}
10301034

10311035
static void printImmTy(raw_ostream& OS, ImmTy Type) {
1036+
// clang-format off
10321037
switch (Type) {
10331038
case ImmTyNone: OS << "None"; break;
10341039
case ImmTyGDS: OS << "GDS"; break;
@@ -1086,7 +1091,10 @@ class AMDGPUOperand : public MCParsedAsmOperand {
10861091
case ImmTyEndpgm: OS << "Endpgm"; break;
10871092
case ImmTyWaitVDST: OS << "WaitVDST"; break;
10881093
case ImmTyWaitEXP: OS << "WaitEXP"; break;
1094+
case ImmTyWaitVAVDst: OS << "WaitVAVDst"; break;
1095+
case ImmTyWaitVMVSrc: OS << "WaitVMVSrc"; break;
10891096
}
1097+
// clang-format on
10901098
}
10911099

10921100
void print(raw_ostream &OS) const override {
@@ -9192,6 +9200,14 @@ bool AMDGPUOperand::isWaitVDST() const {
91929200
return isImmTy(ImmTyWaitVDST) && isUInt<4>(getImm());
91939201
}
91949202

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

llvm/lib/Target/AMDGPU/LDSDIRInstructions.td

Lines changed: 0 additions & 116 deletions
This file was deleted.

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,20 @@ void AMDGPUInstPrinter::printWaitVDST(const MCInst *MI, unsigned OpNo,
639639
printU4ImmDecOperand(MI, OpNo, O);
640640
}
641641

642+
void AMDGPUInstPrinter::printWaitVAVDst(const MCInst *MI, unsigned OpNo,
643+
const MCSubtargetInfo &STI,
644+
raw_ostream &O) {
645+
O << " wait_va_vdst:";
646+
printU4ImmDecOperand(MI, OpNo, O);
647+
}
648+
649+
void AMDGPUInstPrinter::printWaitVMVSrc(const MCInst *MI, unsigned OpNo,
650+
const MCSubtargetInfo &STI,
651+
raw_ostream &O) {
652+
O << " wait_vm_vsrc:";
653+
printU4ImmDecOperand(MI, OpNo, O);
654+
}
655+
642656
void AMDGPUInstPrinter::printWaitEXP(const MCInst *MI, unsigned OpNo,
643657
const MCSubtargetInfo &STI,
644658
raw_ostream &O) {

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ class AMDGPUInstPrinter : public MCInstPrinter {
161161
raw_ostream &O);
162162
void printWaitEXP(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
163163
raw_ostream &O);
164+
void printWaitVAVDst(const MCInst *MI, unsigned OpNo,
165+
const MCSubtargetInfo &STI, raw_ostream &O);
166+
void printWaitVMVSrc(const MCInst *MI, unsigned OpNo,
167+
const MCSubtargetInfo &STI, raw_ostream &O);
164168

165169
void printExpSrcN(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
166170
raw_ostream &O, unsigned N);

0 commit comments

Comments
 (0)