drm/3d_registers_bits.h: render POSSIBLE VALUES

This commit is contained in:
Zack Buhman 2025-10-14 23:40:41 -05:00
parent 95e9ba85ae
commit 564e05f29c
4 changed files with 884 additions and 26 deletions

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,12 @@ def bit_definition_filename(s):
assert False, s
def find_name(descriptor, bit_value):
for value, (name, _) in descriptor.possible_values.items():
if value == bit_value and name is not None:
return f"{descriptor.field_name}__{name} // {bit_value}"
return f"{descriptor.field_name}({bit_value})"
def decode_bits(reg_name, value):
filename = bit_definition_filename(reg_name)
l = list(parse_file_fields(filename))
@ -44,7 +50,8 @@ def decode_bits(reg_name, value):
low = low_from_bits(descriptor.bits)
bit_value = (value >> low) & mask
dot = ',' if i == 0 else '|'
lines.append(f"{dot} {prefix}__{descriptor.field_name}({bit_value})")
lines.append(f"{dot} {prefix}__{find_name(descriptor, bit_value)}")
value &= ~(mask << low)
gen_value |= (bit_value << low)
assert value == 0, (hex(value), hex(orig_value))

View File

@ -24,6 +24,11 @@ def render_descriptor(prefix, d):
mask = mask_from_bits(d.bits)
low = low_from_bits(d.bits)
print(f"#define {prefix}__{d.field_name}(n) (((n) & {hex(mask)}) << {low})")
seen_names = set()
for value, (name, description) in d.possible_values.items():
if name != None and name not in seen_names:
seen_names.add(name)
print(f"#define {prefix}__{d.field_name}__{name} ({hex(value)} << {low})")
def prefix_from_filename(filename):
prefix = filename.removesuffix('.txt')
@ -33,6 +38,6 @@ def prefix_from_filename(filename):
if __name__ == "__main__":
assert sys.argv[1].endswith('.txt')
l = list(parse_file_fields(sys.argv[1]))
prefix = prefix_from_filename(sys.argv[2])
prefix = prefix_from_filename(sys.argv[1])
for descriptor in aggregate(l):
render_descriptor(prefix, descriptor)

View File

@ -83,13 +83,30 @@ def aggregate(fields):
if not fields[ix+1][3] == 'POSSIBLE VALUES:':
return
ix += 1
while ix + 1 < len(fields) and fields[ix+1][0] == '' and fields[ix+1][3] != '':
field_name, bits, default, description = fields[ix+1]
assert not field_name, field_name
assert not bits, bits
assert not default, default
assert re.match('^[0-9]{2} - ', description), repr(description)
yield description
m = re.match('^([0-9]{2}) - (.*)$', description)
assert m, repr(description)
value, desc = m.groups()
if ": " in desc and ' ' not in desc.split(": ")[0].strip():
name, desc = desc.split(": ")
name = name
elif len(desc.strip().split()) == 1:
name = desc
desc = None
else:
name = None
if name is not None:
name = name.strip().upper().replace('.', '_').replace('-', '_').replace(',', '_').replace('*', 'x').replace('+', 'p')
if name != 'RESERVED':
yield int(value, 10), (name, desc)
ix += 1
def parse_description_lines():
@ -106,15 +123,6 @@ def aggregate(fields):
yield description
ix += 1
def parse_possible_value_num(s):
num, description = s.split(' - ', maxsplit=1)
num = int(num, 10)
if ": " in description:
name, description = description.split(": ")
else:
name = None
return num, (name, description)
while ix < len(fields):
field_name, bits, default, description = fields[ix]
if description == 'POSSIBLE VALUES:':
@ -123,9 +131,7 @@ def aggregate(fields):
else:
description_lines = [description]
description_lines.extend(parse_description_lines())
possible_values = OrderedDict(
map(parse_possible_value_num, parse_possible_values())
)
possible_values = OrderedDict(parse_possible_values())
assert default.startswith('0x') or default == 'none', default
yield Descriptor(