regs: add pvs_disassemble
This commit is contained in:
parent
b6472e4c16
commit
ae9b0280fc
3
regs/.gitignore
vendored
Normal file
3
regs/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
pvs_dst.py
|
||||
pvs_src.py
|
||||
pvs_dst_bits.py
|
5
regs/build.sh
Normal file
5
regs/build.sh
Normal 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
85
regs/parse_pvs.py
Normal 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
30
regs/parse_pvs_bits.py
Normal 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
55
regs/pvs_disassemble.py
Normal 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)
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user