Implement saturating absolute value, absolute difference, sum-of-absolute-differences, accumulated sum-of-absolute-differences, and comparison and mask-generation operations.Add the associated decode entries, translators and helpers.
Note that the PSABS.* instructions produce results in the signed element domain. Since the absolute value of the minimum signed value cannot be represented in the same element width, saturate it to the maximum signed value and set vxsat. All other values are converted to their absolute values without saturation. Signed-off-by: Molly Chen <[email protected]> --- target/riscv/helper.h | 38 +++++++++ target/riscv/insn32.decode | 44 ++++++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 38 +++++++++ target/riscv/tcg/psimd_helper.c | 95 +++++++++++++++++++++ 4 files changed, 215 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 0b0f5791874..d9ea90a5c2e 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1416,3 +1416,41 @@ DEF_HELPER_3(pasubu_h, tl, env, tl, tl) DEF_HELPER_3(pasubu_w, i64, env, i64, i64) DEF_HELPER_3(asub, i32, env, i32, i32) DEF_HELPER_3(asubu, i32, env, i32, i32) + +/* Packed SIMD - Absolute Value and Difference Operations */ +DEF_HELPER_2(psabs_b, tl, env, tl) +DEF_HELPER_2(psabs_h, tl, env, tl) +DEF_HELPER_2(abs, tl, env, tl) +DEF_HELPER_2(absw, i64, env, i64) +DEF_HELPER_3(pabd_b, tl, env, tl, tl) +DEF_HELPER_3(pabdu_b, tl, env, tl, tl) +DEF_HELPER_3(pabd_h, tl, env, tl, tl) +DEF_HELPER_3(pabdu_h, tl, env, tl, tl) +DEF_HELPER_3(pabdsumu_b, tl, env, tl, tl) +DEF_HELPER_4(pabdsumau_b, tl, env, tl, tl, tl) + +/* Packed SIMD - Comparison and Mask Generation Operations */ +DEF_HELPER_3(pmseq_b, tl, env, tl, tl) +DEF_HELPER_3(pmslt_b, tl, env, tl, tl) +DEF_HELPER_3(pmsltu_b, tl, env, tl, tl) +DEF_HELPER_3(pmin_b, tl, env, tl, tl) +DEF_HELPER_3(pminu_b, tl, env, tl, tl) +DEF_HELPER_3(pmax_b, tl, env, tl, tl) +DEF_HELPER_3(pmaxu_b, tl, env, tl, tl) +DEF_HELPER_3(pmseq_h, tl, env, tl, tl) +DEF_HELPER_3(pmslt_h, tl, env, tl, tl) +DEF_HELPER_3(pmsltu_h, tl, env, tl, tl) +DEF_HELPER_3(pmin_h, tl, env, tl, tl) +DEF_HELPER_3(pminu_h, tl, env, tl, tl) +DEF_HELPER_3(pmax_h, tl, env, tl, tl) +DEF_HELPER_3(pmaxu_h, tl, env, tl, tl) +DEF_HELPER_3(pmseq_w, i64, env, i64, i64) +DEF_HELPER_3(pmslt_w, i64, env, i64, i64) +DEF_HELPER_3(pmsltu_w, i64, env, i64, i64) +DEF_HELPER_3(pmin_w, i64, env, i64, i64) +DEF_HELPER_3(pminu_w, i64, env, i64, i64) +DEF_HELPER_3(pmax_w, i64, env, i64, i64) +DEF_HELPER_3(pmaxu_w, i64, env, i64, i64) +DEF_HELPER_3(mseq, i32, env, i32, i32) +DEF_HELPER_3(mslt, i32, env, i32, i32) +DEF_HELPER_3(msltu, i32, env, i32, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index e06cc82bdef..32eb7b153aa 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1175,3 +1175,47 @@ pasubu_h 1111100 ..... ..... 000 ..... 0111011 @r asubu 1111101 ..... ..... 000 ..... 0111011 @r pasubu_w 1111101 ..... ..... 000 ..... 0111011 @r } + +# Packed SIMD - Absolute Value and Difference Operations +psabs_b 1110010 00111 ..... 010 ..... 0011011 @r2 +psabs_h 1110000 00111 ..... 010 ..... 0011011 @r2 +abs 01100 0000111 ..... 001 ..... 0010011 @r2 +absw 01100 0000111 ..... 001 ..... 0011011 @r2 +pabd_b 1100110 ..... ..... 000 ..... 0111011 @r +pabdu_b 1110110 ..... ..... 000 ..... 0111011 @r +pabd_h 1100100 ..... ..... 000 ..... 0111011 @r +pabdu_h 1110100 ..... ..... 000 ..... 0111011 @r +pabdsumu_b 1011010 ..... ..... 001 ..... 0111011 @r +pabdsumau_b 1011110 ..... ..... 001 ..... 0111011 @r + +# Packed SIMD - Comparison and Mask Generation Operations +pmseq_b 1100010 ..... ..... 110 ..... 0111011 @r +pmslt_b 1101010 ..... ..... 110 ..... 0111011 @r +pmsltu_b 1101110 ..... ..... 110 ..... 0111011 @r +pmin_b 1110010 ..... ..... 110 ..... 0111011 @r +pminu_b 1110110 ..... ..... 110 ..... 0111011 @r +pmax_b 1111010 ..... ..... 110 ..... 0111011 @r +pmaxu_b 1111110 ..... ..... 110 ..... 0111011 @r +pmseq_h 1100000 ..... ..... 110 ..... 0111011 @r +pmslt_h 1101000 ..... ..... 110 ..... 0111011 @r +pmsltu_h 1101100 ..... ..... 110 ..... 0111011 @r +pmin_h 1110000 ..... ..... 110 ..... 0111011 @r +pminu_h 1110100 ..... ..... 110 ..... 0111011 @r +pmax_h 1111000 ..... ..... 110 ..... 0111011 @r +pmaxu_h 1111100 ..... ..... 110 ..... 0111011 @r +{ + mseq 1100001 ..... ..... 110 ..... 0111011 @r + pmseq_w 1100001 ..... ..... 110 ..... 0111011 @r +} +{ + mslt 1101001 ..... ..... 110 ..... 0111011 @r + pmslt_w 1101001 ..... ..... 110 ..... 0111011 @r +} +{ + msltu 1101101 ..... ..... 110 ..... 0111011 @r + pmsltu_w 1101101 ..... ..... 110 ..... 0111011 @r +} +pmin_w 1110001 ..... ..... 110 ..... 0111011 @r +pminu_w 1110101 ..... ..... 110 ..... 0111011 @r +pmax_w 1111001 ..... ..... 110 ..... 0111011 @r +pmaxu_w 1111101 ..... ..... 110 ..... 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 820d11c33b2..81d3f90eb08 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -569,3 +569,41 @@ GEN_SIMD_TRANS(pasubu_h) GEN_SIMD_TRANS_64(pasubu_w) GEN_SIMD_TRANS_32(asub) GEN_SIMD_TRANS_32(asubu) + +/* Packed SIMD - Absolute Value and Difference Operations */ +GEN_SIMD_TRANS_R1_VXSAT(psabs_b) +GEN_SIMD_TRANS_R1_VXSAT(psabs_h) +GEN_SIMD_TRANS_R1(abs) +GEN_SIMD_TRANS_R1_64(absw) +GEN_SIMD_TRANS(pabd_b) +GEN_SIMD_TRANS(pabdu_b) +GEN_SIMD_TRANS(pabd_h) +GEN_SIMD_TRANS(pabdu_h) +GEN_SIMD_TRANS(pabdsumu_b) +GEN_SIMD_TRANS_ACC(pabdsumau_b) + +/* Packed SIMD - Comparison and Mask Generation Operations */ +GEN_SIMD_TRANS(pmseq_b) +GEN_SIMD_TRANS(pmslt_b) +GEN_SIMD_TRANS(pmsltu_b) +GEN_SIMD_TRANS(pmin_b) +GEN_SIMD_TRANS(pminu_b) +GEN_SIMD_TRANS(pmax_b) +GEN_SIMD_TRANS(pmaxu_b) +GEN_SIMD_TRANS(pmseq_h) +GEN_SIMD_TRANS(pmslt_h) +GEN_SIMD_TRANS(pmsltu_h) +GEN_SIMD_TRANS(pmin_h) +GEN_SIMD_TRANS(pminu_h) +GEN_SIMD_TRANS(pmax_h) +GEN_SIMD_TRANS(pmaxu_h) +GEN_SIMD_TRANS_64(pmseq_w) +GEN_SIMD_TRANS_64(pmslt_w) +GEN_SIMD_TRANS_64(pmsltu_w) +GEN_SIMD_TRANS_64(pmin_w) +GEN_SIMD_TRANS_64(pminu_w) +GEN_SIMD_TRANS_64(pmax_w) +GEN_SIMD_TRANS_64(pmaxu_w) +GEN_SIMD_TRANS_32(mseq) +GEN_SIMD_TRANS_32(mslt) +GEN_SIMD_TRANS_32(msltu) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c index e2796230710..625928dc1dd 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2200,3 +2200,98 @@ GEN_PSIMD_AVG_BINOP(asub, uint32_t, int32_t, int64_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) GEN_PSIMD_AVG_BINOP(asubu, uint32_t, uint32_t, uint64_t, EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB) + +/* Absolute value operations */ + +GEN_PSIMD_ABS(psabs_b, target_ulong, int8_t, + EXTRACT8, INSERT8, ELEMS_B, INT8_MIN, INT8_MAX) +GEN_PSIMD_ABS(psabs_h, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, INT16_MIN, INT16_MAX) + +GEN_PSIMD_SCALAR_ABS(abs, target_ulong, target_long, target_ulong) +GEN_PSIMD_SCALAR_ABS(absw, uint64_t, int32_t, uint32_t) + +/* Absolute difference operations */ + +GEN_PSIMD_BINOP(pabd_b, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabdu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabd_h, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ABD) +GEN_PSIMD_BINOP(pabdu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ABD) + +/** + * PABDSUMU.B - Sum of unsigned absolute differences + * Returns sum(|rs1[i] - rs2[i]|) for all bytes + */ +target_ulong HELPER(pabdsumu_b)(CPURISCVState *env, + target_ulong rs1, target_ulong rs2) +{ + return psimd_abdsumu_b(rs1, rs2, 0); +} + +/** + * PABDSUMAU.B - Accumulated sum of unsigned absolute differences + * rd = rd + sum(|rs1[i] - rs2[i]|) + */ +target_ulong HELPER(pabdsumau_b)(CPURISCVState *env, target_ulong rs1, + target_ulong rs2, target_ulong rd) +{ + return psimd_abdsumu_b(rs1, rs2, rd); +} + +/* Comparison operations (producing masks) */ + +GEN_PSIMD_BINOP(pmseq_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_b, target_ulong, int8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_b, target_ulong, int8_t, int8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_b, target_ulong, int8_t, int8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_b, target_ulong, uint8_t, uint8_t, + EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(pmseq_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_h, target_ulong, int16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_h, target_ulong, int16_t, int16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_h, target_ulong, int16_t, int16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_h, target_ulong, uint16_t, uint16_t, + EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(pmseq_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(pmslt_w, uint64_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmsltu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(pmin_w, uint64_t, int32_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pminu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MIN) +GEN_PSIMD_BINOP(pmax_w, uint64_t, int32_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MAX) +GEN_PSIMD_BINOP(pmaxu_w, uint64_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_MAX) + +GEN_PSIMD_BINOP(mseq, uint32_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_EQ_MASK) +GEN_PSIMD_BINOP(mslt, uint32_t, int32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) +GEN_PSIMD_BINOP(msltu, uint32_t, uint32_t, uint32_t, + EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK) -- 2.34.1
