1 //===- AMDKernelCodeTUtils.cpp --------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// \file - utility functions to parse/print amd_kernel_code_t structure
11 //===----------------------------------------------------------------------===//
13 #include "AMDKernelCodeTUtils.h"
14 #include "SIDefines.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCAsmParser.h"
20 #include "llvm/Support/raw_ostream.h"
27 static ArrayRef
<StringRef
> get_amd_kernel_code_t_FldNames() {
28 static StringRef
const Table
[] = {
29 "", // not found placeholder
30 #define RECORD(name, altName, print, parse) #name
31 #include "AMDKernelCodeTInfo.h"
34 return makeArrayRef(Table
);
37 static ArrayRef
<StringRef
> get_amd_kernel_code_t_FldAltNames() {
38 static StringRef
const Table
[] = {
39 "", // not found placeholder
40 #define RECORD(name, altName, print, parse) #altName
41 #include "AMDKernelCodeTInfo.h"
44 return makeArrayRef(Table
);
47 static StringMap
<int> createIndexMap(const ArrayRef
<StringRef
> &names
,
48 const ArrayRef
<StringRef
> &altNames
) {
50 assert(names
.size() == altNames
.size());
51 for (unsigned i
= 0; i
< names
.size(); ++i
) {
52 map
.insert(std::make_pair(names
[i
], i
));
53 map
.insert(std::make_pair(altNames
[i
], i
));
58 static int get_amd_kernel_code_t_FieldIndex(StringRef name
) {
59 static const auto map
= createIndexMap(get_amd_kernel_code_t_FldNames(),
60 get_amd_kernel_code_t_FldAltNames());
61 return map
.lookup(name
) - 1; // returns -1 if not found
64 static StringRef
get_amd_kernel_code_t_FieldName(int index
) {
65 return get_amd_kernel_code_t_FldNames()[index
+ 1];
70 static raw_ostream
&printName(raw_ostream
&OS
, StringRef Name
) {
71 return OS
<< Name
<< " = ";
74 template <typename T
, T
amd_kernel_code_t::*ptr
>
75 static void printField(StringRef Name
, const amd_kernel_code_t
&C
,
77 printName(OS
, Name
) << (int)(C
.*ptr
);
80 template <typename T
, T
amd_kernel_code_t::*ptr
, int shift
, int width
= 1>
81 static void printBitField(StringRef Name
, const amd_kernel_code_t
&c
,
83 const auto Mask
= (static_cast<T
>(1) << width
) - 1;
84 printName(OS
, Name
) << (int)((c
.*ptr
>> shift
) & Mask
);
87 using PrintFx
= void(*)(StringRef
, const amd_kernel_code_t
&, raw_ostream
&);
89 static ArrayRef
<PrintFx
> getPrinterTable() {
90 static const PrintFx Table
[] = {
91 #define RECORD(name, altName, print, parse) print
92 #include "AMDKernelCodeTInfo.h"
95 return makeArrayRef(Table
);
98 void llvm::printAmdKernelCodeField(const amd_kernel_code_t
&C
,
101 auto Printer
= getPrinterTable()[FldIndex
];
103 Printer(get_amd_kernel_code_t_FieldName(FldIndex
), C
, OS
);
106 void llvm::dumpAmdKernelCode(const amd_kernel_code_t
*C
,
109 const int Size
= getPrinterTable().size();
110 for (int i
= 0; i
< Size
; ++i
) {
112 printAmdKernelCodeField(*C
, i
, OS
);
119 static bool expectAbsExpression(MCAsmParser
&MCParser
, int64_t &Value
, raw_ostream
& Err
) {
121 if (MCParser
.getLexer().isNot(AsmToken::Equal
)) {
122 Err
<< "expected '='";
125 MCParser
.getLexer().Lex();
127 if (MCParser
.parseAbsoluteExpression(Value
)) {
128 Err
<< "integer absolute expression expected";
134 template <typename T
, T
amd_kernel_code_t::*ptr
>
135 static bool parseField(amd_kernel_code_t
&C
, MCAsmParser
&MCParser
,
138 if (!expectAbsExpression(MCParser
, Value
, Err
))
144 template <typename T
, T
amd_kernel_code_t::*ptr
, int shift
, int width
= 1>
145 static bool parseBitField(amd_kernel_code_t
&C
, MCAsmParser
&MCParser
,
148 if (!expectAbsExpression(MCParser
, Value
, Err
))
150 const uint64_t Mask
= ((UINT64_C(1) << width
) - 1) << shift
;
152 C
.*ptr
|= (T
)((Value
<< shift
) & Mask
);
156 using ParseFx
= bool(*)(amd_kernel_code_t
&, MCAsmParser
&MCParser
,
159 static ArrayRef
<ParseFx
> getParserTable() {
160 static const ParseFx Table
[] = {
161 #define RECORD(name, altName, print, parse) parse
162 #include "AMDKernelCodeTInfo.h"
165 return makeArrayRef(Table
);
168 bool llvm::parseAmdKernelCodeField(StringRef ID
,
169 MCAsmParser
&MCParser
,
170 amd_kernel_code_t
&C
,
172 const int Idx
= get_amd_kernel_code_t_FieldIndex(ID
);
174 Err
<< "unexpected amd_kernel_code_t field name " << ID
;
177 auto Parser
= getParserTable()[Idx
];
178 return Parser
? Parser(C
, MCParser
, Err
) : false;