pan/va: Build v15 compiler tables

These use the updated opcodes used by v15.
This commit is contained in:
Lars-Ivar Hesselberg Simonsen 2026-03-11 16:35:17 +01:00
parent e62e3c2010
commit 4d341937b1
4 changed files with 96 additions and 6 deletions

View file

@ -218,6 +218,14 @@ va_disasm_instr(FILE *fp, uint64_t instr)
${recurse_subcodes(OPCODES)}
}
void
va_disasm_instr_v15(FILE *fp, uint64_t instr)
{
unsigned opcode;
${recurse_subcodes(OPCODES_V15)}
}
static bool is_branch(uint64_t instr)
{
<% (exact, mask) = OPCODES.get_exact_mask("BRANCHZ") %>
@ -229,6 +237,17 @@ static bool is_branch(uint64_t instr)
return false;
}
static bool is_branch_v15(uint64_t instr)
{
<% (exact, mask) = OPCODES_V15.get_exact_mask("BRANCHZ") %>
if ((instr & ${hex(mask)}) == ${hex(exact)})
return true;
<% (exact, mask) = OPCODES_V15.get_exact_mask("BRANCHZI") %>
if ((instr & ${hex(mask)}) == ${hex(exact)})
return true;
return false;
}
void
disassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose)
{
@ -276,6 +295,9 @@ class OpBucket:
self.children = {}
def insert(self, subcodes, ins):
# Need an early return in case of removed instructions
if subcodes is None:
return
if len(subcodes) == 0:
self.instr = ins
else:
@ -305,10 +327,12 @@ class OpBucket:
# Build opcode hierarchy:
OPCODES = OpBucket()
OPCODES_V15 = OpBucket()
for ins in instructions:
OPCODES.insert(ins.opcode, ins)
OPCODES_V15.insert(ins.opcode_v15, ins)
try:
print(Template(template).render(OPCODES = OPCODES, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name))
print(Template(template).render(OPCODES = OPCODES, OPCODES_V15 = OPCODES_V15, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name))
except:
print(exceptions.text_error_template().render())

View file

@ -15,6 +15,7 @@
#include <string.h>
void va_disasm_instr(FILE *fp, uint64_t instr);
void va_disasm_instr_v15(FILE *fp, uint64_t instr);
void disassemble_valhall(FILE *fp, const void *code, size_t size, bool verbose);
#endif

View file

@ -100,7 +100,64 @@ valhall_opcodes[BI_NUM_OPCODES] = {
sr_control = op.staging[0].encoded_flags >> 6
%>
[BI_OPCODE_${name.replace('.', '_').upper()}] = {
.exact = ${hex(exact(op))}ULL,
.exact = ${hex(exact(op.opcode))}ULL,
.srcs = {
% for src in ([sr for sr in op.staging if sr.read] + op.srcs):
{
.absneg = ${ibool(src.absneg)},
.swizzle = ${ibool(src.swizzle)},
.notted = ${ibool(src.notted)},
.widen = ${ibool(src.widen)},
.lanes = ${ibool(src.lanes)},
.halfswizzle = ${ibool(src.halfswizzle)},
.lane = ${ibool(src.lane)},
.combine = ${ibool(src.combine)},
% if src.size in [8, 16, 32, 64]:
.size = VA_SIZE_${src.size},
% endif
},
% endfor
},
.type_size = ${typesize(op.name)},
.has_dest = ${ibool(len(op.dests) > 0)},
.is_signed = ${ibool(op.is_signed)},
.unit = VA_UNIT_${op.unit},
.nr_srcs = ${len(op.srcs)},
.nr_staging_srcs = ${sum([sr.read for sr in op.staging])},
.nr_staging_dests = ${sum([sr.write for sr in op.staging])},
.clamp = ${hasmod(x, 'clamp')},
.saturate = ${hasmod(x, 'saturate')},
.rhadd = ${hasmod(x, 'rhadd')},
.round_mode = ${hasmod(x, 'round_mode')},
.condition = ${hasmod(x, 'condition')},
.result_type = ${hasmod(x, 'result_type')},
.vecsize = ${hasmod(x, 'vector_size')},
.register_format = ${hasmod(x, 'register_format')},
.slot = ${hasmod(x, 'slot')},
.sr_count = ${hasmod(x, 'staging_register_count')},
.sr_write_count = ${hasmod(x, 'staging_register_write_count')},
.sr_control = ${sr_control},
},
% endif
% endfor
};
const struct va_opcode_info
valhall_v15_opcodes[BI_NUM_OPCODES] = {
% for op in instructions:
% if op.name not in skip:
<%
name = op.name
if name == 'BRANCHZ':
name = 'BRANCHZ.i16'
sr_control = 0
if len(op.staging) > 0:
sr_control = op.staging[0].encoded_flags >> 6
%>
[BI_OPCODE_${name.replace('.', '_').upper()}] = {
.exact = ${hex(exact(op.opcode_v15))}ULL,
.srcs = {
% for src in ([sr for sr in op.staging if sr.read] + op.srcs):
{
@ -144,9 +201,14 @@ valhall_opcodes[BI_NUM_OPCODES] = {
"""
# Exact value to be ORed in to every opcode
def exact_op(op):
def exact_op(opcode):
exact_op = 0
for subcode in op.opcode:
# Need an early return in case of removed instructions
if not opcode:
return exact_op
for subcode in opcode:
exact_op |= (subcode.value << subcode.start)
return exact_op

View file

@ -186,11 +186,12 @@ class Opcode:
self.mask = mask
class Instruction:
def __init__(self, name, opcode, srcs = [], dests = [], immediates = [], modifiers = [], staging = None, unit = None):
def __init__(self, name, opcode, opcode_v15, srcs = [], dests = [], immediates = [], modifiers = [], staging = None, unit = None):
self.name = name
self.srcs = srcs
self.dests = dests
self.opcode = opcode
self.opcode_v15 = opcode_v15
self.immediates = immediates
self.modifiers = modifiers
self.staging = staging
@ -273,6 +274,7 @@ def build_instr(el, overrides = {}):
# Get overridables
name = overrides.get('name') or el.attrib.get('name')
opcode = overrides.get('opcode') or build_opcode(el, 'opcode')
opcode_v15 = overrides.get('opcode_v15') or build_opcode(el, 'opcode_v15')
unit = overrides.get('unit') or el.attrib.get('unit')
# Get explicit sources/dests
@ -312,7 +314,7 @@ def build_instr(el, overrides = {}):
elif mod.tag =='va_mod':
modifiers.append(build_modifier(mod))
instr = Instruction(name, opcode, srcs = sources, dests = dests, immediates = imms, modifiers = modifiers, staging = staging, unit = unit)
instr = Instruction(name, opcode, opcode_v15, srcs = sources, dests = dests, immediates = imms, modifiers = modifiers, staging = staging, unit = unit)
instructions.append(instr)
@ -323,6 +325,7 @@ def build_group(el):
build_instr(el, overrides = {
'name': ins.attrib['name'],
'opcode': build_opcode(ins, 'opcode'),
'opcode_v15': build_opcode(ins, 'opcode_v15'),
'unit': ins.attrib.get('unit'),
})