target/riscv/helper.h | 18 ++++++++++
target/riscv/insn32.decode | 26 ++++++++++++++
target/riscv/tcg/insn_trans/trans_rvp.c.inc | 18 ++++++++++
target/riscv/tcg/psimd_helper.c | 40 +++++++++++++++++++++
4 files changed, 102 insertions(+)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index eebb2febd95..7256f776ae6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1399,3 +1399,21 @@ DEF_HELPER_3(sati_32, i32, env, i32, i32)
DEF_HELPER_3(usati_32, i32, env, i32, i32)
DEF_HELPER_3(sati_64, i64, env, i64, i64)
DEF_HELPER_3(usati_64, i64, env, i64, i64)
+
+/* Packed SIMD - Averaging and Rounding Operations */
+DEF_HELPER_3(paadd_b, tl, env, tl, tl)
+DEF_HELPER_3(paadd_h, tl, env, tl, tl)
+DEF_HELPER_3(paadd_w, i64, env, i64, i64)
+DEF_HELPER_3(paaddu_b, tl, env, tl, tl)
+DEF_HELPER_3(paaddu_h, tl, env, tl, tl)
+DEF_HELPER_3(paaddu_w, i64, env, i64, i64)
+DEF_HELPER_3(aadd, i32, env, i32, i32)
+DEF_HELPER_3(aaddu, i32, env, i32, i32)
+DEF_HELPER_3(pasub_b, tl, env, tl, tl)
+DEF_HELPER_3(pasub_h, tl, env, tl, tl)
+DEF_HELPER_3(pasub_w, i64, env, i64, i64)
+DEF_HELPER_3(pasubu_b, tl, env, tl, tl)
+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)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 8da13669d73..005cc055b8a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -1147,3 +1147,29 @@ pusati_h 10100 001.... ..... 100 ..... 0011011 @p_ui16
}
sati_64 111001 ...... ..... 100 ..... 0011011 @p_ui64
usati_64 101001 ...... ..... 100 ..... 0011011 @p_ui64
+
+# Packed SIMD - Averaging and Rounding Operations
+paadd_b 1001110 ..... ..... 000 ..... 0111011 @r
+paadd_h 1001100 ..... ..... 000 ..... 0111011 @r
+{
+ aadd 1001101 ..... ..... 000 ..... 0111011 @r
+ paadd_w 1001101 ..... ..... 000 ..... 0111011 @r
+}
+paaddu_b 1011110 ..... ..... 000 ..... 0111011 @r
+paaddu_h 1011100 ..... ..... 000 ..... 0111011 @r
+{
+ aaddu 1011101 ..... ..... 000 ..... 0111011 @r
+ paaddu_w 1011101 ..... ..... 000 ..... 0111011 @r
+}
+pasub_b 1101110 ..... ..... 000 ..... 0111011 @r
+pasub_h 1101100 ..... ..... 000 ..... 0111011 @r
+{
+ asub 1101101 ..... ..... 000 ..... 0111011 @r
+ pasub_w 1101101 ..... ..... 000 ..... 0111011 @r
+}
+pasubu_b 1111110 ..... ..... 000 ..... 0111011 @r
+pasubu_h 1111100 ..... ..... 000 ..... 0111011 @r
+{
+ asubu 1111101 ..... ..... 000 ..... 0111011 @r
+ pasubu_w 1111101 ..... ..... 000 ..... 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 056ccfb486e..43c59aef182 100644
--- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc
+++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc
@@ -545,3 +545,21 @@ GEN_SIMD_TRANS_IMM_32_VXSAT(usati_32)
GEN_SIMD_TRANS_IMM_64_VXSAT(sati_64)
GEN_SIMD_TRANS_IMM_64_VXSAT(usati_64)
+/* Packed SIMD - Averaging and Rounding Operations */
+GEN_SIMD_TRANS(paadd_b)
+GEN_SIMD_TRANS(paadd_h)
+GEN_SIMD_TRANS_64(paadd_w)
+GEN_SIMD_TRANS(paaddu_b)
+GEN_SIMD_TRANS(paaddu_h)
+GEN_SIMD_TRANS_64(paaddu_w)
+GEN_SIMD_TRANS_32(aadd)
+GEN_SIMD_TRANS_32(aaddu)
+GEN_SIMD_TRANS(pasub_b)
+GEN_SIMD_TRANS(pasub_h)
+GEN_SIMD_TRANS_64(pasub_w)
+GEN_SIMD_TRANS(pasubu_b)
+GEN_SIMD_TRANS(pasubu_h)
+GEN_SIMD_TRANS_64(pasubu_w)
+GEN_SIMD_TRANS_32(asub)
+GEN_SIMD_TRANS_32(asubu)
+
diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c
index 52c58e0287e..162041a8f18 100644
--- a/target/riscv/tcg/psimd_helper.c
+++ b/target/riscv/tcg/psimd_helper.c
@@ -1768,3 +1768,43 @@ GEN_PSIMD_SATI(sati_64, uint64_t, int64_t, int64_t,
GEN_PSIMD_USATI(usati_64, uint64_t, int64_t, uint64_t, uint64_t,
EXTRACT64, INSERT64, ELEMS_D, 1ULL)
+/* Averaging Operations (non-saturating) */
+
+GEN_PSIMD_AVG_BINOP(paadd_b, target_ulong, int8_t, int16_t,
+ EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD)
+GEN_PSIMD_AVG_BINOP(paadd_h, target_ulong, int16_t, int32_t,
+ EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD)
+GEN_PSIMD_AVG_BINOP(paadd_w, uint64_t, int32_t, int64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD)
+
+GEN_PSIMD_AVG_BINOP(paaddu_b, target_ulong, uint8_t, uint16_t,
+ EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_ADD)
+GEN_PSIMD_AVG_BINOP(paaddu_h, target_ulong, uint16_t, uint32_t,
+ EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_ADD)
+GEN_PSIMD_AVG_BINOP(paaddu_w, uint64_t, uint32_t, uint64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD)
+
+GEN_PSIMD_AVG_BINOP(aadd, uint32_t, int32_t, int64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD)
+GEN_PSIMD_AVG_BINOP(aaddu, uint32_t, uint32_t, uint64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_ADD)
+
+GEN_PSIMD_AVG_BINOP(pasub_b, target_ulong, int8_t, int16_t,
+ EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB)
+GEN_PSIMD_AVG_BINOP(pasub_h, target_ulong, int16_t, int32_t,
+ EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB)
+GEN_PSIMD_AVG_BINOP(pasub_w, uint64_t, int32_t, int64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB)
+
+GEN_PSIMD_AVG_BINOP(pasubu_b, target_ulong, uint8_t, uint16_t,
+ EXTRACT8, INSERT8, ELEMS_B, PSIMD_DO_SUB)
+GEN_PSIMD_AVG_BINOP(pasubu_h, target_ulong, uint16_t, uint32_t,
+ EXTRACT16, INSERT16, ELEMS_H, PSIMD_DO_SUB)
+GEN_PSIMD_AVG_BINOP(pasubu_w, uint64_t, uint32_t, uint64_t,
+ EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_SUB)
+
+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)
+