Implement Q-format horizontal multiply-add and PM2 horizontal multiply-add/subtract operations. Cover signed, unsigned, mixed-sign, corresponding and crossed element pairing, accumulating and non-accumulating, and rounded and non-rounded variants. Add the associated decode entries, translators and helpers.
These instructions combine two products from each packed element group using addition or subtraction. Q-format variants discard the low fractional bits of each product, while rounded variants add the required rounding value before extraction. Accumulating variants add the combined result to the corresponding element of rd. Note that PM2SADD.H and PM2SADD.HX clamp out-of-range sums to the signed destination range and set vxsat; the other operations wrap to the destination width and do not affect vxsat. Signed-off-by: Molly Chen <[email protected]> --- target/riscv/helper.h | 36 ++++++ target/riscv/insn32.decode | 36 ++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 36 ++++++ target/riscv/tcg/psimd_helper.c | 119 ++++++++++++++++++++ 4 files changed, 227 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 7a052991ad1..5e33026bcb0 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1705,3 +1705,39 @@ DEF_HELPER_4(pmqacc_w_h11, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h00, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h01, i64, env, i64, i64, i64) DEF_HELPER_4(pmqracc_w_h11, i64, env, i64, i64, i64) + +/* Packed SIMD - Two-Way Multiply and Accumulate Operations */ +DEF_HELPER_3(pmq2add_h, tl, env, tl, tl) +DEF_HELPER_3(pmqr2add_h, tl, env, tl, tl) +DEF_HELPER_4(pmq2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pmqr2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_3(pmq2add_w, i64, env, i64, i64) +DEF_HELPER_3(pmqr2add_w, i64, env, i64, i64) +DEF_HELPER_4(pmq2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pmqr2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_3(pm2add_h, tl, env, tl, tl) +DEF_HELPER_3(pm2addsu_h, tl, env, tl, tl) +DEF_HELPER_3(pm2addu_h, tl, env, tl, tl) +DEF_HELPER_3(pm2add_hx, tl, env, tl, tl) +DEF_HELPER_3(pm2sub_h, tl, env, tl, tl) +DEF_HELPER_3(pm2sub_hx, tl, env, tl, tl) +DEF_HELPER_3(pm2sadd_h, tl, env, tl, tl) +DEF_HELPER_3(pm2sadd_hx, tl, env, tl, tl) +DEF_HELPER_4(pm2adda_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2addasu_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2addau_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2adda_hx, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2suba_h, tl, env, tl, tl, tl) +DEF_HELPER_4(pm2suba_hx, tl, env, tl, tl, tl) +DEF_HELPER_3(pm2add_w, i64, env, i64, i64) +DEF_HELPER_3(pm2addsu_w, i64, env, i64, i64) +DEF_HELPER_3(pm2addu_w, i64, env, i64, i64) +DEF_HELPER_3(pm2add_wx, i64, env, i64, i64) +DEF_HELPER_3(pm2sub_w, i64, env, i64, i64) +DEF_HELPER_3(pm2sub_wx, i64, env, i64, i64) +DEF_HELPER_4(pm2adda_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2addasu_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2addau_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2adda_wx, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2suba_w, i64, env, i64, i64, i64) +DEF_HELPER_4(pm2suba_wx, i64, env, i64, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 3d9e79de58f..263e02ef903 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1567,3 +1567,39 @@ mqacc_w11 11111 01 ..... ..... 111 ..... 0111011 @r mqracc_w00 11101 11 ..... ..... 111 ..... 0111011 @r mqracc_w01 11111 11 ..... ..... 101 ..... 0111011 @r mqracc_w11 11111 11 ..... ..... 111 ..... 0111011 @r + +# Packed SIMD - Two-Way Multiply and Accumulate Operations +pmq2add_h 10110 00 ..... ..... 101 ..... 0111011 @r +pmqr2add_h 10110 10 ..... ..... 101 ..... 0111011 @r +pmq2adda_h 10111 00 ..... ..... 101 ..... 0111011 @r +pmqr2adda_h 10111 10 ..... ..... 101 ..... 0111011 @r +pmq2add_w 10110 01 ..... ..... 101 ..... 0111011 @r +pmqr2add_w 10110 11 ..... ..... 101 ..... 0111011 @r +pmq2adda_w 10111 01 ..... ..... 101 ..... 0111011 @r +pmqr2adda_w 10111 11 ..... ..... 101 ..... 0111011 @r +pm2add_h 10000 00 ..... ..... 101 ..... 0111011 @r +pm2addsu_h 11100 00 ..... ..... 101 ..... 0111011 @r +pm2addu_h 10100 00 ..... ..... 101 ..... 0111011 @r +pm2add_hx 10010 00 ..... ..... 101 ..... 0111011 @r +pm2sub_h 11000 00 ..... ..... 101 ..... 0111011 @r +pm2sub_hx 11010 00 ..... ..... 101 ..... 0111011 @r +pm2sadd_h 11000 10 ..... ..... 101 ..... 0111011 @r +pm2sadd_hx 11010 10 ..... ..... 101 ..... 0111011 @r +pm2adda_h 10001 00 ..... ..... 101 ..... 0111011 @r +pm2addasu_h 11101 00 ..... ..... 101 ..... 0111011 @r +pm2addau_h 10101 00 ..... ..... 101 ..... 0111011 @r +pm2adda_hx 10011 00 ..... ..... 101 ..... 0111011 @r +pm2suba_h 11001 00 ..... ..... 101 ..... 0111011 @r +pm2suba_hx 11011 00 ..... ..... 101 ..... 0111011 @r +pm2add_w 10000 01 ..... ..... 101 ..... 0111011 @r +pm2addsu_w 11100 01 ..... ..... 101 ..... 0111011 @r +pm2addu_w 10100 01 ..... ..... 101 ..... 0111011 @r +pm2add_wx 10010 01 ..... ..... 101 ..... 0111011 @r +pm2sub_w 11000 01 ..... ..... 101 ..... 0111011 @r +pm2sub_wx 11010 01 ..... ..... 101 ..... 0111011 @r +pm2adda_w 10001 01 ..... ..... 101 ..... 0111011 @r +pm2addasu_w 11101 01 ..... ..... 101 ..... 0111011 @r +pm2addau_w 10101 01 ..... ..... 101 ..... 0111011 @r +pm2adda_wx 10011 01 ..... ..... 101 ..... 0111011 @r +pm2suba_w 11001 01 ..... ..... 101 ..... 0111011 @r +pm2suba_wx 11011 01 ..... ..... 101 ..... 0111011 @r diff --git a/target/riscv/tcg/insn_trans/trans_rvp.c.inc b/target/riscv/tcg/insn_trans/trans_rvp.c.inc index ef3c5b00a3a..65647fd61eb 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -874,3 +874,39 @@ GEN_SIMD_TRANS_ACC_64(pmqacc_w_h11) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h00) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h01) GEN_SIMD_TRANS_ACC_64(pmqracc_w_h11) + +/* Packed SIMD - Two-Way Multiply and Accumulate Operations */ +GEN_SIMD_TRANS(pmq2add_h) +GEN_SIMD_TRANS(pmqr2add_h) +GEN_SIMD_TRANS_ACC(pmq2adda_h) +GEN_SIMD_TRANS_ACC(pmqr2adda_h) +GEN_SIMD_TRANS_64(pmq2add_w) +GEN_SIMD_TRANS_64(pmqr2add_w) +GEN_SIMD_TRANS_ACC_64(pmq2adda_w) +GEN_SIMD_TRANS_ACC_64(pmqr2adda_w) +GEN_SIMD_TRANS(pm2add_h) +GEN_SIMD_TRANS(pm2addsu_h) +GEN_SIMD_TRANS(pm2addu_h) +GEN_SIMD_TRANS(pm2add_hx) +GEN_SIMD_TRANS(pm2sub_h) +GEN_SIMD_TRANS(pm2sub_hx) +GEN_SIMD_TRANS_VXSAT(pm2sadd_h) +GEN_SIMD_TRANS_VXSAT(pm2sadd_hx) +GEN_SIMD_TRANS_ACC(pm2adda_h) +GEN_SIMD_TRANS_ACC(pm2addasu_h) +GEN_SIMD_TRANS_ACC(pm2addau_h) +GEN_SIMD_TRANS_ACC(pm2adda_hx) +GEN_SIMD_TRANS_ACC(pm2suba_h) +GEN_SIMD_TRANS_ACC(pm2suba_hx) +GEN_SIMD_TRANS_64(pm2add_w) +GEN_SIMD_TRANS_64(pm2addsu_w) +GEN_SIMD_TRANS_64(pm2addu_w) +GEN_SIMD_TRANS_64(pm2add_wx) +GEN_SIMD_TRANS_64(pm2sub_w) +GEN_SIMD_TRANS_64(pm2sub_wx) +GEN_SIMD_TRANS_ACC_64(pm2adda_w) +GEN_SIMD_TRANS_ACC_64(pm2addasu_w) +GEN_SIMD_TRANS_ACC_64(pm2addau_w) +GEN_SIMD_TRANS_ACC_64(pm2adda_wx) +GEN_SIMD_TRANS_ACC_64(pm2suba_w) +GEN_SIMD_TRANS_ACC_64(pm2suba_wx) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c index feb93561e60..639557351da 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3101,3 +3101,122 @@ GEN_PSIMD_QMUL_ACC_INDEXED(pmqracc_w_h11, uint64_t, int16_t, int16_t, int32_t, int64_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, ELEMS_W, 2, 1, 1, 15, 1LL << 14, PSIMD_MUL_S64) + +/* Two-Way Multiply and Accumulate Operations */ + +GEN_PSIMD_Q2ADD(pmq2add_h, target_ulong, int16_t, int32_t, int64_t, + uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, 15, 0, + PSIMD_MUL_S32) +GEN_PSIMD_Q2ADD(pmqr2add_h, target_ulong, int16_t, int32_t, int64_t, + uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, 15, 1LL << 14, + PSIMD_MUL_S32) +GEN_PSIMD_Q2ADDA(pmq2adda_h, target_ulong, int16_t, int32_t, int32_t, + int64_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, + ELEMS_W, 2, 15, 0, PSIMD_MUL_S32) +GEN_PSIMD_Q2ADDA(pmqr2adda_h, target_ulong, int16_t, int32_t, int32_t, + int64_t, uint32_t, EXTRACT16, EXTRACT32, INSERT32, + ELEMS_W, 2, 15, 1LL << 14, PSIMD_MUL_S32) + +GEN_PSIMD_Q2ADD(pmq2add_w, uint64_t, int32_t, int64_t, int64_t, + uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, 31, 0, + PSIMD_MUL_S64) +GEN_PSIMD_Q2ADD(pmqr2add_w, uint64_t, int32_t, int64_t, int64_t, + uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, 31, 1LL << 30, + PSIMD_MUL_S64) +GEN_PSIMD_Q2ADDA(pmq2adda_w, uint64_t, int32_t, int64_t, int64_t, + int64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, + ELEMS_D, 0, 31, 0, PSIMD_MUL_S64) +GEN_PSIMD_Q2ADDA(pmqr2adda_w, uint64_t, int32_t, int64_t, int64_t, + int64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, + ELEMS_D, 0, 31, 1LL << 30, PSIMD_MUL_S64) + +GEN_PSIMD_2WAY_MUL(pm2add_h, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_S32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addsu_h, target_ulong, int16_t, uint16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_SU32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addu_h, target_ulong, uint16_t, uint16_t, + uint32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_U32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2add_hx, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 1, 0, PSIMD_MUL_S32, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2sub_h, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 0, 1, PSIMD_MUL_S32, PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL(pm2sub_hx, target_ulong, int16_t, int16_t, + int32_t, uint32_t, EXTRACT16, INSERT32, ELEMS_W, 2, + 0, 1, 1, 0, PSIMD_MUL_S32, PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_SAT_MUL(pm2sadd_h, 0, 1, 0, 1) +GEN_PSIMD_2WAY_SAT_MUL(pm2sadd_hx, 0, 1, 1, 0) + +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_h, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_S32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addasu_h, target_ulong, int16_t, uint16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_SU32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addau_h, target_ulong, uint16_t, uint16_t, + uint32_t, uint32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_U32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_hx, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 1, 0, PSIMD_MUL_S32, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_h, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 0, 1, PSIMD_MUL_S32, + PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_hx, target_ulong, int16_t, int16_t, + int32_t, int32_t, uint32_t, EXTRACT16, EXTRACT32, + INSERT32, ELEMS_W, 2, 0, 1, 1, 0, PSIMD_MUL_S32, + PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_MUL(pm2add_w, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addsu_w, uint64_t, int32_t, uint32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_SU64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2addu_w, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_U64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2add_wx, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL(pm2sub_w, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 0, 1, PSIMD_MUL_S64, PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL(pm2sub_wx, uint64_t, int32_t, int32_t, + int64_t, uint64_t, EXTRACT32, INSERT64, ELEMS_D, 0, + 0, 1, 1, 0, PSIMD_MUL_S64, PSIMD_COMB_SUB) + +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_w, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addasu_w, uint64_t, int32_t, uint32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_SU64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2addau_w, uint64_t, uint32_t, uint32_t, + uint64_t, uint64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_U64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2adda_wx, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_ADD) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_w, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 0, 1, PSIMD_MUL_S64, + PSIMD_COMB_SUB) +GEN_PSIMD_2WAY_MUL_ACC(pm2suba_wx, uint64_t, int32_t, int32_t, + int64_t, int64_t, uint64_t, EXTRACT32, EXTRACT64, + INSERT64, ELEMS_D, 0, 0, 1, 1, 0, PSIMD_MUL_S64, + PSIMD_COMB_SUB) -- 2.34.1
