diff --git a/src/imagination/pco/pco_info.c.py b/src/imagination/pco/pco_info.c.py index 601c4edac42..a446912cdc9 100644 --- a/src/imagination/pco/pco_info.c.py +++ b/src/imagination/pco/pco_info.c.py @@ -3,6 +3,7 @@ from mako.template import Template, exceptions from pco_ops import * +from pco_map import * template = """/* * Copyright © 2024 Imagination Technologies Ltd. @@ -45,6 +46,18 @@ const struct pco_op_info pco_op_info[_PCO_OP_COUNT] = { }, .type = PCO_OP_TYPE_${op.op_type.upper()}, .has_target_cf_node = ${str(op.has_target_cf_node).lower()}, +% if op.bname in group_maps: + .dest_intrn_map = { + % for index, val in group_maps[op.bname].dest_intrn_map: + [${index}] = ${val}, + % endfor + }, + .src_intrn_map = { + % for index, val in group_maps[op.bname].src_intrn_map: + [${index}] = ${val}, + % endfor + }, +% endif }, % endfor }; @@ -91,7 +104,7 @@ const struct pco_ref_mod_info pco_ref_mod_info[_PCO_REF_MOD_COUNT] = { def main(): try: - print(Template(template).render(BaseType=BaseType, ops=ops, op_mods=op_mods, ref_mods=ref_mods)) + print(Template(template).render(BaseType=BaseType, ops=ops, op_mods=op_mods, ref_mods=ref_mods, group_maps=group_maps)) except: raise Exception(exceptions.text_error_template().render()) diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index 0c25ca57751..c53b0b586c5 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -356,6 +356,8 @@ struct pco_op_info { uint64_t src_mods[_PCO_OP_MAX_SRCS]; /** Supported source mods. */ enum pco_op_type type; /** Op type. */ bool has_target_cf_node; /** Set if op has a cf-node as a target. */ + uint8_t dest_intrn_map[_PCO_OP_MAX_DESTS]; + uint8_t src_intrn_map[_PCO_OP_MAX_SRCS]; }; extern const struct pco_op_info pco_op_info[_PCO_OP_COUNT]; diff --git a/src/imagination/pco/pco_map.py b/src/imagination/pco/pco_map.py index 13d9cd36aee..01ed4452a8f 100644 --- a/src/imagination/pco/pco_map.py +++ b/src/imagination/pco/pco_map.py @@ -365,10 +365,12 @@ def encode_map(op, encodings): # Instruction group mapping. class GroupMap(object): - def __init__(self, name, cop_name, mapping_sets): + def __init__(self, name, cop_name, mapping_sets, dest_intrn_map, src_intrn_map): self.name = name self.mapping_sets = mapping_sets self.cop_name = cop_name + self.dest_intrn_map = dest_intrn_map + self.src_intrn_map = src_intrn_map def group_map(op, hdr, enc_ops, srcs=[], iss=[], dests=[]): assert op.bname not in group_maps.keys(), f'Duplicate group mapping for op "{op.name}".' @@ -585,9 +587,54 @@ def group_map(op, hdr, enc_ops, srcs=[], iss=[], dests=[]): assert bool(variant_mappings) mapping_sets.append(variant_mappings); + # Collect src/dest I/O + dest_intrn_map = [] + src_intrn_map = [] + + for src, *_spec in srcs: + if len(_spec) != 2: + continue + + (_phase, origin), _io = _spec + phase = OP_PHASE.enum.elems[_phase].cname + io = IO.enum.elems[_io] + + if not io.string.startswith('s'): + continue + + val = int(io.string[1:]) + 1 + + if is_self: + if origin.type == 'dest': + dest_intrn_map.append((origin.index, val)) + else: + src_intrn_map.append((origin.index, val)) + continue + + origin_op = None + for enc_op in enc_ops: + if enc_op[0] != _phase: + continue + + origin_op = enc_op + break + assert origin_op is not None + + _enc_phase, enc_op, *_enc_spec = enc_op + enc_dests = _enc_spec[0] if len(_enc_spec) > 0 else [] + enc_srcs = _enc_spec[1] if len(_enc_spec) > 1 else [] + + origin = enc_dests[origin.index] if origin.type == 'dest' else enc_srcs[origin.index] + assert isinstance(origin, OpRef) + + if origin.type == 'dest': + dest_intrn_map.append((origin.index, val)) + else: + src_intrn_map.append((origin.index, val)) + name = op.bname cop_name = op.cname.upper() - group_maps[name] = GroupMap(name, cop_name, mapping_sets) + group_maps[name] = GroupMap(name, cop_name, mapping_sets, dest_intrn_map, src_intrn_map) # Encode mappings. encode_map(O_FADD,