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