1313
1414#include " AMDGPUMIRFormatter.h"
1515#include " SIMachineFunctionInfo.h"
16+ #include " llvm/TargetParser/TargetParser.h"
1617
1718using namespace llvm ;
1819
20+ const char SWaitAluImmPrefix = ' .' ;
21+ StringLiteral SWaitAluDelim = " _" ;
22+
23+ StringLiteral VaVdstName = " VaVdst" ;
24+ StringLiteral VaSdstName = " VaSdst" ;
25+ StringLiteral VaSsrcName = " VaSsrc" ;
26+ StringLiteral HoldCntName = " HoldCnt" ;
27+ StringLiteral VmVsrcName = " VmVsrc" ;
28+ StringLiteral VaVccName = " VaVcc" ;
29+ StringLiteral SaSdstName = " SaSdst" ;
30+
31+ StringLiteral AllOff = " AllOff" ;
32+
33+ void AMDGPUMIRFormatter::printSWaitAluImm (uint64_t Imm, raw_ostream &OS) const {
34+ bool NonePrinted = true ;
35+ ListSeparator Delim (SWaitAluDelim);
36+ auto PrintFieldIfNotMax = [&](StringRef Descr, uint64_t Num, unsigned Max) {
37+ if (Num != Max) {
38+ OS << Delim << Descr << SWaitAluDelim << Num;
39+ NonePrinted = false ;
40+ }
41+ };
42+ OS << SWaitAluImmPrefix;
43+ PrintFieldIfNotMax (VaVdstName, AMDGPU::DepCtr::decodeFieldVaVdst (Imm),
44+ AMDGPU::DepCtr::getVaVdstBitMask ());
45+ PrintFieldIfNotMax (VaSdstName, AMDGPU::DepCtr::decodeFieldVaSdst (Imm),
46+ AMDGPU::DepCtr::getVaSdstBitMask ());
47+ PrintFieldIfNotMax (VaSsrcName, AMDGPU::DepCtr::decodeFieldVaSsrc (Imm),
48+ AMDGPU::DepCtr::getVaSsrcBitMask ());
49+ PrintFieldIfNotMax (
50+ HoldCntName,
51+ AMDGPU::DepCtr::decodeFieldHoldCnt (Imm,
52+ AMDGPU::getIsaVersion (STI.getCPU ())),
53+ AMDGPU::DepCtr::getHoldCntBitMask (AMDGPU::getIsaVersion (STI.getCPU ())));
54+ PrintFieldIfNotMax (VmVsrcName, AMDGPU::DepCtr::decodeFieldVmVsrc (Imm),
55+ AMDGPU::DepCtr::getVmVsrcBitMask ());
56+ PrintFieldIfNotMax (VaVccName, AMDGPU::DepCtr::decodeFieldVaVcc (Imm),
57+ AMDGPU::DepCtr::getVaVccBitMask ());
58+ PrintFieldIfNotMax (SaSdstName, AMDGPU::DepCtr::decodeFieldSaSdst (Imm),
59+ AMDGPU::DepCtr::getSaSdstBitMask ());
60+ if (NonePrinted)
61+ OS << AllOff;
62+ }
63+
1964void AMDGPUMIRFormatter::printImm (raw_ostream &OS, const MachineInstr &MI,
2065 std::optional<unsigned int > OpIdx, int64_t Imm) const {
2166
2267 switch (MI.getOpcode ()) {
68+ case AMDGPU::S_WAITCNT_DEPCTR:
69+ printSWaitAluImm (Imm, OS);
70+ break ;
2371 case AMDGPU::S_DELAY_ALU:
2472 assert (OpIdx == 0 );
2573 printSDelayAluImm (Imm, OS);
@@ -39,6 +87,8 @@ bool AMDGPUMIRFormatter::parseImmMnemonic(const unsigned OpCode,
3987{
4088
4189 switch (OpCode) {
90+ case AMDGPU::S_WAITCNT_DEPCTR:
91+ return parseSWaitAluImmMnemonic (OpIdx, Imm, Src, ErrorCallback);
4292 case AMDGPU::S_DELAY_ALU:
4393 return parseSDelayAluImmMnemonic (OpIdx, Imm, Src, ErrorCallback);
4494 default :
@@ -90,6 +140,89 @@ void AMDGPUMIRFormatter::printSDelayAluImm(int64_t Imm,
90140 Outdep (Id1);
91141}
92142
143+ bool AMDGPUMIRFormatter::parseSWaitAluImmMnemonic (
144+ const unsigned int OpIdx, int64_t &Imm, StringRef &Src,
145+ MIRFormatter::ErrorCallbackType &ErrorCallback) const {
146+ // TODO: For now accept integer masks for compatibility with old MIR.
147+ if (!Src.consumeInteger (10 , Imm))
148+ return false ;
149+
150+ // Initialize with all checks off.
151+ Imm = AMDGPU::DepCtr::getDefaultDepCtrEncoding (STI);
152+ // The input is in the form: .Name1_Num1_Name2_Num2
153+ // Drop the '.' prefix.
154+ bool ConsumePrefix = Src.consume_front (SWaitAluImmPrefix);
155+ if (!ConsumePrefix)
156+ return ErrorCallback (Src.begin (), " expected prefix" );
157+ if (Src.empty ())
158+ return ErrorCallback (Src.begin (), " expected <CounterName>_<CounterNum>" );
159+
160+ // Special case for all off.
161+ if (Src == AllOff)
162+ return false ;
163+
164+ // Parse a counter name, number pair in each iteration.
165+ while (!Src.empty ()) {
166+ // Src: Name1_Num1_Name2_Num2
167+ // ^
168+ size_t DelimIdx = Src.find (SWaitAluDelim);
169+ if (DelimIdx == StringRef::npos)
170+ return ErrorCallback (Src.begin (), " expected <CounterName>_<CounterNum>" );
171+ // Src: Name1_Num1_Name2_Num2
172+ // ^^^^^
173+ StringRef Name = Src.substr (0 , DelimIdx);
174+ // Save the position of the name for accurate error reporting.
175+ StringRef::iterator NamePos = Src.begin ();
176+ [[maybe_unused]] bool ConsumeName = Src.consume_front (Name);
177+ assert (ConsumeName && " Expected name" );
178+ [[maybe_unused]] bool ConsumeDelim = Src.consume_front (SWaitAluDelim);
179+ assert (ConsumeDelim && " Expected delimiter" );
180+ // Src: Num1_Name2_Num2
181+ // ^
182+ DelimIdx = Src.find (SWaitAluDelim);
183+ // Src: Num1_Name2_Num2
184+ // ^^^^
185+ int64_t Num;
186+ // Save the position of the number for accurate error reporting.
187+ StringRef::iterator NumPos = Src.begin ();
188+ if (Src.consumeInteger (10 , Num) || Num < 0 )
189+ return ErrorCallback (NumPos,
190+ " expected non-negative integer counter number" );
191+ unsigned Max;
192+ if (Name == VaVdstName) {
193+ Max = AMDGPU::DepCtr::getVaVdstBitMask ();
194+ Imm = AMDGPU::DepCtr::encodeFieldVaVdst (Imm, Num);
195+ } else if (Name == VmVsrcName) {
196+ Max = AMDGPU::DepCtr::getVmVsrcBitMask ();
197+ Imm = AMDGPU::DepCtr::encodeFieldVmVsrc (Imm, Num);
198+ } else if (Name == VaSdstName) {
199+ Max = AMDGPU::DepCtr::getVaSdstBitMask ();
200+ Imm = AMDGPU::DepCtr::encodeFieldVaSdst (Imm, Num);
201+ } else if (Name == VaSsrcName) {
202+ Max = AMDGPU::DepCtr::getVaSsrcBitMask ();
203+ Imm = AMDGPU::DepCtr::encodeFieldVaSsrc (Imm, Num);
204+ } else if (Name == HoldCntName) {
205+ const AMDGPU::IsaVersion &Version = AMDGPU::getIsaVersion (STI.getCPU ());
206+ Max = AMDGPU::DepCtr::getHoldCntBitMask (Version);
207+ Imm = AMDGPU::DepCtr::encodeFieldHoldCnt (Imm, Num, Version);
208+ } else if (Name == VaVccName) {
209+ Max = AMDGPU::DepCtr::getVaVccBitMask ();
210+ Imm = AMDGPU::DepCtr::encodeFieldVaVcc (Imm, Num);
211+ } else if (Name == SaSdstName) {
212+ Max = AMDGPU::DepCtr::getSaSdstBitMask ();
213+ Imm = AMDGPU::DepCtr::encodeFieldSaSdst (Imm, Num);
214+ } else {
215+ return ErrorCallback (NamePos, " invalid counter name" );
216+ }
217+ // Don't allow the values to reach their maximum value.
218+ if (Num >= Max)
219+ return ErrorCallback (NumPos, " counter value too large" );
220+ // Src: Name2_Num2
221+ Src.consume_front (SWaitAluDelim);
222+ }
223+ return false ;
224+ }
225+
93226bool AMDGPUMIRFormatter::parseSDelayAluImmMnemonic (
94227 const unsigned int OpIdx, int64_t &Imm, llvm::StringRef &Src,
95228 llvm::MIRFormatter::ErrorCallbackType &ErrorCallback) const
0 commit comments