mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 10:50:16 +01:00
ac/sid_tables: add FieldTable object
Automatically re-use table entries like StringTable and IntTable do. This allows us to get rid of the "fields_owner" logic, and simplifies the next change. Acked-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
parent
981335b704
commit
925ad7d2f6
1 changed files with 85 additions and 30 deletions
|
|
@ -25,6 +25,8 @@ CopyRight = '''
|
|||
*/
|
||||
'''
|
||||
|
||||
import collections
|
||||
import functools
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
|
@ -132,12 +134,88 @@ class Field:
|
|||
self.name = strip_prefix(s_name)
|
||||
self.values = []
|
||||
|
||||
def format(self, string_table, idx_table):
|
||||
if len(self.values):
|
||||
values_offsets = []
|
||||
for value in self.values:
|
||||
while value[1] >= len(values_offsets):
|
||||
values_offsets.append(-1)
|
||||
values_offsets[value[1]] = string_table.add(strip_prefix(value[0]))
|
||||
return '{%s, %s(~0u), %s, %s}' % (
|
||||
string_table.add(self.name), self.s_name,
|
||||
len(values_offsets), idx_table.add(values_offsets))
|
||||
else:
|
||||
return '{%s, %s(~0u)}' % (string_table.add(self.name), self.s_name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.s_name == other.s_name and
|
||||
self.name == other.name and
|
||||
len(self.values) == len(other.values) and
|
||||
all(a[0] == b[0] and a[1] == b[1] for a, b, in zip(self.values, other.values)))
|
||||
|
||||
def __ne__(self, other):
|
||||
return not (self == other)
|
||||
|
||||
|
||||
class FieldTable:
|
||||
"""
|
||||
A class for collecting multiple arrays of register fields in a single big
|
||||
array that is used by indexing (to avoid relocations in the resulting binary)
|
||||
"""
|
||||
def __init__(self):
|
||||
self.table = []
|
||||
self.idxs = set()
|
||||
self.name_to_idx = collections.defaultdict(lambda: [])
|
||||
|
||||
def add(self, array):
|
||||
"""
|
||||
Add an array of Field objects, and return the index of where to find
|
||||
the array in the table.
|
||||
"""
|
||||
# Check if we can find the array in the table already
|
||||
for base_idx in self.name_to_idx.get(array[0].name, []):
|
||||
if base_idx + len(array) > len(self.table):
|
||||
continue
|
||||
|
||||
for i, a in enumerate(array):
|
||||
b = self.table[base_idx + i]
|
||||
if a != b:
|
||||
break
|
||||
else:
|
||||
return base_idx
|
||||
|
||||
base_idx = len(self.table)
|
||||
self.idxs.add(base_idx)
|
||||
|
||||
for field in array:
|
||||
self.name_to_idx[field.name].append(len(self.table))
|
||||
self.table.append(field)
|
||||
|
||||
return base_idx
|
||||
|
||||
def emit(self, filp, string_table, idx_table):
|
||||
"""
|
||||
Write
|
||||
static const struct si_field sid_fields_table[] = { ... };
|
||||
to filp.
|
||||
"""
|
||||
idxs = sorted(self.idxs) + [len(self.table)]
|
||||
|
||||
filp.write('static const struct si_field sid_fields_table[] = {\n')
|
||||
|
||||
for start, end in zip(idxs, idxs[1:]):
|
||||
filp.write('\t/* %s */\n' % (start))
|
||||
for field in self.table[start:end]:
|
||||
filp.write('\t%s,\n' % (field.format(string_table, idx_table)))
|
||||
|
||||
filp.write('};\n')
|
||||
|
||||
|
||||
class Reg:
|
||||
def __init__(self, r_name):
|
||||
self.r_name = r_name
|
||||
self.name = strip_prefix(r_name)
|
||||
self.fields = []
|
||||
self.own_fields = True
|
||||
|
||||
|
||||
def strip_prefix(s):
|
||||
|
|
@ -207,14 +285,13 @@ def parse(filename, regs, packets):
|
|||
reg0 = reg_dict.get(match_number.sub('0', reg.name))
|
||||
if reg0 != None:
|
||||
reg.fields = reg0.fields
|
||||
reg.fields_owner = reg0
|
||||
reg.own_fields = False
|
||||
|
||||
|
||||
def write_tables(regs, packets):
|
||||
|
||||
strings = StringTable()
|
||||
strings_offsets = IntTable("int")
|
||||
fields = FieldTable()
|
||||
|
||||
print '/* This file is autogenerated by sid_tables.py from sid.h. Do not edit directly. */'
|
||||
print
|
||||
|
|
@ -249,42 +326,20 @@ struct si_packet3 {
|
|||
print '};'
|
||||
print
|
||||
|
||||
print 'static const struct si_field sid_fields_table[] = {'
|
||||
|
||||
fields_idx = 0
|
||||
for reg in regs:
|
||||
if len(reg.fields) and reg.own_fields:
|
||||
print '\t/* %s */' % (fields_idx)
|
||||
|
||||
reg.fields_idx = fields_idx
|
||||
|
||||
for field in reg.fields:
|
||||
if len(field.values):
|
||||
values_offsets = []
|
||||
for value in field.values:
|
||||
while value[1] >= len(values_offsets):
|
||||
values_offsets.append(-1)
|
||||
values_offsets[value[1]] = strings.add(strip_prefix(value[0]))
|
||||
print '\t{%s, %s(~0u), %s, %s},' % (
|
||||
strings.add(field.name), field.s_name,
|
||||
len(values_offsets), strings_offsets.add(values_offsets))
|
||||
else:
|
||||
print '\t{%s, %s(~0u)},' % (strings.add(field.name), field.s_name)
|
||||
fields_idx += 1
|
||||
|
||||
print '};'
|
||||
print
|
||||
|
||||
print 'static const struct si_reg sid_reg_table[] = {'
|
||||
for reg in regs:
|
||||
if len(reg.fields):
|
||||
print '\t{%s, %s, %s, %s},' % (strings.add(reg.name), reg.r_name,
|
||||
len(reg.fields), reg.fields_idx if reg.own_fields else reg.fields_owner.fields_idx)
|
||||
len(reg.fields), fields.add(reg.fields))
|
||||
else:
|
||||
print '\t{%s, %s},' % (strings.add(reg.name), reg.r_name)
|
||||
print '};'
|
||||
print
|
||||
|
||||
fields.emit(sys.stdout, strings, strings_offsets)
|
||||
|
||||
print
|
||||
|
||||
strings.emit(sys.stdout, "sid_strings")
|
||||
|
||||
print
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue