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