Implement Q-format multiplication operations. Cover packed halfword and word elements, RV32 scalar forms, and rounded and non-rounded variants. Add the associated decode entries, translators and helpers.
Note that these instructions double each signed full-width product and extract a result in the original element width. Rounded variants add the required rounding value before extracting the result. When both source elements are the minimum signed value, the Q-format product cannot be represented in the signed destination range, so saturate it to the maximum signed value and set vxsat. Signed-off-by: Molly Chen <[email protected]> --- target/riscv/helper.h | 8 ++++++++ target/riscv/insn32.decode | 12 ++++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 8 ++++++++ target/riscv/tcg/psimd_helper.c | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index e90e01373ed..40cb4f3825e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1677,3 +1677,11 @@ DEF_HELPER_4(maccsu_w11, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w00, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w01, i64, env, i64, i64, i64) DEF_HELPER_4(maccu_w11, i64, env, i64, i64, i64) + +/* Packed SIMD - Q-Format Multiplication Operations */ +DEF_HELPER_3(pmulq_h, tl, env, tl, tl) +DEF_HELPER_3(pmulqr_h, tl, env, tl, tl) +DEF_HELPER_3(pmulq_w, i64, env, i64, i64) +DEF_HELPER_3(pmulqr_w, i64, env, i64, i64) +DEF_HELPER_3(mulq, i32, env, i32, i32) +DEF_HELPER_3(mulqr, i32, env, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 2bf26ec1563..6f9c40f2db7 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1523,3 +1523,15 @@ maccsu_w11 11111 11 ..... ..... 011 ..... 0111011 @r maccu_w00 10101 11 ..... ..... 011 ..... 0111011 @r maccu_w01 10111 11 ..... ..... 001 ..... 0111011 @r maccu_w11 10111 11 ..... ..... 011 ..... 0111011 @r + +# Packed SIMD - Q-Format Multiplication Operations +pmulq_h 11010 00 ..... ..... 111 ..... 0111011 @r +pmulqr_h 11010 10 ..... ..... 111 ..... 0111011 @r +{ + mulq 11010 01 ..... ..... 111 ..... 0111011 @r + pmulq_w 11010 01 ..... ..... 111 ..... 0111011 @r +} +{ + mulqr 11010 11 ..... ..... 111 ..... 0111011 @r + pmulqr_w 11010 11 ..... ..... 111 ..... 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 5aaa3c6ffa5..5eff8031885 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -846,3 +846,11 @@ GEN_SIMD_TRANS_ACC_64(maccsu_w11) GEN_SIMD_TRANS_ACC_64(maccu_w00) GEN_SIMD_TRANS_ACC_64(maccu_w01) GEN_SIMD_TRANS_ACC_64(maccu_w11) + +/* Packed SIMD - Q-Format Multiplication Operations */ +GEN_SIMD_TRANS_VXSAT(pmulq_h) +GEN_SIMD_TRANS_VXSAT(pmulqr_h) +GEN_SIMD_TRANS_64_VXSAT(pmulq_w) +GEN_SIMD_TRANS_64_VXSAT(pmulqr_w) +GEN_SIMD_TRANS_32_VXSAT(mulq) +GEN_SIMD_TRANS_32_VXSAT(mulqr) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c index b9bb7d497fc..52df992b462 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -3005,3 +3005,21 @@ GEN_PSIMD_MUL_ACC_INDEXED(maccu_w11, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t, uint64_t, EXTRACT32, EXTRACT64, INSERT64, ELEMS_D, 0, 1, 1, PSIMD_MUL_U64) + +/* Q-Format Multiplication Operations */ + +GEN_PSIMD_QMUL(pmulq_h, target_ulong, int16_t, int32_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 15, 0, INT16_MIN, INT16_MAX) +GEN_PSIMD_QMUL(pmulqr_h, target_ulong, int16_t, int32_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, 15, 1 << 14, INT16_MIN, + INT16_MAX) +GEN_PSIMD_QMUL(pmulq_w, uint64_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 0, INT32_MIN, INT32_MAX) +GEN_PSIMD_QMUL(pmulqr_w, uint64_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 1LL << 30, INT32_MIN, + INT32_MAX) +GEN_PSIMD_QMUL(mulq, uint32_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 0, INT32_MIN, INT32_MAX) +GEN_PSIMD_QMUL(mulqr, uint32_t, int32_t, int64_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, 31, 1LL << 30, INT32_MIN, + INT32_MAX) -- 2.34.1
