llvm.org GIT mirror llvm / c7d8cf3
[AMDGPU] table-driven parser/printer for amd_kernel_code_t structure fields This is going to be used in .hsatext disassembler and can be used in current assembler parser (lit tests passed on parsing). Code using this helpers isn't included in this patch. Benefits: unified approach fast field name lookup on parsing Later I would like to enhance some of the field naming/syntax using this code. Patch by: Valery Pykhtin Differential Revision: http://reviews.llvm.org/D17150 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@262473 91177308-0d34-0410-b5e6-96231b3b80d8 Nikolay Haustov 4 years ago
4 changed file(s) with 370 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===--------------------- AMDKernelCodeTInfo.h -----------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 /// \file - specifies tables for amd_kernel_code_t structure parsing/printing
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define QNAME(name) amd_kernel_code_t::name
16 #define FLD_T(name) decltype(QNAME(name)), &QNAME(name)
17
18 #define FIELD2(sname, name) \
19 RECORD(sname, printField, parseField)
20
21 #define FIELD(name) FIELD2(name, name)
22
23
24 #define PRINTCODEPROP(name) \
25 printBitField
26 AMD_CODE_PROPERTY_##name##_SHIFT,\
27 AMD_CODE_PROPERTY_##name##_WIDTH>
28
29 #define PARSECODEPROP(name) \
30 parseBitField
31 AMD_CODE_PROPERTY_##name##_SHIFT,\
32 AMD_CODE_PROPERTY_##name##_WIDTH>
33
34 #define CODEPROP(name, shift) \
35 RECORD(name, PRINTCODEPROP(shift), PARSECODEPROP(shift))
36
37 // have to define these lambdas because of Set/GetMacro
38 #define PRINTCOMP(GetMacro, Shift) \
39 [](StringRef Name, const amd_kernel_code_t &C, raw_ostream &OS) { \
40 printName(OS, Name) << \
41 (int)GetMacro(C.compute_pgm_resource_registers >> Shift); \
42 }
43 #define PARSECOMP(SetMacro, Shift) \
44 [](amd_kernel_code_t &C, MCAsmLexer &Lexer, raw_ostream &Err) { \
45 if (!expectEqualInt(Lexer, Err)) \
46 return false; \
47 const uint64_t Value = Lexer.getTok().getIntVal(); \
48 C.compute_pgm_resource_registers |= SetMacro(Value) << Shift; \
49 return true; \
50 }
51
52 #define COMPPGM(name, GetMacro, SetMacro, Shift) \
53 RECORD(name, PRINTCOMP(GetMacro, Shift), PARSECOMP(SetMacro, Shift))
54
55 #define COMPPGM1(name, AccMacro) \
56 COMPPGM(compute_pgm_rsrc1_##name, \
57 G_00B848_##AccMacro, S_00B848_##AccMacro, 0)
58
59 #define COMPPGM2(name, AccMacro) \
60 COMPPGM(compute_pgm_rsrc2_##name, \
61 G_00B84C_##AccMacro, S_00B84C_##AccMacro, 32)
62
63 ///////////////////////////////////////////////////////////////////////////////
64 // Begin of the table
65 // Define RECORD(name, print, parse) in your code to get field definitions
66 // and include this file
67
68 FIELD2(kernel_code_version_major, amd_kernel_code_version_major),
69 FIELD2(kernel_code_version_minor, amd_kernel_code_version_minor),
70 FIELD2(machine_kind, amd_machine_kind),
71 FIELD2(machine_version_major, amd_machine_version_major),
72 FIELD2(machine_version_minor, amd_machine_version_minor),
73 FIELD2(machine_version_stepping, amd_machine_version_stepping),
74 FIELD(kernel_code_entry_byte_offset),
75 FIELD(kernel_code_prefetch_byte_size),
76 FIELD(max_scratch_backing_memory_byte_size),
77 FIELD(compute_pgm_resource_registers),
78 FIELD(workitem_private_segment_byte_size),
79 FIELD(workgroup_group_segment_byte_size),
80 FIELD(gds_segment_byte_size),
81 FIELD(kernarg_segment_byte_size),
82 FIELD(workgroup_fbarrier_count),
83 FIELD(wavefront_sgpr_count),
84 FIELD(workitem_vgpr_count),
85 FIELD(reserved_vgpr_first),
86 FIELD(reserved_vgpr_count),
87 FIELD(reserved_sgpr_first),
88 FIELD(reserved_sgpr_count),
89 FIELD(debug_wavefront_private_segment_offset_sgpr),
90 FIELD(debug_private_segment_buffer_sgpr),
91 FIELD(kernarg_segment_alignment),
92 FIELD(group_segment_alignment),
93 FIELD(private_segment_alignment),
94 FIELD(wavefront_size),
95 FIELD(call_convention),
96 FIELD(runtime_loader_kernel_symbol),
97
98 COMPPGM1(vgprs, VGPRS),
99 COMPPGM1(sgprs, SGPRS),
100 COMPPGM1(priority, PRIORITY),
101 COMPPGM1(float_mode, FLOAT_MODE),
102 COMPPGM1(priv, PRIV),
103 COMPPGM1(dx10_clamp, DX10_CLAMP),
104 COMPPGM1(debug_mode, DEBUG_MODE),
105 COMPPGM1(ieee_mode, IEEE_MODE),
106 COMPPGM2(scratch_en, SCRATCH_EN),
107 COMPPGM2(user_sgpr, USER_SGPR),
108 COMPPGM2(tgid_x_en, TGID_X_EN),
109 COMPPGM2(tgid_y_en, TGID_Y_EN),
110 COMPPGM2(tgid_z_en, TGID_Z_EN),
111 COMPPGM2(tg_size_en, TG_SIZE_EN),
112 COMPPGM2(tidig_comp_cnt, TIDIG_COMP_CNT),
113 COMPPGM2(excp_en_msb, EXCP_EN_MSB),
114 COMPPGM2(lds_size, LDS_SIZE),
115 COMPPGM2(excp_en, EXCP_EN),
116
117 CODEPROP(enable_sgpr_private_segment_buffer,
118 ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER),
119 CODEPROP(enable_sgpr_dispatch_ptr,
120 ENABLE_SGPR_DISPATCH_PTR),
121 CODEPROP(enable_sgpr_queue_ptr,
122 ENABLE_SGPR_QUEUE_PTR),
123 CODEPROP(enable_sgpr_kernarg_segment_ptr,
124 ENABLE_SGPR_KERNARG_SEGMENT_PTR),
125 CODEPROP(enable_sgpr_dispatch_id,
126 ENABLE_SGPR_DISPATCH_ID),
127 CODEPROP(enable_sgpr_flat_scratch_init,
128 ENABLE_SGPR_FLAT_SCRATCH_INIT),
129 CODEPROP(enable_sgpr_private_segment_size,
130 ENABLE_SGPR_PRIVATE_SEGMENT_SIZE),
131 CODEPROP(enable_sgpr_grid_workgroup_count_x,
132 ENABLE_SGPR_GRID_WORKGROUP_COUNT_X),
133 CODEPROP(enable_sgpr_grid_workgroup_count_y,
134 ENABLE_SGPR_GRID_WORKGROUP_COUNT_Y),
135 CODEPROP(enable_sgpr_grid_workgroup_count_z,
136 ENABLE_SGPR_GRID_WORKGROUP_COUNT_Z),
137 CODEPROP(enable_ordered_append_gds,
138 ENABLE_ORDERED_APPEND_GDS),
139 CODEPROP(private_element_size,
140 PRIVATE_ELEMENT_SIZE),
141 CODEPROP(is_ptr64,
142 IS_PTR64),
143 CODEPROP(is_dynamic_callstack,
144 IS_DYNAMIC_CALLSTACK),
145 CODEPROP(is_debug_enabled,
146 IS_DEBUG_SUPPORTED),
147 CODEPROP(is_xnack_enabled,
148 IS_XNACK_SUPPORTED)
149
150 // end of the table
151 ///////////////////////////////////////////////////////////////////////////////
152
153 #undef QNAME
154 #undef FLD_T
155 #undef FIELD2
156 #undef FIELD
157 #undef PRINTCODEPROP
158 #undef PARSECODEPROP
159 #undef CODEPROP
160 #undef PRINTCOMP
161 #undef PAPSECOMP
162 #undef COMPPGM
163 #undef COMPPGM1
164 #undef COMPPGM2
0 //===-------------------- AMDKernelCodeTUtils.cpp -------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 /// \file - utility functions to parse/print amd_kernel_code_t structure
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AMDKernelCodeT.h"
16 #include "AMDKernelCodeTUtils.h"
17 #include "SIDefines.h"
18 #include
19 #include
20
21 using namespace llvm;
22
23 static ArrayRef get_amd_kernel_code_t_FldNames() {
24 static StringRef const Table[] = {
25 "", // not found placeholder
26 #define RECORD(name, print, parse) #name
27 #include "AMDKernelCodeTInfo.h"
28 #undef RECORD
29 };
30 return Table;
31 }
32
33 static StringMap createIndexMap(const ArrayRef &a) {
34 StringMap map;
35 for (auto Name : a)
36 map.insert(std::make_pair(Name, map.size()));
37 return std::move(map);
38 }
39
40 static int get_amd_kernel_code_t_FieldIndex(StringRef name) {
41 static const auto map = createIndexMap(get_amd_kernel_code_t_FldNames());
42 return map.lookup(name) - 1; // returns -1 if not found
43 }
44
45 static StringRef get_amd_kernel_code_t_FieldName(int index) {
46 return get_amd_kernel_code_t_FldNames()[index + 1];
47 }
48
49
50 // Field printing
51
52 raw_ostream& printName(raw_ostream &OS, StringRef Name) {
53 return OS << Name << " = ";
54 }
55
56 template
57 void printField(StringRef Name,
58 const amd_kernel_code_t &C,
59 raw_ostream &OS) {
60 printName(OS, Name) << (int)(C.*ptr);
61 }
62
63 template
64 void printBitField(StringRef Name,
65 const amd_kernel_code_t &c,
66 raw_ostream &OS) {
67 const auto Mask = (static_cast(1) << width) - 1;
68 printName(OS, Name) << (int)((c.*ptr >> shift) & Mask);
69 }
70
71 typedef void(*PrintFx)(StringRef,
72 const amd_kernel_code_t&,
73 raw_ostream&);
74
75 static ArrayRef getPrinterTable() {
76 static const PrintFx table[] = {
77 #define RECORD(name, print, parse) print
78 #include "AMDKernelCodeTInfo.h"
79 #undef RECORD
80 };
81 return table;
82 }
83
84 void llvm::printAmdKernelCodeField(const amd_kernel_code_t &C,
85 int FldIndex,
86 raw_ostream &OS) {
87 auto Printer = getPrinterTable()[FldIndex];
88 if (Printer)
89 Printer(get_amd_kernel_code_t_FieldName(FldIndex), C, OS);
90 }
91
92 void llvm::dumpAmdKernelCode(const amd_kernel_code_t *C,
93 raw_ostream &OS,
94 const char *tab) {
95 const int Size = getPrinterTable().size();
96 for (int i = 0; i < Size; ++i) {
97 OS << tab;
98 printAmdKernelCodeField(*C, i, OS);
99 OS << '\n';
100 }
101 }
102
103
104 // Field parsing
105
106 static bool expectEqualInt(MCAsmLexer &Lexer, raw_ostream &Err) {
107 if (Lexer.isNot(AsmToken::Equal)) {
108 Err << "expected '='";
109 return false;
110 }
111 Lexer.Lex();
112 if (Lexer.isNot(AsmToken::Integer)) {
113 Err << "integer literal expected";
114 return false;
115 }
116 return true;
117 }
118
119 template
120 bool parseField(amd_kernel_code_t &C,
121 MCAsmLexer &Lexer,
122 raw_ostream &Err) {
123 if (!expectEqualInt(Lexer, Err))
124 return false;
125 C.*ptr = (T)Lexer.getTok().getIntVal();
126 return true;
127 }
128
129 template
130 bool parseBitField(amd_kernel_code_t &C,
131 MCAsmLexer &Lexer,
132 raw_ostream &Err) {
133 if (!expectEqualInt(Lexer, Err))
134 return false;
135 const uint64_t Mask = ((UINT64_C(1) << width) - 1) << shift;
136 C.*ptr &= (T)~Mask;
137 C.*ptr |= (T)((Lexer.getTok().getIntVal() << shift) & Mask);
138 return true;
139 }
140
141 typedef bool(*ParseFx)(amd_kernel_code_t&,
142 MCAsmLexer&,
143 raw_ostream&);
144
145 static ArrayRef getParserTable() {
146 static const ParseFx table[] = {
147 #define RECORD(name, print, parse) parse
148 #include "AMDKernelCodeTInfo.h"
149 #undef RECORD
150 };
151 return table;
152 }
153
154 bool llvm::parseAmdKernelCodeField(StringRef ID,
155 MCAsmLexer &Lexer,
156 amd_kernel_code_t &C,
157 raw_ostream &Err) {
158 const int Idx = get_amd_kernel_code_t_FieldIndex(ID);
159 if (Idx < 0) {
160 Err << "unexpected amd_kernel_code_t field name " << ID;
161 return false;
162 }
163 auto Parser = getParserTable()[Idx];
164 return Parser ? Parser(C, Lexer, Err) : false;
165 }
0 //===- AMDGPUKernelCodeTUtils.h - helpers for amd_kernel_code_t *- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file AMDKernelCodeTUtils.h
9 //===----------------------------------------------------------------------===//
10
11 #ifndef AMDKERNELCODETUTILS_H
12 #define AMDKERNELCODETUTILS_H
13
14 typedef struct amd_kernel_code_s amd_kernel_code_t;
15
16 namespace llvm {
17
18 class MCAsmLexer;
19 class raw_ostream;
20 class StringRef;
21
22 void printAmdKernelCodeField(const amd_kernel_code_t &C,
23 int FldIndex,
24 raw_ostream &OS);
25
26 void dumpAmdKernelCode(const amd_kernel_code_t *C,
27 raw_ostream &OS,
28 const char *tab);
29
30 bool parseAmdKernelCodeField(StringRef ID,
31 MCAsmLexer &Lexer,
32 amd_kernel_code_t &C,
33 raw_ostream &Err);
34
35 }
36
37 #endif // AMDKERNELCODETUTILS_H
0 add_llvm_library(LLVMAMDGPUUtils
11 AMDGPUBaseInfo.cpp
2 AMDKernelCodeTUtils.cpp
23 )