diff options
author | Valery Pykhtin <Valery.Pykhtin@amd.com> | 2016-03-06 13:27:13 +0000 |
---|---|---|
committer | Valery Pykhtin <Valery.Pykhtin@amd.com> | 2016-03-06 13:27:13 +0000 |
commit | 499a5c632366b12968b9b19400117a8fcb91a38c (patch) | |
tree | f1d25efa842355b9ded79104dab1d735211f1078 /llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp | |
parent | 4d94d4d5f7c82a543cebe0b7413aa9b0b90ae6ec (diff) | |
download | llvm-499a5c632366b12968b9b19400117a8fcb91a38c.zip llvm-499a5c632366b12968b9b19400117a8fcb91a38c.tar.gz llvm-499a5c632366b12968b9b19400117a8fcb91a38c.tar.bz2 |
[AMDGPU] table-driven parser/printer for amd_kernel_code_t structure fields
Differential Revision: http://reviews.llvm.org/D17150
llvm-svn: 262804
Diffstat (limited to 'llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp new file mode 100644 index 0000000..6a416b9 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/Utils/AMDKernelCodeTUtils.cpp @@ -0,0 +1,165 @@ +//===--------------------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 <llvm/MC/MCParser/MCAsmLexer.h> +#include <llvm/Support/raw_ostream.h> + +using namespace llvm; + +static ArrayRef<StringRef> 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<int> createIndexMap(const ArrayRef<StringRef>& a) { + StringMap<int> map; + for (auto Name : a) + map.insert(std::make_pair(Name, map.size())); + return std::move(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 + +raw_ostream& printName(raw_ostream& OS, StringRef Name) { + return OS << Name << " = "; +} + +template <typename T, T amd_kernel_code_t::*ptr> +void printField(StringRef Name, + const amd_kernel_code_t& C, + raw_ostream& OS) { + printName(OS, Name) << (int)(C.*ptr); +} + +template <typename T, T amd_kernel_code_t::*ptr, int shift, int width=1> +void printBitField(StringRef Name, + const amd_kernel_code_t& c, + raw_ostream& OS) { + const auto Mask = (static_cast<T>(1) << width) - 1; + printName(OS, Name) << (int)((c.*ptr >> shift) & Mask); +} + +typedef void(*PrintFx)(StringRef, + const amd_kernel_code_t&, + raw_ostream&); + +static ArrayRef<PrintFx> 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 expectEqualInt(MCAsmLexer& Lexer, raw_ostream& Err) { + if (Lexer.isNot(AsmToken::Equal)) { + Err << "expected '='"; + return false; + } + Lexer.Lex(); + if (Lexer.isNot(AsmToken::Integer)) { + Err << "integer literal expected"; + return false; + } + return true; +} + +template <typename T, T amd_kernel_code_t::*ptr> +bool parseField(amd_kernel_code_t& C, + MCAsmLexer& Lexer, + raw_ostream& Err) { + if (!expectEqualInt(Lexer, Err)) + return false; + C.*ptr = (T)Lexer.getTok().getIntVal(); + return true; +} + +template <typename T, T amd_kernel_code_t::*ptr, int shift, int width = 1> +bool parseBitField(amd_kernel_code_t& C, + MCAsmLexer& Lexer, + raw_ostream& Err) { + if (!expectEqualInt(Lexer, Err)) + return false; + const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift; + C.*ptr &= (T)~Mask; + C.*ptr |= (T)((Lexer.getTok().getIntVal() << shift) & Mask); + return true; +} + +typedef bool(*ParseFx)(amd_kernel_code_t&, + MCAsmLexer& Lexer, + raw_ostream& Err); + +static ArrayRef<ParseFx> getParserTable() { + static const ParseFx Table[] = { +#define RECORD(name, print, parse) parse +#include "AMDKernelCodeTInfo.h" +#undef RECORD + }; + return makeArrayRef(Table); +} + +bool llvm::parseAmdKernelCodeField(StringRef ID, + MCAsmLexer& Lexer, + 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, Lexer, Err) : false; +} |