diff --git a/src/panfrost/compiler/bifrost_isa.py b/src/panfrost/compiler/bifrost_isa.py
index 4be004c3417..6f317e64331 100644
--- a/src/panfrost/compiler/bifrost_isa.py
+++ b/src/panfrost/compiler/bifrost_isa.py
@@ -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 instead of
+ 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: