pco, pygen: add support for tst, movc instructions and s{lt,ge,eq,ne} ops

Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Acked-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33998>
This commit is contained in:
Simon Perretta 2024-11-30 11:42:15 +00:00 committed by Marge Bot
parent f1b63fe3f9
commit ff51ba7e43
5 changed files with 200 additions and 0 deletions

View file

@ -1434,6 +1434,38 @@ static inline enum pco_io pco_ref_get_io(pco_ref ref)
return ref.val;
}
/**
* \brief Returns the movw01 value of an I/O reference type.
*
* \param[in] ref Reference.
* \return movw01 value.
*/
static inline enum pco_movw01 pco_ref_get_movw01(pco_ref ref)
{
/* Default/unused case. */
if (pco_ref_is_null(ref))
return PCO_MOVW01_FT0;
switch (pco_ref_get_io(ref)) {
case PCO_IO_FT0:
return PCO_MOVW01_FT0;
case PCO_IO_FT1:
return PCO_MOVW01_FT1;
case PCO_IO_FT2:
return PCO_MOVW01_FT2;
case PCO_IO_FTE:
return PCO_MOVW01_FTE;
default:
break;
}
unreachable();
}
/**
* \brief Returns the predicate from its reference type.
*

View file

@ -163,6 +163,36 @@ enum_map(OM_SCHED.t, F_SCHED_CTRL, [
('wdf', 'wdf'),
])
enum_map(OM_TST_OP_MAIN.t, F_TST_OP, [
('zero', 'z'),
('gzero', 'gz'),
('gezero', 'gez'),
('carry', 'c'),
('equal', 'e'),
('greater', 'g'),
('gequal', 'ge'),
('notequal', 'ne'),
('less', 'l'),
('lequal', 'le'),
])
enum_map(OM_TST_TYPE_MAIN.t, F_TST_TYPE, [
('f32', 'f32'),
('u16', 'u16'),
('s16', 's16'),
('u8', 'u8'),
('s8', 's8'),
('u32', 'u32'),
('s32', 's32'),
])
enum_map(RM_ELEM.t, F_MASKW0, [
('e0', 'e0'),
('e1', 'e1'),
('e2', 'e2'),
('e3', 'e3'),
], pass_zero=['e0', 'e1', 'e2', 'e3'])
encode_maps = {}
group_maps = {}
@ -598,6 +628,48 @@ encode_map(O_PCK,
]
)
encode_map(O_TST,
encodings=[
(I_TST_EXT, [
('tst_op', OM_TST_OP_MAIN),
('pwen', ('!pco_ref_is_null', 'dest[1]')),
('type', OM_TST_TYPE_MAIN),
('p2end', OM_PHASE2END),
('elem', (RM_ELEM, 'src[0]'))
]),
(I_TST, [
('tst_op', OM_TST_OP_MAIN),
('pwen', ('!pco_ref_is_null', 'dest[1]')),
], [
(OM_TST_OP_MAIN, '<= PCO_TST_OP_MAIN_NOTEQUAL'),
(OM_TST_TYPE_MAIN, '== PCO_TST_TYPE_MAIN_F32'),
(OM_PHASE2END, '== false'),
(OM_TST_TYPE_MAIN, '== PCO_TST_TYPE_MAIN_F32'),
(RM_ELEM, 'src[0]', '== 0'),
(RM_ELEM, 'src[1]', '== 0'),
])
]
)
encode_map(O_MOVC,
encodings=[
(I_MOVC_EXT, [
('movw0', ('pco_ref_get_movw01', 'src[1]')),
('movw1', ('pco_ref_get_movw01', 'src[3]')),
('maskw0', (RM_ELEM, 'dest[0]')),
('aw', False),
('p2end', OM_PHASE2END)
]),
(I_MOVC, [
('movw0', ('pco_ref_get_movw01', 'src[1]')),
('movw1', ('pco_ref_get_movw01', 'src[3]')),
], [
(RM_ELEM, 'dest[0]', '== 0b1111'),
(OM_PHASE2END, '== false'),
])
]
)
encode_map(O_UVSW_WRITE,
encodings=[
(I_UVSW_WRITE_IMM, [
@ -822,6 +894,40 @@ group_map(O_PCK,
dests=[('w[0]', ('2_pck', 'dest[0]'), 'ft2')]
)
group_map(O_SCMP,
hdr=(I_IGRP_HDR_MAIN, [
('oporg', 'p0_p1_p2'),
('olchk', OM_OLCHK),
('w1p', False),
('w0p', True),
('cc', OM_EXEC_CND),
('end', OM_END),
('atom', OM_ATOM),
('rpt', OM_RPT)
]),
enc_ops=[
('0', O_MBYP, ['ft0'], ['src[0]']),
('1', O_MBYP, ['ft1'], ['src[1]']),
('2_tst', O_TST, ['ftt', '_'], ['is1', 'is2'], [(OM_TST_OP_MAIN, OM_TST_OP_MAIN), (OM_TST_TYPE_MAIN, 'f32')]),
('2_pck', O_PCK, ['ft2'], ['_'], [(OM_PCK_FMT, 'one')]),
('2_mov', O_MOVC, ['dest[0]', '_'], ['ftt', 'ft2', 'is4', '_', '_'])
],
srcs=[
('s[0]', ('0', 'src[0]'), 's0'),
('s[1]', 'pco_zero'),
('s[3]', ('1', 'src[0]'), 's3'),
],
iss=[
('is[0]', 's1'),
('is[1]', 'ft0'),
('is[2]', 'ft1'),
('is[4]', 'fte'),
],
dests=[
('w[0]', ('2_mov', 'dest[0]'), 'w0'),
]
)
group_map(O_UVSW_WRITE,
hdr=(I_IGRP_HDR_MAIN, [
('oporg', 'be'),

View file

@ -25,6 +25,8 @@ static const struct spirv_to_nir_options pco_base_spirv_options = {
static const nir_shader_compiler_options pco_base_nir_options = {
.fuse_ffma32 = true,
.has_fused_comp_and_csel = true,
.lower_fdiv = true,
.lower_fquantize2f16 = true,
.lower_layer_fs_input_to_sysval = true,

View file

@ -141,6 +141,15 @@ OM_LP = op_mod('lp', BaseType.bool)
OM_SCALE = op_mod('scale', BaseType.bool)
OM_ROUNDZERO = op_mod('roundzero', BaseType.bool)
OM_S = op_mod('s', BaseType.bool)
OM_TST_TYPE_MAIN = op_mod_enum('tst_type_main', [
'f32',
'u16',
's16',
'u8',
's8',
'u32',
's32',
])
OM_TST_OP_MAIN = op_mod_enum('tst_op_main', [
('zero', 'z'),
('gzero', 'gz'),
@ -281,6 +290,9 @@ O_FRCP = hw_op('frcp', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
O_MBYP = hw_op('mbyp', OM_ALU, 1, 1, [], [[RM_ABS, RM_NEG]])
O_PCK = hw_op('pck', OM_ALU + [OM_PCK_FMT, OM_ROUNDZERO, OM_SCALE], 1, 1)
O_TST = hw_direct_op('tst', [OM_TST_OP_MAIN, OM_PHASE2END, OM_TST_TYPE_MAIN], 2, 2, [], [[RM_ELEM], [RM_ELEM]])
O_MOVC = hw_direct_op('movc', [OM_PHASE2END], 2, 5, [[RM_ELEM]])
# TODO
# O_PCK_ELEM = pseudo_op('pck.elem', OM_ALU_RPT1 + [OM_PCK_FMT, OM_ROUNDZERO, OM_SCALE], 1, 2)
@ -310,6 +322,9 @@ 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)
# 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]])
# Pseudo-ops (unmapped).
O_NEG = pseudo_op('neg', OM_ALU, 1, 1)
O_ABS = pseudo_op('abs', OM_ALU, 1, 1)

View file

@ -603,6 +603,44 @@ static pco_instr *pco_trans_nir_vec(trans_ctx *tctx,
return instr;
}
/**
* \brief Translates a NIR float set-on comparison into PCO.
*
* \param[in,out] tctx Translation context.
* \param[in] op The NIR op.
* \param[in] dest Instruction destination.
* \param[in] src0 First comparison source.
* \param[in] src1 Second comparison source.
* \return The translated PCO instruction.
*/
static pco_instr *
trans_scmp(trans_ctx *tctx, nir_op op, pco_ref dest, pco_ref src0, pco_ref src1)
{
enum pco_tst_op_main tst_op_main;
switch (op) {
case nir_op_slt:
tst_op_main = PCO_TST_OP_MAIN_LESS;
break;
case nir_op_sge:
tst_op_main = PCO_TST_OP_MAIN_GEQUAL;
break;
case nir_op_seq:
tst_op_main = PCO_TST_OP_MAIN_EQUAL;
break;
case nir_op_sne:
tst_op_main = PCO_TST_OP_MAIN_NOTEQUAL;
break;
default:
unreachable();
}
return pco_scmp(&tctx->b, dest, src0, src1, .tst_op_main = tst_op_main);
}
/**
* \brief Translates a NIR alu instruction into PCO.
*
@ -651,6 +689,13 @@ static pco_instr *trans_alu(trans_ctx *tctx, nir_alu_instr *alu)
instr = pco_frcp(&tctx->b, dest, src[0]);
break;
case nir_op_slt:
case nir_op_sge:
case nir_op_seq:
case nir_op_sne:
instr = trans_scmp(tctx, alu->op, dest, src[0], src[1]);
break;
case nir_op_pack_unorm_4x8:
instr = pco_pck(&tctx->b,
dest,