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