panfrost: Update bifrost_isa.py to handle some Valhall constructs

Updates the ISA.xml parser to be able to handle some of the constructs
from the Valhall ISA.xml (which differs in significant ways from the
Bifrost ISA.xml). The eventual intent is to avoid duplicating instructions
in the two files, although that isn't enabled in this patch.

The new features aren't used yet, that will be in a future commit.

Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Acked-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30179>
This commit is contained in:
Eric R. Smith 2024-07-04 20:51:53 +00:00 committed by Marge Bot
parent 470c2637fb
commit c7308b19a0

View file

@ -102,8 +102,8 @@ def parse_modifiers(obj, include_pseudo):
opts = [x.text if x.tag == 'opt' else x.tag for x in mod.findall('*')]
if len(opts) == 0:
assert('opt' in mod.attrib)
opts = ['none', mod.attrib['opt']]
if 'opt' in mod.attrib:
opts = ['none', mod.attrib['opt']]
# Find suitable default
default = mod.attrib.get('default', 'none' if 'none' in opts else None)
@ -122,6 +122,33 @@ def parse_copy(enc, existing):
if ex[0][0] == name:
ex[0][1] = node.get('start')
mod_names = {
'cmp' : [['cmpf', None, None], None, ['eq', 'gt', 'ge', 'ne', 'lt', 'le', 'gtlt', 'total']],
# FIXME: Valhall can accept any integer comparision, but the old IR generator only generated
# gt and ge, and left out lt and le. For now follow the old way so we can compare generated files,
# but we should switch over to the proper way once everything is working
# 'cmpfi' : [['cmpf', None, None], None, ['eq', 'ne', 'gt', 'ge', 'lt', 'le']],
'cmpfi' : [['cmpf', None, None], None, ['eq', 'ne', 'gt', 'ge']],
'eq' : [['cmpf', None, None], 'ne', ['eq', 'ne']],
'dimension' : [['dimension', None, None], None, ['1d', '2d', '3d', 'cube']],
'fetch_component' : [['fetch_component', None, None], None, ['gather4_r', 'gather4_g', 'gather4_b', 'gather4_a']],
'lod_mode': [['va_lod_mode', None, None], 'zero_lod', ['zero_lod', 'computed_lod', 'explicit', 'computed_bias', 'grdesc']],
'regfmt' : [['register_format', None, None], None, ['f16', 'f32', 's32', 'u32', 's16', 'u16', 'f64', 'i64', 'auto']],
'result_type' : [['result_type', None, None], None, ['i1', 'f1', 'm1']],
'sample' : [['sample', None, None], 'none', ['center', 'centroid', 'sample', 'explicit', 'none']],
'update' : [['update', None, None], None, ['store', 'retrieve', 'conditional', 'clobber']],
'vecsize' : [['vecsize', None, None], 'none', ['none', 'v2', 'v3', 'v4']],
'source_format' : [['source_format', None, None], None, ['flat32', 'flat16', 'f32', 'f16']],
'array_enable': [['array_enable', None, None], 'none', ['none', 'array_enable']],
'integer_coordinates': [['integer_coordinates', None, None], 'none', ['none', 'integer_coordinates']],
'shadow' : [['shadow', None, None], 'none', ['none', 'shadow']],
'skip' : [['skip', None, None], 'none', ['none', 'skip']],
'texel_offset': [['texel_offset', None, None], 'none', ['none', 'texel_offset']],
'wide_indices': [['wide_indices', None, None], 'none', ['none', 'wide_indices']],
'write_mask' : [['write_mask', None, None], 'none', ['none', 'r', 'g', 'rg', 'b', 'rb', 'gb', 'rgb', 'a', 'ra', 'ga', 'rga', 'ba', 'rba', 'gba', 'rgba']]
}
def parse_instruction(ins, include_pseudo):
common = {
'srcs': [],
@ -144,12 +171,21 @@ def parse_instruction(ins, include_pseudo):
if 'exact' in ins.attrib:
common['exact'] = parse_exact(ins)
extra_modifiers=[]
src_num = 0
for src in ins.findall('src'):
if src.attrib.get('pseudo', False) and not include_pseudo:
continue
mask = int(src.attrib['mask'], 0) if ('mask' in src.attrib) else 0xFF
common['srcs'].append([int(src.attrib['start'], 0), mask])
if src.attrib.get('start') is not None:
common['srcs'].append([int(src.attrib['start'], 0), mask])
else:
common['srcs'].append([src_num*3, mask])
if src.attrib.get('absneg', False):
extra_modifiers.append([['neg'+str(src_num), '0', '1'], 'neg',['none', 'neg']])
extra_modifiers.append([['abs'+str(src_num), '0', '1'], 'abs',['none', 'abs']])
src_num += 1
for imm in ins.findall('immediate'):
if imm.attrib.get('pseudo', False) and not include_pseudo:
@ -158,8 +194,49 @@ def parse_instruction(ins, include_pseudo):
start = int(imm.attrib['start']) if 'start' in imm.attrib else None
common['immediates'].append([imm.attrib['name'], start, int(imm.attrib['size'])])
# FIXME valhall ISA.xml uses <imm/> instead of <immediate/>
for imm in ins.findall('imm'):
if imm.attrib.get('pseudo', False) and not include_pseudo:
continue
base_name = imm.attrib['name']
name = imm.attrib.get('ir_name', base_name)
if not name:
continue
start = int(imm.attrib['start']) if 'start' in imm.attrib else None
common['immediates'].append([name, start, int(imm.attrib['size'])])
staging_read = False
staging_write = False
for sr in ins.findall('sr'):
if sr.attrib.get('read', False):
staging_read = True
if sr.attrib.get('write', False):
staging_write = True
if staging_read:
common['staging'] = 'r'
if staging_write:
common['staging'] += 'w'
for sr in ins.findall('sr_count'):
size = sr.attrib.get('count', 'sr_count')
common['staging_count'] = size
for m in ins.findall('*'):
name = m.tag
if name == 'cmp':
if m.attrib.get('int_only', False):
name = 'cmpfi'
elif m.attrib.get('eqne_only', False):
name = 'cmpfeq'
if name == 'va_mod':
name = m.attrib.get('name', '')
if name in mod_names:
extra_modifiers.append(mod_names[name])
common['derived'] = parse_derived(ins)
common['modifiers'] = parse_modifiers(ins, include_pseudo)
common['modifiers'] = parse_modifiers(ins, include_pseudo) + extra_modifiers
for swap in ins.findall('swap'):
lr = [int(swap.get('left')), int(swap.get('right'))]
@ -206,14 +283,27 @@ def ins_name(ins, group = False):
base_name = ins.attrib['name']
if group.attrib['unit'] == 'fma':
tagged_name = '*' + base_name
elif group.attrib.get('ir_unit', '') == 'fma':
tagged_name = '*' + base_name
else:
tagged_name = '+' + base_name
return tagged_name
def parse_instructions(xml, include_unused = False, include_pseudo = False):
final = {}
# look at groups of instructions
groups = ET.parse(xml).getroot().findall('group')
for gr in groups:
if gr.attrib.get('unused', False) and not include_unused:
continue
if gr.attrib.get('pseudo', False) and not include_pseudo:
continue
group_base = parse_instruction(gr, include_pseudo)
for ins in gr.findall('ins'):
parsed = copy.deepcopy(group_base)
tagged_name = ins_name(ins, gr)
final[tagged_name] = parsed
# now look at individual instructions
instructions = ET.parse(xml).getroot().findall('ins')
for ins in instructions: