diff --git a/src/imagination/pco/pco_map.py b/src/imagination/pco/pco_map.py index 573e54802b1..edc314c7000 100644 --- a/src/imagination/pco/pco_map.py +++ b/src/imagination/pco/pco_map.py @@ -242,6 +242,14 @@ enum_map(OM_LOGIOP.t, F_LOGICAL_OP, [ ('xnor', 'xnor'), ]) +enum_map(OM_SHIFTOP.t, F_SHIFT2_OP, [ + ('lsl', 'lsl'), + ('shr', 'shr'), + ('rol', 'rol'), + ('cps', 'cps'), + ('asr', 'asr_twb'), +]) + enum_map(RM_ELEM.t, F_UPCK_ELEM, [ ('e0', 'e0'), ('e1', 'e1'), @@ -1049,6 +1057,18 @@ encode_map(O_LOGICAL, op_ref_maps=[('1', ['ft4'], ['ft2', 's3'])] ) +encode_map(O_SHIFT, + encodings=[ + (I_PHASE2, [ + ('pwen', False), + ('tst_src', 0), + ('bw_tst_op', 0), + ('shift2_op', OM_SHIFTOP), + ]) + ], + op_ref_maps=[('2', ['ft5'], ['ft4', 's4', ['_', 'p0']])] +) + encode_map(O_WOP, encodings=[(I_WOP, [])], op_ref_maps=[('ctrl', [], [])]) encode_map(O_WDF, encodings=[(I_WDF, [])], op_ref_maps=[('ctrl', [], ['drc'])]) encode_map(O_NOP, encodings=[(I_NOP, [])], op_ref_maps=[('ctrl', [], [])]) @@ -1609,6 +1629,28 @@ group_map(O_LOGICAL, dests=[('w[0]', ('1', DEST(0)), 'ft4')] ) +group_map(O_SHIFT, + hdr=(I_IGRP_HDR_BITWISE, [ + ('opcnt', ['p0', '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_BBYP0BM, ['ft0', 'ft1'], ['s0', SRC(0)]), + ('2', O_SHIFT, [DEST(0)], ['ft4', SRC(1), SRC(2)], [(OM_SHIFTOP, OM_SHIFTOP)]) + ], + srcs=[ + ('s[1]', ('0', SRC(1)), 's1'), + ('s[4]', ('2', SRC(1)), 's4') + ], + dests=[('w[0]', ('2', DEST(0)), 'ft5')] +) + group_map(O_WOP, hdr=(I_IGRP_HDR_CONTROL, [ ('olchk', False), diff --git a/src/imagination/pco/pco_ops.py b/src/imagination/pco/pco_ops.py index d688f365246..8930ad90f42 100644 --- a/src/imagination/pco/pco_ops.py +++ b/src/imagination/pco/pco_ops.py @@ -284,6 +284,15 @@ OM_LOGIOP = op_mod_enum('logiop', [ 'nand', 'xnor', ]) + +OM_SHIFTOP = op_mod_enum('shiftop', [ + 'lsl', + 'shr', + 'rol', + 'cps', + 'asr', +]) + # Ops. OM_ALU = [OM_OLCHK, OM_EXEC_CND, OM_END, OM_ATOM, OM_RPT] @@ -324,6 +333,7 @@ O_LD = hw_op('ld', OM_ALU_RPT1 + [OM_MCU_CACHE_MODE_LD], 1, 3) O_MOVI32 = hw_op('movi32', OM_ALU, 1, 1) O_LOGICAL = hw_op('logical', OM_ALU + [OM_LOGIOP], 1, 2) +O_SHIFT = hw_op('shift', OM_ALU + [OM_SHIFTOP], 1, 3) O_BBYP0BM = hw_direct_op('bbyp0bm', [], 2, 2) O_BBYP0BM_IMM32 = hw_direct_op('bbyp0bm_imm32', [], 2, 2) diff --git a/src/imagination/pco/pco_trans_nir.c b/src/imagination/pco/pco_trans_nir.c index 62618e6145b..82e91fd7f5a 100644 --- a/src/imagination/pco/pco_trans_nir.c +++ b/src/imagination/pco/pco_trans_nir.c @@ -880,6 +880,49 @@ static pco_instr *trans_logical(trans_ctx *tctx, return pco_logical(&tctx->b, dest, src0, src1, .logiop = logiop); } +/** + * \brief Translates a NIR shift op into PCO. + * + * \param[in,out] tctx Translation context. + * \param[in] op The NIR op. + * \param[in] src Instruction source. + * \return The translated PCO instruction. + */ +static pco_instr *trans_shift(trans_ctx *tctx, + nir_op op, + pco_ref dest, + pco_ref src0, + pco_ref src1) +{ + ASSERTED unsigned bits = pco_ref_get_bits(dest); + assert(bits == 32); + + enum pco_shiftop shiftop; + switch (op) { + case nir_op_ishl: + shiftop = PCO_SHIFTOP_LSL; + break; + + case nir_op_ishr: + shiftop = PCO_SHIFTOP_ASR; + break; + + case nir_op_ushr: + shiftop = PCO_SHIFTOP_SHR; + break; + + default: + UNREACHABLE(""); + } + + return pco_shift(&tctx->b, + dest, + src0, + src1, + pco_ref_null(), + .shiftop = shiftop); +} + static inline bool is_min(nir_op op) { switch (op) { @@ -1007,6 +1050,12 @@ static pco_instr *trans_alu(trans_ctx *tctx, nir_alu_instr *alu) instr = trans_logical(tctx, alu->op, dest, src[0], src[1]); break; + case nir_op_ishl: + case nir_op_ishr: + case nir_op_ushr: + instr = trans_shift(tctx, alu->op, dest, src[0], src[1]); + break; + case nir_op_f2i32: instr = pco_pck(&tctx->b, dest,