nds/registers/format_bits.py
2024-08-31 01:58:07 -05:00

57 lines
1.8 KiB
Python

import sys
from csv_input import read_input
from parse_bits import aggregate_registers
from parse_bits import aggregate_all_enums
from parse_bits import Enum, Bit
from generate import renderer
def mask_from_bits(bits):
h, l = max(bits), min(bits)
mask = 2 ** ((h - l) + 1) - 1
return mask
def render_bit(prefix, bit):
macro_name = f"{prefix}__{bit.name}"
if bit.value is None and bit.mask is None:
# value read macro
mask_value = mask_from_bits(bit.bits)
yield f"#define {macro_name}(v) (((v) >> {min(bit.bits)}) & {hex(mask_value)})"
elif bit.mask is None:
# constant value macro
yield f"#define {macro_name} ({hex(bit.value)} << {min(bit.bits)})"
elif bit.value is None:
# variable macro
mask_value = mask_from_bits(bit.bits)
assert bit.mask & mask_value == mask_value, (bit.mask, mask_value)
yield f"#define {macro_name}(v) (((v) & {hex(mask_value)}) << {min(bit.bits)})"
else:
assert False, bit
def render_enum(prefix, enum):
enum_prefix = f"{prefix}__{enum.name}"
for bit in enum.defs:
yield from render_bit(enum_prefix, bit)
def render_register(register):
for bit_or_enum in register.defs:
if type(bit_or_enum) is Enum:
yield from render_enum(register.name, bit_or_enum)
elif type(bit_or_enum) is Bit:
yield from render_bit(register.name, bit_or_enum)
else:
assert False, (bit_or_enum, type(bit_or_enum))
def render_registers(registers):
for register in registers:
yield from render_register(register)
if __name__ == "__main__":
d = read_input(sys.argv[1])
aggregated = aggregate_registers(d)
registers = aggregate_all_enums(aggregated)
render, out = renderer()
render(render_registers(registers))
sys.stdout.write(out.getvalue())