regs: add pvs_disassemble

This commit is contained in:
Zack Buhman 2025-10-11 17:51:53 -05:00
parent b6472e4c16
commit ae9b0280fc
9 changed files with 225 additions and 42 deletions

3
regs/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
pvs_dst.py
pvs_src.py
pvs_dst_bits.py

5
regs/build.sh Normal file
View File

@ -0,0 +1,5 @@
set -eux
python parse_pvs.py PVS_DST pvs_opcode_and_destination_operand.txt > pvs_dst.py
python parse_pvs.py PVS_SRC pvs_source_operand.txt > pvs_src.py
python parse_pvs_bits.py regs/pvs_opcode_and_destination_operand_bits.txt > pvs_dst_bits.py

85
regs/parse_pvs.py Normal file
View File

@ -0,0 +1,85 @@
import sys
from typing import Union
import re
from dataclasses import dataclass
from pprint import pprint
def split_line_fields(line):
fields = [0, 22, 30]
a = line[fields[0]:fields[1]]
b = line[fields[1]:fields[2]]
c = line[fields[2]:]
return a, b, c
def parse_file_fields(filename):
with open(filename) as f:
lines = f.read().split('\n')
first, *rest = lines
a, b, c = split_line_fields(first)
assert a.rstrip() == 'Field Name', a
assert b.rstrip() == 'Bits', b
assert c.rstrip() == 'Description', c
for line in rest:
if not line.strip():
continue
a, b, c = split_line_fields(line)
yield a.strip(), b.strip(), c.strip()
def parse_bits(s):
if ':' in s:
a, b = s.split(':')
h = int(a, 10)
l = int(b, 10)
assert h > l
return h, l
else:
b = int(s, 10)
return b
def parse_file_fields2(filename):
for line in parse_file_fields(filename):
field_name, bits, description = line
bits = parse_bits(bits)
if not field_name.startswith(prefix + '_'):
assert field_name.startswith("SPARE_")
continue
field_name = field_name.removeprefix(prefix + '_')
yield field_name, bits, description
def out(level, *args):
sys.stdout.write(" " * level + " ".join(args) + '\n')
def mask_from_bits(bits):
if type(bits) is tuple:
high, low = bits
assert high > low, (high, low)
else:
high = bits
low = bits
length = (high - low) + 1
return (1 << length) - 1
def low_from_bits(bits):
if type(bits) is tuple:
return bits[1]
else:
return bits
def generate_python(prefix, fields):
#out(0, f"class {prefix}:")
fields = list(fields)
for field_name, bits, description in fields:
#out(1, f"@staticmethod")
out(0, f"def {field_name}(n):")
out(1, f"return (n >> {low_from_bits(bits)}) & {mask_from_bits(bits)}")
out(0, "")
out(0, "table = [")
for field_name, bits, description in fields:
out(1, f'("{field_name}", {field_name}),')
out(0, "]")
prefix = sys.argv[1]
filename = sys.argv[2]
generate_python(prefix, parse_file_fields2(filename))

30
regs/parse_pvs_bits.py Normal file
View File

@ -0,0 +1,30 @@
import sys
with open(sys.argv[1]) as f:
lines = f.read().strip().split('\n')
ix = 0
def next_ix():
global ix
while not lines[ix].strip():
ix += 1
return ix
while ix < len(lines):
name = lines[next_ix()]
assert name.strip().endswith(":")
name = name.strip().removesuffix(":")
ix += 1
print(f"{name} = {{")
while ix < len(lines) and not lines[next_ix()].strip().endswith(":"):
key, value = lines[next_ix()].split("=")
if key.startswith("PVS_DST_REG_"):
key = key.removeprefix("PVS_DST_REG_")
print(f' {value.strip()}: "{key.strip()}",')
ix += 1
print("}")
print()

55
regs/pvs_disassemble.py Normal file
View File

@ -0,0 +1,55 @@
import pvs_src
import pvs_dst
import pvs_dst_bits
from pprint import pprint
code = [
0xf00203,
0xd10001,
0x1248001,
0x1248001
]
def out(level, *args):
sys.stdout.write(" " * level + " ".join(args))
def parse_code(code):
ix = 0
pvs_dst_maxlen = max(len(k) for k, _ in pvs_dst.table)
print(pvs_dst_maxlen)
while ix < len(code):
print(f"ix: {ix // 4}")
dst_op = code[ix + 0]
src_op0 = code[ix + 1]
src_op1 = code[ix + 2]
src_op2 = code[ix + 3]
print(f" dst: {dst_op:08x}")
for name, parse in pvs_dst.table:
namepad = name.ljust(pvs_dst_maxlen + 1)
value = parse(dst_op)
if name == "OPCODE":
if pvs_dst.MATH_INST(dst_op):
print(" ", namepad, pvs_dst_bits.MATH_OPCODE[value])
else:
print(" ", namepad, pvs_dst_bits.VECTOR_OPCODE[value])
elif name == "REG_TYPE":
print(" ", namepad, pvs_dst_bits.PVS_DST_REG[value])
else:
print(" ", namepad, value)
print(f" src0: {src_op0:08x}")
for name, parse in pvs_src.table:
print(" ", name, parse(src_op0))
print(f" src1: {src_op1:08x}")
for name, parse in pvs_src.table:
print(" ", name, parse(src_op1))
print(f" src2: {src_op2:08x}")
for name, parse in pvs_src.table:
print(" ", name, parse(src_op2))
ix += 4
parse_code(code)

View File

@ -2,10 +2,7 @@ Field Name Bit(s) Description
PVS_SRC_REG_TYPE 1:0 Defines the Memory Select (Register Type) for the Source Operand. See Below.
PVS_DST_OPCODE_MSB 2 Math Opcode MSB for Dual Math Inst.
PVS_SRC_ABS_XYZW 3 If set, Take absolute value of both components of Dual Math input vector.
PVS_SRC_ADDR_MODE_0 4 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE as follows:
0 = Absolute addressing
1 = Relative addressing using A0 register
2 = Relative addressing using I0 register (loop index)
PVS_SRC_ADDR_MODE_0 4 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
PVS_SRC_OFFSET 12:5 Vector Offset into selected memory (Register Type)
PVS_SRC_SWIZZLE_X 15:13 X-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_Y 18:16 Y-Component Swizzle Select. See Below
@ -15,7 +12,4 @@ PVS_SRC_MODIFIER_X 25 If set, Negate X Component of input vector.
PVS_SRC_MODIFIER_Y 26 If set, Negate Y Component of input vector.
PVS_DST_WE_SEL 28:27 Encoded Write Enable for Dual Math Op Inst (0 = X, 1 = Y, 2 = Z, 3 = W)
PVS_SRC_ADDR_SEL 30:29 When PVS_SRC_ADDR_MODE is set, this selects which component of the 4-component address register to use.
PVS_SRC_ADDR_MODE_1 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE as follows:
0 = Absolute addressing
1 = Relative addressing using A0 register
2 = Relative addressing using I0 register (loop index)
PVS_SRC_ADDR_MODE_1 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE

View File

@ -1,18 +1,18 @@
Field Name Bits Description
PVS_DST_OPCODE 5:0 Selects the Operation which is to be performed.
PVS_DST_MATH_INST 6 Specifies a Math Engine Operation
PVS_DST_MACRO_INST 7 Specifies a Macro Operation
PVS_DST_REG_TYPE 11:8 Defines the Memory Select (Register Type) for the Dest Operand.
PVS_DST_ADDR_MODE_1 12 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
PVS_DST_OFFSET 20 Vector Offset into the Selected Memory
PVS_DST_WE_X 21 Write Enable for X Component
PVS_DST_WE_Y 22 Write Enable for Y Component
PVS_DST_WE_Z 23 Write Enable for Z Component
PVS_DST_WE_W 24 Write Enable for W Component
PVS_DST_VE_SAT 19:13 Vector engine operation is saturate clamped between 0 and 1 (all components)
PVS_DST_ME_SAT 25 Math engine operation is saturate clamped between 0 and 1 (all components)
PVS_DST_PRED_ENABLE 26 Operation is predicated – Operation writes if predicate bit matches predicate sense.
PVS_DST_PRED_SENSE 27 Operation predication sense – If set, operation writes if predicate bit is set. If reset, operation writes if predicate bit is reset.
PVS_DST_DUAL_MATH_OP 28 Set to describe a dual-math op.
PVS_DST_ADDR_SEL 30:29 When PVS_DST_ADDR_MODE is set, this selects which component of the 4-component address register to use.
PVS_DST_ADDR_MODE_0 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
Field Name Bits Description
PVS_DST_OPCODE 5:0 Selects the Operation which is to be performed.
PVS_DST_MATH_INST 6 Specifies a Math Engine Operation
PVS_DST_MACRO_INST 7 Specifies a Macro Operation
PVS_DST_REG_TYPE 11:8 Defines the Memory Select (Register Type) for the Dest Operand.
PVS_DST_ADDR_MODE_1 12 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
PVS_DST_OFFSET 19:13 Vector Offset into the Selected Memory
PVS_DST_WE_X 20 Write Enable for X Component
PVS_DST_WE_Y 21 Write Enable for Y Component
PVS_DST_WE_Z 22 Write Enable for Z Component
PVS_DST_WE_W 23 Write Enable for W Component
PVS_DST_VE_SAT 24 Vector engine operation is saturate clamped between 0 and 1 (all components)
PVS_DST_ME_SAT 25 Math engine operation is saturate clamped between 0 and 1 (all components)
PVS_DST_PRED_ENABLE 26 Operation is predicated – Operation writes if predicate bit matches predicate sense.
PVS_DST_PRED_SENSE 27 Operation predication sense – If set, operation writes if predicate bit is set. If reset, operation writes if predicate bit is reset.
PVS_DST_DUAL_MATH_OP 28 Set to describe a dual-math op.
PVS_DST_ADDR_SEL 30:29 When PVS_DST_ADDR_MODE is set, this selects which component of the 4-component address register to use.
PVS_DST_ADDR_MODE_0 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE

View File

@ -58,3 +58,14 @@ ME_PRED_SET_CLR = 25
ME_PRED_SET_INV = 26
ME_PRED_SET_POP = 27
ME_PRED_SET_RESTORE = 28
PVS_DST_REG:
PVS_DST_REG_TEMPORARY = 0
PVS_DST_REG_A0 = 1
PVS_DST_REG_OUT = 2
PVS_DST_REG_OUT_REPL_X = 3
PVS_DST_REG_ALT_TEMPORARY = 4
PVS_DST_REG_INPUT = 5
ADDR_MODE:
ABSOLUTE = 0
RELATIVE_A0 = 1
RELATIVE_I0 = 2

View File

@ -1,16 +1,16 @@
Field Name Bit(s) Description
PVS_SRC_REG_TYPE 1:0 Defines the Memory Select (Register Type) for the Source Operand. See Below.
SPARE_0 2
PVS_SRC_ABS_XYZW 3 If set, Take absolute value of all 4 components of input vector.
PVS_SRC_ADDR_MODE_0 4 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
PVS_SRC_OFFSET 12:5 Vector Offset into selected memory (Register Type)
PVS_SRC_SWIZZLE_X 15:13 X-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_Y 18:16 Y-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_Z 21:19 Z-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_W 24:22 W-Component Swizzle Select. See Below
PVS_SRC_MODIFIER_X 25 If set, Negate X Component of input vector.
PVS_SRC_MODIFIER_Y 26 If set, Negate Y Component of input vector.
PVS_SRC_MODIFIER_Z 27 If set, Negate Z Component of input vector.
PVS_SRC_MODIFIER_W 28 If set, Negate W Component of input vector.
PVS_SRC_ADDR_SEL 30:29 When PVS_SRC_ADDR_MODE is set, this selects which component of the 4-component address register to use.
PVS_SRC_ADDR_MODE_1 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
Field Name Bits Description
PVS_SRC_REG_TYPE 1:0 Defines the Memory Select (Register Type) for the Source Operand. See Below.
SPARE_0 2
PVS_SRC_ABS_XYZW 3 If set, Take absolute value of all 4 components of input vector.
PVS_SRC_ADDR_MODE_0 4 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE
PVS_SRC_OFFSET 12:5 Vector Offset into selected memory (Register Type)
PVS_SRC_SWIZZLE_X 15:13 X-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_Y 18:16 Y-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_Z 21:19 Z-Component Swizzle Select. See Below
PVS_SRC_SWIZZLE_W 24:22 W-Component Swizzle Select. See Below
PVS_SRC_MODIFIER_X 25 If set, Negate X Component of input vector.
PVS_SRC_MODIFIER_Y 26 If set, Negate Y Component of input vector.
PVS_SRC_MODIFIER_Z 27 If set, Negate Z Component of input vector.
PVS_SRC_MODIFIER_W 28 If set, Negate W Component of input vector.
PVS_SRC_ADDR_SEL 30:29 When PVS_SRC_ADDR_MODE is set, this selects which component of the 4-component address register to use.
PVS_SRC_ADDR_MODE_1 31 Combine ADDR_MODE_1 (msb) with ADDR_MODE_0 (lsb) to form 2-bit ADDR_MODE