Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/r600/egd_tables.py
4570 views
1
from __future__ import print_function
2
3
CopyRight = '''
4
/*
5
* Copyright 2015 Advanced Micro Devices, Inc.
6
*
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* on the rights to use, copy, modify, merge, publish, distribute, sub
11
* license, and/or sell copies of the Software, and to permit persons to whom
12
* the Software is furnished to do so, subject to the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the next
15
* paragraph) shall be included in all copies or substantial portions of the
16
* Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
* USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*
26
*/
27
'''
28
29
import sys
30
import re
31
32
33
class StringTable:
34
"""
35
A class for collecting multiple strings in a single larger string that is
36
used by indexing (to avoid relocations in the resulting binary)
37
"""
38
def __init__(self):
39
self.table = []
40
self.length = 0
41
42
def add(self, string):
43
# We might get lucky with string being a suffix of a previously added string
44
for te in self.table:
45
if te[0].endswith(string):
46
idx = te[1] + len(te[0]) - len(string)
47
te[2].add(idx)
48
return idx
49
50
idx = self.length
51
self.table.append((string, idx, set((idx,))))
52
self.length += len(string) + 1
53
54
return idx
55
56
def emit(self, filp, name, static=True):
57
"""
58
Write
59
[static] const char name[] = "...";
60
to filp.
61
"""
62
fragments = [
63
'"%s\\0" /* %s */' % (
64
te[0].encode('unicode_escape').decode(),
65
', '.join(str(idx) for idx in te[2])
66
)
67
for te in self.table
68
]
69
filp.write('%sconst char %s[] =\n%s;\n' % (
70
'static ' if static else '',
71
name,
72
'\n'.join('\t' + fragment for fragment in fragments)
73
))
74
75
class IntTable:
76
"""
77
A class for collecting multiple arrays of integers in a single big array
78
that is used by indexing (to avoid relocations in the resulting binary)
79
"""
80
def __init__(self, typename):
81
self.typename = typename
82
self.table = []
83
self.idxs = set()
84
85
def add(self, array):
86
# We might get lucky and find the array somewhere in the existing data
87
try:
88
idx = 0
89
while True:
90
idx = self.table.index(array[0], idx, len(self.table) - len(array) + 1)
91
92
for i in range(1, len(array)):
93
if array[i] != self.table[idx + i]:
94
break
95
else:
96
self.idxs.add(idx)
97
return idx
98
99
idx += 1
100
except ValueError:
101
pass
102
103
idx = len(self.table)
104
self.table += array
105
self.idxs.add(idx)
106
return idx
107
108
def emit(self, filp, name, static=True):
109
"""
110
Write
111
[static] const typename name[] = { ... };
112
to filp.
113
"""
114
idxs = sorted(self.idxs) + [len(self.table)]
115
116
fragments = [
117
('\t/* %s */ %s' % (
118
idxs[i],
119
' '.join((str(elt) + ',') for elt in self.table[idxs[i]:idxs[i+1]])
120
))
121
for i in range(len(idxs) - 1)
122
]
123
124
filp.write('%sconst %s %s[] = {\n%s\n};\n' % (
125
'static ' if static else '',
126
self.typename, name,
127
'\n'.join(fragments)
128
))
129
130
class Field:
131
def __init__(self, reg, s_name):
132
self.s_name = s_name
133
self.name = strip_prefix(s_name)
134
self.values = []
135
self.varname_values = '%s__%s__values' % (reg.r_name.lower(), self.name.lower())
136
137
class Reg:
138
def __init__(self, r_name):
139
self.r_name = r_name
140
self.name = strip_prefix(r_name)
141
self.fields = []
142
self.own_fields = True
143
144
145
def strip_prefix(s):
146
'''Strip prefix in the form ._.*_, e.g. R_001234_'''
147
return s[s[2:].find('_')+3:]
148
149
def parse(filename, regs, packets):
150
stream = open(filename)
151
152
for line in stream:
153
if not line.startswith('#define '):
154
continue
155
156
line = line[8:].strip()
157
158
if line.startswith('R_'):
159
name = line.split()[0]
160
161
for it in regs:
162
if it.r_name == name:
163
reg = it
164
break
165
else:
166
reg = Reg(name)
167
regs.append(reg)
168
169
elif line.startswith('S_'):
170
name = line[:line.find('(')]
171
172
for it in reg.fields:
173
if it.s_name == name:
174
field = it
175
break
176
else:
177
field = Field(reg, name)
178
reg.fields.append(field)
179
180
elif line.startswith('V_'):
181
split = line.split()
182
name = split[0]
183
value = int(split[1], 0)
184
185
for (n,v) in field.values:
186
if n == name:
187
if v != value:
188
sys.exit('Value mismatch: name = ' + name)
189
190
field.values.append((name, value))
191
192
elif line.startswith('PKT3_') and line.find('0x') != -1 and line.find('(') == -1:
193
packets.append(line.split()[0])
194
195
# Copy fields to indexed registers which have their fields only defined
196
# at register index 0.
197
# For example, copy fields from CB_COLOR0_INFO to CB_COLORn_INFO, n > 0.
198
match_number = re.compile('[0-9]+')
199
reg_dict = dict()
200
201
# Create a dict of registers with fields and '0' in their name
202
for reg in regs:
203
if len(reg.fields) and reg.name.find('0') != -1:
204
reg_dict[reg.name] = reg
205
206
# Assign fields
207
for reg in regs:
208
if not len(reg.fields):
209
reg0 = reg_dict.get(match_number.sub('0', reg.name))
210
if reg0 != None:
211
reg.fields = reg0.fields
212
reg.fields_owner = reg0
213
reg.own_fields = False
214
215
216
def write_tables(regs, packets):
217
218
strings = StringTable()
219
strings_offsets = IntTable("int")
220
221
print('/* This file is autogenerated by egd_tables.py from evergreend.h. Do not edit directly. */')
222
print()
223
print(CopyRight.strip())
224
print('''
225
#ifndef EG_TABLES_H
226
#define EG_TABLES_H
227
228
struct eg_field {
229
unsigned name_offset;
230
unsigned mask;
231
unsigned num_values;
232
unsigned values_offset; /* offset into eg_strings_offsets */
233
};
234
235
struct eg_reg {
236
unsigned name_offset;
237
unsigned offset;
238
unsigned num_fields;
239
unsigned fields_offset;
240
};
241
242
struct eg_packet3 {
243
unsigned name_offset;
244
unsigned op;
245
};
246
''')
247
248
print('static const struct eg_packet3 packet3_table[] = {')
249
for pkt in packets:
250
print('\t{%s, %s},' % (strings.add(pkt[5:]), pkt))
251
print('};')
252
print()
253
254
print('static const struct eg_field egd_fields_table[] = {')
255
256
fields_idx = 0
257
for reg in regs:
258
if len(reg.fields) and reg.own_fields:
259
print('\t/* %s */' % (fields_idx))
260
261
reg.fields_idx = fields_idx
262
263
for field in reg.fields:
264
if len(field.values):
265
values_offsets = []
266
for value in field.values:
267
while value[1] >= len(values_offsets):
268
values_offsets.append(-1)
269
values_offsets[value[1]] = strings.add(strip_prefix(value[0]))
270
print('\t{%s, %s(~0u), %s, %s},' % (
271
strings.add(field.name), field.s_name,
272
len(values_offsets), strings_offsets.add(values_offsets)))
273
else:
274
print('\t{%s, %s(~0u)},' % (strings.add(field.name), field.s_name))
275
fields_idx += 1
276
277
print('};')
278
print()
279
280
print('static const struct eg_reg egd_reg_table[] = {')
281
for reg in regs:
282
if len(reg.fields):
283
print('\t{%s, %s, %s, %s},' % (strings.add(reg.name), reg.r_name,
284
len(reg.fields), reg.fields_idx if reg.own_fields else reg.fields_owner.fields_idx))
285
else:
286
print('\t{%s, %s},' % (strings.add(reg.name), reg.r_name))
287
print('};')
288
print()
289
290
strings.emit(sys.stdout, "egd_strings")
291
292
print()
293
294
strings_offsets.emit(sys.stdout, "egd_strings_offsets")
295
296
print()
297
print('#endif')
298
299
300
def main():
301
regs = []
302
packets = []
303
for arg in sys.argv[1:]:
304
parse(arg, regs, packets)
305
write_tables(regs, packets)
306
307
308
if __name__ == '__main__':
309
main()
310
311
# kate: space-indent on; indent-width 4; replace-tabs on;
312
313