//===--------------------AMDKernelCodeTUtils.cpp --------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // //===----------------------------------------------------------------------===// // /// \file - utility functions to parse/print amd_kernel_code_t structure // //===----------------------------------------------------------------------===// #include "AMDKernelCodeTUtils.h" #include "SIDefines.h" #include #include #include using namespace llvm; static ArrayRef get_amd_kernel_code_t_FldNames() { static StringRef const Table[] = { "", // not found placeholder #define RECORD(name, print, parse) #name #include "AMDKernelCodeTInfo.h" #undef RECORD }; return makeArrayRef(Table); } static StringMap createIndexMap(const ArrayRef &a) { StringMap map; for (auto Name : a) map.insert(std::make_pair(Name, map.size())); return map; } static int get_amd_kernel_code_t_FieldIndex(StringRef name) { static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames()); return map.lookup(name) - 1; // returns -1 if not found } static StringRef get_amd_kernel_code_t_FieldName(int index) { return get_amd_kernel_code_t_FldNames()[index + 1]; } // Field printing static raw_ostream &printName(raw_ostream &OS, StringRef Name) { return OS << Name << " = "; } template static void printField(StringRef Name, const amd_kernel_code_t &C, raw_ostream &OS) { printName(OS, Name) << (int)(C.*ptr); } template static void printBitField(StringRef Name, const amd_kernel_code_t &c, raw_ostream &OS) { const auto Mask = (static_cast(1) << width) - 1; printName(OS, Name) << (int)((c.*ptr >> shift) & Mask); } typedef void(*PrintFx)(StringRef, const amd_kernel_code_t &, raw_ostream &); static ArrayRef getPrinterTable() { static const PrintFx Table[] = { #define RECORD(name, print, parse) print #include "AMDKernelCodeTInfo.h" #undef RECORD }; return makeArrayRef(Table); } void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C, int FldIndex, raw_ostream &OS) { auto Printer = getPrinterTable()[FldIndex]; if (Printer) Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS); } void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C, raw_ostream &OS, const char *tab) { const int Size = getPrinterTable().size(); for (int i = 0; i < Size; ++i) { OS << tab; printAmdKernelCodeField(*C, i, OS); OS << '\n'; } } // Field parsing static bool expectAbsExpression(MCAsmParser &MCParser, int64_t &Value, raw_ostream& Err) { if (MCParser.getLexer().isNot(AsmToken::Equal)) { Err << "expected '='"; return false; } MCParser.getLexer().Lex(); if (MCParser.parseAbsoluteExpression(Value)) { Err << "integer absolute expression expected"; return false; } return true; } template static bool parseField(amd_kernel_code_t &C, MCAsmParser &MCParser, raw_ostream &Err) { int64_t Value = 0; if (!expectAbsExpression(MCParser, Value, Err)) return false; C.*ptr = (T)Value; return true; } template static bool parseBitField(amd_kernel_code_t &C, MCAsmParser &MCParser, raw_ostream &Err) { int64_t Value = 0; if (!expectAbsExpression(MCParser, Value, Err)) return false; const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift; C.*ptr &= (T)~Mask; C.*ptr |= (T)((Value << shift) & Mask); return true; } typedef bool(*ParseFx)(amd_kernel_code_t &, MCAsmParser &MCParser, raw_ostream &Err); static ArrayRef getParserTable() { static const ParseFx Table[] = { #define RECORD(name, print, parse) parse #include "AMDKernelCodeTInfo.h" #undef RECORD }; return makeArrayRef(Table); } bool llvm::parseAmdKernelCodeField(StringRef ID, MCAsmParser &MCParser, amd_kernel_code_t &C, raw_ostream &Err) { const int Idx = get_amd_kernel_code_t_FieldIndex(ID); if (Idx < 0) { Err << "unexpected amd_kernel_code_t field name " << ID; return false; } auto Parser = getParserTable()[Idx]; return Parser ? Parser(C, MCParser, Err) : false; }