pco: pygen: add control-flow and branch ops

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36412>
This commit is contained in:
Simon Perretta 2025-01-01 14:20:42 +00:00 committed by Marge Bot
parent 00f0813659
commit 7259b4a5cd
3 changed files with 133 additions and 5 deletions

View file

@ -2604,6 +2604,22 @@ static inline pco_instr *find_parent_instr_from(pco_ref src, pco_instr *from)
return NULL;
}
static inline unsigned pco_igrp_offset(pco_igrp *igrp)
{
return igrp->enc.offset;
}
static inline unsigned pco_cf_node_offset(pco_cf_node *cf_node)
{
pco_block *block = pco_cf_node_as_block(cf_node);
return pco_igrp_offset(pco_first_igrp(block));
}
static inline unsigned pco_branch_rel_offset(pco_igrp *br, pco_cf_node *cf_node)
{
return pco_cf_node_offset(cf_node) - pco_igrp_offset(br);
}
static inline bool pco_should_skip_pass(const char *pass)
{
return comma_separated_list_contains(pco_skip_passes, pass);

View file

@ -264,6 +264,19 @@ enum_map(RM_ELEM.t, F_MASKW0, [
('e3', 'e3'),
], pass_zero=['e0', 'e1', 'e2', 'e3'])
enum_map(OM_CND.t, F_PCND, [
('always', 'always'),
('p0_true', 'p0_true'),
('never', 'never'),
('p0_false', 'p0_false'),
])
enum_map(OM_BRANCH_CND.t, F_BPRED, [
('exec_cond', 'cc'),
('allinst', 'allp'),
('anyinst', 'anyp'),
])
class OpRef(object):
def __init__(self, ref_type, index, mods):
self.type = ref_type
@ -311,13 +324,19 @@ def encode_map(op, encodings, op_ref_maps):
elif isinstance(val_spec, int):
encode_variant += str(val_spec)
elif isinstance(val_spec, str):
assert struct_field.type.base_type == BaseType.enum
# Special case
if val_spec == 'target_cf_node':
assert op.has_target_cf_node
enum = struct_field.type.enum
assert enum.parent is None
assert val_spec in enum.elems.keys(), f'Invalid enum element "{val_spec}" in field "{isa_op_field}" in isa op "{isa_op.bsname}" mapping for op "{op.name}".'
encode_variant += f'pco_branch_rel_offset({{1}}->parent_igrp, {{1}}->target_cf_node)'
else:
assert struct_field.type.base_type == BaseType.enum
encode_variant += enum.elems[val_spec].cname
enum = struct_field.type.enum
assert enum.parent is None
assert val_spec in enum.elems.keys(), f'Invalid enum element "{val_spec}" in field "{isa_op_field}" in isa op "{isa_op.bsname}" mapping for op "{op.name}".'
encode_variant += enum.elems[val_spec].cname
elif isinstance(val_spec, OpMod):
assert val_spec in op.op_mods, f'Op mod "{val_spec.t.tname}" was specified but not valid in isa op "{isa_op.bsname}" mapping for op "{op.name}".'
@ -1269,6 +1288,40 @@ encode_map(O_DITRP,
op_ref_maps=[('ctrl', ['temp'], ['drc', 'coeff', 'coeff', 'imm'])]
)
encode_map(O_CNDST,
encodings=[
(I_CND, [
('adjust', ('pco_ref_get_imm', SRC(1))),
('pcnd', OM_CND),
('cndinst', 'st')
])
],
op_ref_maps=[('ctrl', ['pe', 'w0'], ['s0', 'imm'])]
)
encode_map(O_CNDEND,
encodings=[
(I_CND, [
('adjust', ('pco_ref_get_imm', SRC(1))),
('pcnd', 0),
('cndinst', 'end')
])
],
op_ref_maps=[('ctrl', ['pe', 'w0'], ['s0', 'imm'])]
)
encode_map(O_BR,
encodings=[
(I_BRANCH, [
('link', OM_LINK),
('bpred', OM_BRANCH_CND),
('abs', False),
('offset', 'target_cf_node')
])
],
op_ref_maps=[('ctrl', [], [])]
)
# Group mappings.
group_map(O_FADD,
hdr=(I_IGRP_HDR_MAIN, [
@ -2031,3 +2084,49 @@ group_map(O_DITRP,
]),
enc_ops=[('ctrl', O_DITRP)]
)
group_map(O_CNDST,
hdr=(I_IGRP_HDR_CONTROL, [
('olchk', False),
('w1p', False),
('w0p', True),
('cc', OM_EXEC_CND),
('miscctl', False),
('ctrlop', 'cnd')
]),
enc_ops=[('ctrl', O_CNDST)],
srcs=[
('s[0]', ('ctrl', SRC(0)), 's0'),
('s[3]', 'pco_zero')
],
dests=[('w[0]', ('ctrl', DEST(1)), 'w0')]
)
group_map(O_CNDEND,
hdr=(I_IGRP_HDR_CONTROL, [
('olchk', False),
('w1p', False),
('w0p', True),
('cc', OM_EXEC_CND),
('miscctl', False),
('ctrlop', 'cnd')
]),
enc_ops=[('ctrl', O_CNDEND)],
srcs=[
('s[0]', ('ctrl', SRC(0)), 's0'),
('s[3]', 'pco_zero')
],
dests=[('w[0]', ('ctrl', DEST(1)), 'w0')]
)
group_map(O_BR,
hdr=(I_IGRP_HDR_CONTROL, [
('olchk', False),
('w1p', False),
('w0p', False),
('cc', OM_EXEC_CND),
('miscctl', False),
('ctrlop', 'b')
]),
enc_ops=[('ctrl', O_BR)]
)

View file

@ -293,6 +293,13 @@ OM_SHIFTOP = op_mod_enum('shiftop', [
'asr',
])
OM_CND = op_mod_enum('cnd', [
('always', 'if(1)'),
('p0_true', 'if(p0)'),
('never', 'if(0)'),
('p0_false', 'if(!p0)'),
])
# Ops.
OM_ALU = [OM_OLCHK, OM_EXEC_CND, OM_END, OM_ATOM, OM_RPT]
@ -356,6 +363,12 @@ O_DITRP = hw_op('ditrp', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1
O_DITRP_WRITE = hw_op('ditrp.write', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 4)
O_DITRP_READ = hw_op('ditrp.read', [OM_EXEC_CND, OM_ITR_MODE, OM_SAT, OM_SCHED, OM_F16], 1, 3)
O_CNDST = hw_op('cndst', [OM_EXEC_CND, OM_CND], 2, 2)
O_CNDEF = hw_op('cndef', [OM_EXEC_CND, OM_CND], 2, 2)
O_CNDEND = hw_op('cndend', [OM_EXEC_CND], 2, 2)
O_BR = hw_op('br', [OM_EXEC_CND, OM_BRANCH_CND, OM_LINK], has_target_cf_node=True)
# Combination (> 1 instructions per group).
O_SCMP = hw_op('scmp', OM_ALU + [OM_TST_OP_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])
O_BCMP = hw_op('bcmp', OM_ALU + [OM_TST_OP_MAIN, OM_TST_TYPE_MAIN], 1, 2, [], [[RM_ABS, RM_NEG], [RM_ABS, RM_NEG]])