wip
This commit is contained in:
parent
0879b6b8f1
commit
4b47f4f2c7
@ -64,7 +64,7 @@ ADDR2_REL 29 0x0 Specifies whether the loop register is added to
|
||||
01 - RELATIVE: Add aL before lookup.
|
||||
SRCP_OP 31:30 0x0 Specifies how the pre-subtract value (SRCP) is computed.
|
||||
POSSIBLE VALUES:
|
||||
00 - 1.0-2.0*A0
|
||||
01 - A1-A0
|
||||
02 - A1+A0
|
||||
03 - 1.0-A0
|
||||
00 - neg2: 1.0-2.0*A0
|
||||
01 - sub: A1-A0
|
||||
02 - add: A1+A0
|
||||
03 - neg: 1.0-A0
|
||||
|
||||
@ -65,7 +65,7 @@ ADDR2_REL 29 0x0 Specifies whether the loop register is added to
|
||||
SRCP_OP 31:30 0x0 Specifies how the pre-subtract value (SRCP) is
|
||||
computed.
|
||||
POSSIBLE VALUES:
|
||||
00 - 1.0-2.0*RGB0
|
||||
01 - RGB1-RGB0
|
||||
02 - RGB1+RGB0
|
||||
03 - 1.0-RGB0
|
||||
00 - neg2: 1.0-2.0*RGB0
|
||||
01 - sub: RGB1-RGB0
|
||||
02 - add: RGB1+RGB0
|
||||
03 - neg: 1.0-RGB0
|
||||
|
||||
@ -45,8 +45,10 @@ fc = [
|
||||
]
|
||||
|
||||
def parse_registers():
|
||||
base = path.dirname(__file__)
|
||||
|
||||
for register in register_names:
|
||||
filename = path.join("bits", register.lower() + ".txt")
|
||||
filename = path.join(base, "bits", register.lower() + ".txt")
|
||||
l = list(parse_bits.parse_file_fields(filename))
|
||||
yield register, OrderedDict(
|
||||
(d.field_name, d) for d in parse_bits.aggregate(l)
|
||||
@ -142,5 +144,4 @@ if __name__ == "__main__":
|
||||
buf = f.read()
|
||||
code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()]
|
||||
for i in range(len(code) // 6):
|
||||
|
||||
disassemble(code, i * 6)
|
||||
|
||||
186
regs/us_disassemble2.py
Normal file
186
regs/us_disassemble2.py
Normal file
@ -0,0 +1,186 @@
|
||||
import sys
|
||||
from os import path
|
||||
import parse_bits
|
||||
from collections import OrderedDict
|
||||
from functools import partial
|
||||
from pprint import pprint
|
||||
|
||||
class BaseRegister:
|
||||
def get(self, n, *, descriptor):
|
||||
if type(descriptor.bits) is int:
|
||||
return (n >> descriptor.bits) & 1
|
||||
else:
|
||||
high, low = descriptor.bits
|
||||
assert high > low
|
||||
mask_length = (high - low) + 1
|
||||
mask = (1 << mask_length) - 1
|
||||
return (n >> low) & mask
|
||||
|
||||
def get_name(self, n, *, descriptor):
|
||||
value = self.get(n, descriptor=descriptor)
|
||||
return value, *descriptor.possible_values[value]
|
||||
|
||||
def parse_register(register_name):
|
||||
base = path.dirname(__file__)
|
||||
|
||||
filename = path.join(base, "bits", register_name.lower() + ".txt")
|
||||
l = list(parse_bits.parse_file_fields(filename))
|
||||
#return OrderedDict(
|
||||
# (d.field_name, d) for d in parse_bits.aggregate(l)
|
||||
#)
|
||||
cls = type(register_name, (BaseRegister,), {})
|
||||
instance = cls()
|
||||
descriptors = list(parse_bits.aggregate(l))
|
||||
for descriptor in descriptors:
|
||||
setattr(instance, descriptor.field_name, partial(instance.get, descriptor=descriptor))
|
||||
setattr(instance, f"_{descriptor.field_name}", partial(instance.get_name, descriptor=descriptor))
|
||||
func = getattr(instance, descriptor.field_name)
|
||||
for pv_value, (pv_name, _) in descriptor.possible_values.items():
|
||||
if pv_name is not None:
|
||||
setattr(func, pv_name, pv_value)
|
||||
assert getattr(instance, "descriptors", None) is None
|
||||
instance.descriptors = descriptors
|
||||
|
||||
return instance
|
||||
|
||||
US_CMN_INST = parse_register("US_CMN_INST")
|
||||
US_ALU_RGB_ADDR = parse_register("US_ALU_RGB_ADDR")
|
||||
US_ALU_ALPHA_ADDR = parse_register("US_ALU_ALPHA_ADDR")
|
||||
US_ALU_RGB_INST = parse_register("US_ALU_RGB_INST")
|
||||
US_ALU_ALPHA_INST = parse_register("US_ALU_ALPHA_INST")
|
||||
US_ALU_RGBA_INST = parse_register("US_ALU_RGBA_INST")
|
||||
US_TEX_INST = parse_register("US_TEX_INST")
|
||||
US_TEX_ADDR = parse_register("US_TEX_ADDR")
|
||||
US_TEX_ADDR_DXDY = parse_register("US_TEX_ADDR_DXDY")
|
||||
US_FC_INST = parse_register("US_FC_INST")
|
||||
US_FC_ADDR = parse_register("US_FC_ADDR")
|
||||
|
||||
def disassemble_addr_inner(register_const, address, const, rel):
|
||||
assert rel == 0
|
||||
if const == register_const.TEMPORARY:
|
||||
if address & (1 << 7):
|
||||
value = address & 0x7f
|
||||
return f"float({value})"
|
||||
else:
|
||||
return f"temp[{address}]"
|
||||
elif const == register_const.CONSTANT:
|
||||
return f"const[{address}]"
|
||||
else:
|
||||
assert False, const
|
||||
|
||||
def disassemble_addr(register, addr, prefix):
|
||||
addr0 = register.ADDR0(addr)
|
||||
addr0_const = register.ADDR0_CONST(addr)
|
||||
addr0_rel = register.ADDR0_REL(addr)
|
||||
addr1 = register.ADDR1(addr)
|
||||
addr1_const = register.ADDR1_CONST(addr)
|
||||
addr1_rel = register.ADDR1_REL(addr)
|
||||
addr2 = register.ADDR2(addr)
|
||||
addr2_const = register.ADDR2_CONST(addr)
|
||||
addr2_rel = register.ADDR2_REL(addr)
|
||||
_, srcp_op, _ = register._SRCP_OP(addr)
|
||||
|
||||
s0 = disassemble_addr_inner(register.ADDR0_CONST, addr0, addr0_const, addr0_rel)
|
||||
s1 = disassemble_addr_inner(register.ADDR1_CONST, addr1, addr1_const, addr1_rel)
|
||||
s2 = disassemble_addr_inner(register.ADDR2_CONST, addr2, addr2_const, addr2_rel)
|
||||
sp = srcp_op.lower()
|
||||
return [
|
||||
f"{prefix}{i} = {s}"
|
||||
for i, s in [('0', s0), ('1', s1), ('2', s2), ('p', sp)]
|
||||
]
|
||||
|
||||
swizzle_strs = ['r', 'g', 'b', 'a', '0', 'h', '1', '_']
|
||||
sel_strs = ['0', '1', '2', 'p']
|
||||
|
||||
def disassemble_rgb_swizzle_sel(us_alu_rgb_inst, us_alu_rgba_inst):
|
||||
rgb_sel_a = US_ALU_RGB_INST.RGB_SEL_A(us_alu_rgb_inst)
|
||||
red_swiz_a = US_ALU_RGB_INST.RED_SWIZ_A(us_alu_rgb_inst)
|
||||
green_swiz_a = US_ALU_RGB_INST.GREEN_SWIZ_A(us_alu_rgb_inst)
|
||||
blue_swiz_a = US_ALU_RGB_INST.BLUE_SWIZ_A(us_alu_rgb_inst)
|
||||
rgb_mod_a = US_ALU_RGB_INST.RGB_MOD_A(us_alu_rgb_inst)
|
||||
|
||||
rgb_sel_b = US_ALU_RGB_INST.RGB_SEL_B(us_alu_rgb_inst)
|
||||
red_swiz_b = US_ALU_RGB_INST.RED_SWIZ_B(us_alu_rgb_inst)
|
||||
green_swiz_b = US_ALU_RGB_INST.GREEN_SWIZ_B(us_alu_rgb_inst)
|
||||
blue_swiz_b = US_ALU_RGB_INST.BLUE_SWIZ_B(us_alu_rgb_inst)
|
||||
rgb_mod_b = US_ALU_RGB_INST.RGB_MOD_B(us_alu_rgb_inst)
|
||||
|
||||
rgb_sel_c = US_ALU_RGBA_INST.RGB_SEL_C(us_alu_rgba_inst)
|
||||
red_swiz_c = US_ALU_RGBA_INST.RED_SWIZ_C(us_alu_rgba_inst)
|
||||
green_swiz_c = US_ALU_RGBA_INST.GREEN_SWIZ_C(us_alu_rgba_inst)
|
||||
blue_swiz_c = US_ALU_RGBA_INST.BLUE_SWIZ_C(us_alu_rgba_inst)
|
||||
rgb_mod_c = US_ALU_RGBA_INST.RGB_MOD_C(us_alu_rgba_inst)
|
||||
|
||||
assert rgb_mod_a == 0
|
||||
assert rgb_mod_b == 0
|
||||
assert rgb_mod_c == 0
|
||||
|
||||
rgb_swiz_a = ''.join(swizzle_strs[n] for n in [red_swiz_a, green_swiz_a, blue_swiz_a])
|
||||
rgb_swiz_b = ''.join(swizzle_strs[n] for n in [red_swiz_b, green_swiz_b, blue_swiz_b])
|
||||
rgb_swiz_c = ''.join(swizzle_strs[n] for n in [red_swiz_c, green_swiz_c, blue_swiz_c])
|
||||
|
||||
rgb_swiz = [rgb_swiz_a, rgb_swiz_b, rgb_swiz_c]
|
||||
rgb_sels = [sel_strs[n] for n in [rgb_sel_a, rgb_sel_b, rgb_sel_c]]
|
||||
|
||||
return ", ".join(f"rgb{sel}.{swiz}" for swiz, sel in zip(rgb_swiz, rgb_sels))
|
||||
|
||||
def disassemble_a_swizzle_sel(us_alu_alpha_inst, us_alu_rgba_inst):
|
||||
alpha_sel_a = US_ALU_ALPHA_INST.ALPHA_SEL_A(us_alu_alpha_inst)
|
||||
alpha_swiz_a = US_ALU_ALPHA_INST.ALPHA_SWIZ_A(us_alu_alpha_inst)
|
||||
alpha_mod_a = US_ALU_ALPHA_INST.ALPHA_MOD_A(us_alu_alpha_inst)
|
||||
|
||||
alpha_sel_b = US_ALU_ALPHA_INST.ALPHA_SEL_B(us_alu_alpha_inst)
|
||||
alpha_swiz_b = US_ALU_ALPHA_INST.ALPHA_SWIZ_B(us_alu_alpha_inst)
|
||||
alpha_mod_b = US_ALU_ALPHA_INST.ALPHA_MOD_B(us_alu_alpha_inst)
|
||||
|
||||
alpha_sel_c = US_ALU_RGBA_INST.ALPHA_SEL_C(us_alu_rgba_inst)
|
||||
alpha_swiz_c = US_ALU_RGBA_INST.ALPHA_SWIZ_C(us_alu_rgba_inst)
|
||||
alpha_mod_c = US_ALU_RGBA_INST.ALPHA_MOD_C(us_alu_rgba_inst)
|
||||
|
||||
assert alpha_mod_a == 0
|
||||
assert alpha_mod_b == 0
|
||||
assert alpha_mod_c == 0
|
||||
|
||||
a_swiz = [swizzle_strs[n] for n in [alpha_swiz_a, alpha_swiz_b, alpha_swiz_c]]
|
||||
a_sels = [sel_strs[n] for n in [alpha_sel_a, alpha_sel_b, alpha_sel_c]]
|
||||
|
||||
return ", ".join(f"a{sel}.{swiz}" for swiz, sel in zip(a_swiz, a_sels))
|
||||
|
||||
def disassemble_alu(ix, code):
|
||||
us_cmn_inst = code[ix + 0]
|
||||
us_alu_rgb_addr = code[ix + 1]
|
||||
us_alu_alpha_addr = code[ix + 2]
|
||||
us_alu_rgb_inst = code[ix + 3]
|
||||
us_alu_alpha_inst = code[ix + 4]
|
||||
us_alu_rgba_inst = code[ix + 5]
|
||||
|
||||
rgb_addr_strs = disassemble_addr(US_ALU_RGB_ADDR, us_alu_rgb_addr, "rgb")
|
||||
a_addr_strs = disassemble_addr(US_ALU_ALPHA_ADDR, us_alu_alpha_addr, "a")
|
||||
print(", ".join([*rgb_addr_strs, *a_addr_strs]))
|
||||
|
||||
rgb_swizzle_sel = disassemble_rgb_swizzle_sel(us_alu_rgb_inst, us_alu_rgba_inst)
|
||||
a_swizzle_sel = disassemble_a_swizzle_sel(us_alu_alpha_inst, us_alu_rgba_inst)
|
||||
|
||||
#omod
|
||||
#target
|
||||
#alu_wmask
|
||||
|
||||
def disassemble(ix, code):
|
||||
value = US_CMN_INST.TYPE(code[ix + 0])
|
||||
alu_types = {US_CMN_INST.TYPE.US_INST_TYPE_OUT, US_CMN_INST.TYPE.US_INST_TYPE_ALU}
|
||||
if value in alu_types:
|
||||
disassemble_alu(ix, code)
|
||||
else:
|
||||
assert False, US_CMN_INST._TYPE(code[ix + 0])
|
||||
|
||||
def parse_hex(s):
|
||||
assert s.startswith('0x')
|
||||
return int(s.removeprefix('0x'), 16)
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = sys.argv[1]
|
||||
with open(filename) as f:
|
||||
buf = f.read()
|
||||
code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()]
|
||||
for i in range(len(code) // 6):
|
||||
disassemble(i * 6, code)
|
||||
Loading…
x
Reference in New Issue
Block a user