xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--------------------AMDKernelCodeTUtils.cpp --------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker /// \file - utility functions to parse/print amd_kernel_code_t structure
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "AMDKernelCodeTUtils.h"
17*9880d681SAndroid Build Coastguard Worker #include "SIDefines.h"
18*9880d681SAndroid Build Coastguard Worker #include <llvm/MC/MCParser/MCAsmLexer.h>
19*9880d681SAndroid Build Coastguard Worker #include <llvm/MC/MCParser/MCAsmParser.h>
20*9880d681SAndroid Build Coastguard Worker #include <llvm/Support/raw_ostream.h>
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker 
get_amd_kernel_code_t_FldNames()24*9880d681SAndroid Build Coastguard Worker static ArrayRef<StringRef> get_amd_kernel_code_t_FldNames() {
25*9880d681SAndroid Build Coastguard Worker   static StringRef const Table[] = {
26*9880d681SAndroid Build Coastguard Worker     "", // not found placeholder
27*9880d681SAndroid Build Coastguard Worker #define RECORD(name, print, parse) #name
28*9880d681SAndroid Build Coastguard Worker #include "AMDKernelCodeTInfo.h"
29*9880d681SAndroid Build Coastguard Worker #undef RECORD
30*9880d681SAndroid Build Coastguard Worker   };
31*9880d681SAndroid Build Coastguard Worker   return makeArrayRef(Table);
32*9880d681SAndroid Build Coastguard Worker }
33*9880d681SAndroid Build Coastguard Worker 
createIndexMap(const ArrayRef<StringRef> & a)34*9880d681SAndroid Build Coastguard Worker static StringMap<int> createIndexMap(const ArrayRef<StringRef> &a) {
35*9880d681SAndroid Build Coastguard Worker   StringMap<int> map;
36*9880d681SAndroid Build Coastguard Worker   for (auto Name : a)
37*9880d681SAndroid Build Coastguard Worker     map.insert(std::make_pair(Name, map.size()));
38*9880d681SAndroid Build Coastguard Worker   return map;
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker 
get_amd_kernel_code_t_FieldIndex(StringRef name)41*9880d681SAndroid Build Coastguard Worker static int get_amd_kernel_code_t_FieldIndex(StringRef name) {
42*9880d681SAndroid Build Coastguard Worker   static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames());
43*9880d681SAndroid Build Coastguard Worker   return map.lookup(name) - 1; // returns -1 if not found
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker 
get_amd_kernel_code_t_FieldName(int index)46*9880d681SAndroid Build Coastguard Worker static StringRef get_amd_kernel_code_t_FieldName(int index) {
47*9880d681SAndroid Build Coastguard Worker   return get_amd_kernel_code_t_FldNames()[index + 1];
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker // Field printing
52*9880d681SAndroid Build Coastguard Worker 
printName(raw_ostream & OS,StringRef Name)53*9880d681SAndroid Build Coastguard Worker static raw_ostream &printName(raw_ostream &OS, StringRef Name) {
54*9880d681SAndroid Build Coastguard Worker   return OS << Name << " = ";
55*9880d681SAndroid Build Coastguard Worker }
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker template <typename T, T amd_kernel_code_t::*ptr>
printField(StringRef Name,const amd_kernel_code_t & C,raw_ostream & OS)58*9880d681SAndroid Build Coastguard Worker static void printField(StringRef Name, const amd_kernel_code_t &C,
59*9880d681SAndroid Build Coastguard Worker                        raw_ostream &OS) {
60*9880d681SAndroid Build Coastguard Worker   printName(OS, Name) << (int)(C.*ptr);
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
printBitField(StringRef Name,const amd_kernel_code_t & c,raw_ostream & OS)64*9880d681SAndroid Build Coastguard Worker static void printBitField(StringRef Name, const amd_kernel_code_t &c,
65*9880d681SAndroid Build Coastguard Worker                           raw_ostream &OS) {
66*9880d681SAndroid Build Coastguard Worker   const auto Mask = (static_cast<T>(1) << width) - 1;
67*9880d681SAndroid Build Coastguard Worker   printName(OS, Name) << (int)((c.*ptr >> shift) & Mask);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker typedef void(*PrintFx)(StringRef,
71*9880d681SAndroid Build Coastguard Worker                        const amd_kernel_code_t &,
72*9880d681SAndroid Build Coastguard Worker                        raw_ostream &);
73*9880d681SAndroid Build Coastguard Worker 
getPrinterTable()74*9880d681SAndroid Build Coastguard Worker static ArrayRef<PrintFx> getPrinterTable() {
75*9880d681SAndroid Build Coastguard Worker   static const PrintFx Table[] = {
76*9880d681SAndroid Build Coastguard Worker #define RECORD(name, print, parse) print
77*9880d681SAndroid Build Coastguard Worker #include "AMDKernelCodeTInfo.h"
78*9880d681SAndroid Build Coastguard Worker #undef RECORD
79*9880d681SAndroid Build Coastguard Worker   };
80*9880d681SAndroid Build Coastguard Worker   return makeArrayRef(Table);
81*9880d681SAndroid Build Coastguard Worker }
82*9880d681SAndroid Build Coastguard Worker 
printAmdKernelCodeField(const amd_kernel_code_t & C,int FldIndex,raw_ostream & OS)83*9880d681SAndroid Build Coastguard Worker void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C,
84*9880d681SAndroid Build Coastguard Worker                                    int FldIndex,
85*9880d681SAndroid Build Coastguard Worker                                    raw_ostream &OS) {
86*9880d681SAndroid Build Coastguard Worker   auto Printer = getPrinterTable()[FldIndex];
87*9880d681SAndroid Build Coastguard Worker   if (Printer)
88*9880d681SAndroid Build Coastguard Worker     Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS);
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker 
dumpAmdKernelCode(const amd_kernel_code_t * C,raw_ostream & OS,const char * tab)91*9880d681SAndroid Build Coastguard Worker void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C,
92*9880d681SAndroid Build Coastguard Worker                              raw_ostream &OS,
93*9880d681SAndroid Build Coastguard Worker                              const char *tab) {
94*9880d681SAndroid Build Coastguard Worker   const int Size = getPrinterTable().size();
95*9880d681SAndroid Build Coastguard Worker   for (int i = 0; i < Size; ++i) {
96*9880d681SAndroid Build Coastguard Worker     OS << tab;
97*9880d681SAndroid Build Coastguard Worker     printAmdKernelCodeField(*C, i, OS);
98*9880d681SAndroid Build Coastguard Worker     OS << '\n';
99*9880d681SAndroid Build Coastguard Worker   }
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker // Field parsing
104*9880d681SAndroid Build Coastguard Worker 
expectAbsExpression(MCAsmParser & MCParser,int64_t & Value,raw_ostream & Err)105*9880d681SAndroid Build Coastguard Worker static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream& Err) {
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker   if (MCParser.getLexer().isNot(AsmToken::Equal)) {
108*9880d681SAndroid Build Coastguard Worker     Err << "expected '='";
109*9880d681SAndroid Build Coastguard Worker     return false;
110*9880d681SAndroid Build Coastguard Worker   }
111*9880d681SAndroid Build Coastguard Worker   MCParser.getLexer().Lex();
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker   if (MCParser.parseAbsoluteExpression(Value)) {
114*9880d681SAndroid Build Coastguard Worker     Err << "integer absolute expression expected";
115*9880d681SAndroid Build Coastguard Worker     return false;
116*9880d681SAndroid Build Coastguard Worker   }
117*9880d681SAndroid Build Coastguard Worker   return true;
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker template <typename T, T amd_kernel_code_t::*ptr>
parseField(amd_kernel_code_t & C,MCAsmParser & MCParser,raw_ostream & Err)121*9880d681SAndroid Build Coastguard Worker static bool parseField(amd_kernel_code_t &C, MCAsmParser &MCParser,
122*9880d681SAndroid Build Coastguard Worker                        raw_ostream &Err) {
123*9880d681SAndroid Build Coastguard Worker   int64_t Value = 0;
124*9880d681SAndroid Build Coastguard Worker   if (!expectAbsExpression(MCParser, Value, Err))
125*9880d681SAndroid Build Coastguard Worker     return false;
126*9880d681SAndroid Build Coastguard Worker   C.*ptr = (T)Value;
127*9880d681SAndroid Build Coastguard Worker   return true;
128*9880d681SAndroid Build Coastguard Worker }
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1>
parseBitField(amd_kernel_code_t & C,MCAsmParser & MCParser,raw_ostream & Err)131*9880d681SAndroid Build Coastguard Worker static bool parseBitField(amd_kernel_code_t &C, MCAsmParser &MCParser,
132*9880d681SAndroid Build Coastguard Worker                           raw_ostream &Err) {
133*9880d681SAndroid Build Coastguard Worker   int64_t Value = 0;
134*9880d681SAndroid Build Coastguard Worker   if (!expectAbsExpression(MCParser, Value, Err))
135*9880d681SAndroid Build Coastguard Worker     return false;
136*9880d681SAndroid Build Coastguard Worker   const uint64_t Mask = ((UINT64_C(1)  << width) - 1) << shift;
137*9880d681SAndroid Build Coastguard Worker   C.*ptr &= (T)~Mask;
138*9880d681SAndroid Build Coastguard Worker   C.*ptr |= (T)((Value << shift) & Mask);
139*9880d681SAndroid Build Coastguard Worker   return true;
140*9880d681SAndroid Build Coastguard Worker }
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker typedef bool(*ParseFx)(amd_kernel_code_t &,
143*9880d681SAndroid Build Coastguard Worker                        MCAsmParser &MCParser,
144*9880d681SAndroid Build Coastguard Worker                        raw_ostream &Err);
145*9880d681SAndroid Build Coastguard Worker 
getParserTable()146*9880d681SAndroid Build Coastguard Worker static ArrayRef<ParseFx> getParserTable() {
147*9880d681SAndroid Build Coastguard Worker   static const ParseFx Table[] = {
148*9880d681SAndroid Build Coastguard Worker #define RECORD(name, print, parse) parse
149*9880d681SAndroid Build Coastguard Worker #include "AMDKernelCodeTInfo.h"
150*9880d681SAndroid Build Coastguard Worker #undef RECORD
151*9880d681SAndroid Build Coastguard Worker   };
152*9880d681SAndroid Build Coastguard Worker   return makeArrayRef(Table);
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
parseAmdKernelCodeField(StringRef ID,MCAsmParser & MCParser,amd_kernel_code_t & C,raw_ostream & Err)155*9880d681SAndroid Build Coastguard Worker bool llvm::parseAmdKernelCodeField(StringRef ID,
156*9880d681SAndroid Build Coastguard Worker                                    MCAsmParser &MCParser,
157*9880d681SAndroid Build Coastguard Worker                                    amd_kernel_code_t &C,
158*9880d681SAndroid Build Coastguard Worker                                    raw_ostream &Err) {
159*9880d681SAndroid Build Coastguard Worker   const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
160*9880d681SAndroid Build Coastguard Worker   if (Idx < 0) {
161*9880d681SAndroid Build Coastguard Worker     Err << "unexpected amd_kernel_code_t field name " << ID;
162*9880d681SAndroid Build Coastguard Worker     return false;
163*9880d681SAndroid Build Coastguard Worker   }
164*9880d681SAndroid Build Coastguard Worker   auto Parser = getParserTable()[Idx];
165*9880d681SAndroid Build Coastguard Worker   return Parser ? Parser(C, MCParser, Err) : false;
166*9880d681SAndroid Build Coastguard Worker }
167