pan/va: XMLify opcode2

Opcode2 was a bit all over the place, so utilize the new opcode modifier
to gather opcode2 information in a single place.

This cleans up the implicit va_mods "left", "descriptor_type" and
"memory_width".

Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Acked-by: Lorenzo Rossi <lorenzo.rossi@collabora.com>
Acked-by: Eric R. Smith <eric.smith@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40199>
This commit is contained in:
Lars-Ivar Hesselberg Simonsen 2026-03-02 13:22:59 +01:00 committed by Marge Bot
parent 5b24568c87
commit adffad6adb
5 changed files with 323 additions and 178 deletions

File diff suppressed because it is too large Load diff

View file

@ -316,7 +316,8 @@ def parse_asm(line):
# Encode the operation itself
encoded |= (ins.opcode.value << ins.opcode.start)
encoded |= (ins.opcode2 << ins.secondary_shift)
if ins.opcode2:
encoded |= (ins.opcode2.value << ins.opcode2.start)
# Encode FAU page
if fau.page:

View file

@ -121,17 +121,17 @@ va_disasm_instr(FILE *fp, uint64_t instr)
% if len(ops) > 0:
case ${hex(bucket)}:
% if ambiguous:
secondary_opc = (instr >> ${ops[0].secondary_shift}) & ${hex(ops[0].secondary_mask)};
secondary_opc = (instr >> ${ops[0].opcode2.start}) & ${hex(ops[0].opcode2.mask)};
% endif
% for op in ops:
<% no_comma = True %>
% if ambiguous:
if (secondary_opc == ${op.opcode2}) {
if (secondary_opc == ${op.opcode2.value}) {
% endif
fputs("${op.name}", fp);
% for mod in op.modifiers:
% if mod.name not in ["left", "memory_width", "descriptor_type", "staging_register_count", "staging_register_write_count"]:
% if mod.name not in ["staging_register_count", "staging_register_write_count"]:
% if mod.is_enum:
fputs(valhall_${safe_name(mod.enum)}[(instr >> ${mod.start}) & ${hex((1 << mod.size) - 1)}], fp);
% else:
@ -288,8 +288,8 @@ for op in OPCODE_BUCKETS:
assert(len(ins.srcs) == len(bucket[0].srcs))
# Must not repeat, else we're ambiguous
assert(ins.opcode2 not in SECONDARY)
SECONDARY[ins.opcode2] = ins
assert(ins.opcode2.value not in SECONDARY)
SECONDARY[ins.opcode2.value] = ins
try:
print(Template(template).render(OPCODES = OPCODE_BUCKETS, IMMEDIATES = immediates, ENUMS = enums, typesize = typesize, safe_name = safe_name))

View file

@ -147,7 +147,10 @@ valhall_opcodes[BI_NUM_OPCODES] = {
# Exact value to be ORed in to every opcode
def exact_op(op):
return (op.opcode.value << op.opcode.start) | (op.opcode2 << op.secondary_shift)
exact_op = (op.opcode.value << op.opcode.start)
if op.opcode2:
exact_op |= (op.opcode2.value << op.opcode2.start)
return exact_op
try:
print(Template(template).render(immediates = immediates, instructions = instructions, skip = SKIP, exact = exact_op, typesize = typesize))

View file

@ -169,7 +169,7 @@ class Instruction:
self.srcs = srcs
self.dests = dests
self.opcode = opcode
self.opcode2 = opcode2 or 0
self.opcode2 = opcode2
self.immediates = immediates
self.modifiers = modifiers
self.staging = staging
@ -179,27 +179,8 @@ class Instruction:
# Message-passing instruction <===> not ALU instruction
self.message = unit not in ["FMA", "CVT", "SFU"]
self.secondary_shift = max(len(self.srcs) * 8, 16)
self.secondary_mask = 0xF if opcode2 is not None else 0x0
if "left" in [x.name for x in self.modifiers]:
self.secondary_mask |= 0x100
if len(srcs) == 3 and (srcs[1].widen or srcs[1].lanes or srcs[1].swizzle):
self.secondary_mask &= ~0xC # conflicts
if opcode.value == 0x90:
# XXX: XMLify this, but disambiguates sign of conversions
self.secondary_mask |= 0x10
if name.startswith("LOAD.i") or name.startswith("STORE.i") or name.startswith("LD_PKA.i"):
self.secondary_shift = 27 # Alias with memory_size
self.secondary_mask = 0x7
if "descriptor_type" in [x.name for x in self.modifiers]:
self.secondary_mask = 0x3
self.secondary_shift = 37
elif "memory_width" in [x.name for x in self.modifiers]:
self.secondary_mask = 0x7
self.secondary_shift = 27
assert(len(dests) == 0 or not staging)
assert(not opcode2 or (opcode2 & self.secondary_mask) == opcode2)
assert(not opcode2 or (opcode2.value & opcode2.mask) == opcode2.value)
def __str__(self):
return self.name
@ -258,9 +239,8 @@ 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')
opcode2 = overrides.get('opcode2') or el.attrib.get('opcode2')
opcode2 = overrides.get('opcode2') or build_opcode(el, 'opcode2')
unit = overrides.get('unit') or el.attrib.get('unit')
opcode2 = int(opcode2, base=0) if opcode2 else None
# Get explicit sources/dests
tsize = typesize(name)
@ -310,7 +290,7 @@ def build_group(el):
build_instr(el, overrides = {
'name': ins.attrib['name'],
'opcode': build_opcode(ins, 'opcode'),
'opcode2': ins.attrib.get('opcode2'),
'opcode2': build_opcode(ins, 'opcode2'),
'unit': ins.attrib.get('unit'),
})