Implement packed add-subtract cross operations. Cover normal, saturating, and averaging variants for halfword and word elements. Add the associated decode entries, translators and helpers.
These instructions perform addition and subtraction using crossed source elements within each packed element pair. Note that saturating variants clamp results to the signed element range and set vxsat when saturation occurs, while averaging variants shift the intermediate results right by one bit and do not affect vxsat. Signed-off-by: Molly Chen <[email protected]> --- target/riscv/helper.h | 14 +++++++ target/riscv/insn32.decode | 14 +++++++ target/riscv/tcg/insn_trans/trans_rvp.c.inc | 14 +++++++ target/riscv/tcg/psimd_helper.c | 44 +++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 53107334e1f..cca3b88535d 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1497,3 +1497,17 @@ DEF_HELPER_3(sshl, i32, env, i32, i32) DEF_HELPER_3(sshlr, i32, env, i32, i32) DEF_HELPER_3(shl, i64, env, i64, i64) DEF_HELPER_3(shlr, i64, env, i64, i64) + +/* Packed SIMD - Exchange Operations */ +DEF_HELPER_3(pas_hx, tl, env, tl, tl) +DEF_HELPER_3(psa_hx, tl, env, tl, tl) +DEF_HELPER_3(psas_hx, tl, env, tl, tl) +DEF_HELPER_3(pssa_hx, tl, env, tl, tl) +DEF_HELPER_3(paas_hx, tl, env, tl, tl) +DEF_HELPER_3(pasa_hx, tl, env, tl, tl) +DEF_HELPER_3(pas_wx, i64, env, i64, i64) +DEF_HELPER_3(psa_wx, i64, env, i64, i64) +DEF_HELPER_3(psas_wx, i64, env, i64, i64) +DEF_HELPER_3(pssa_wx, i64, env, i64, i64) +DEF_HELPER_3(paas_wx, i64, env, i64, i64) +DEF_HELPER_3(pasa_wx, i64, env, i64, i64) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index 82434b10410..3cfd8602c1c 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -1276,3 +1276,17 @@ psshlr_hs 1011100 ..... ..... 010 ..... 0011011 @r } shl 1010111 ..... ..... 010 ..... 0011011 @r shlr 1011111 ..... ..... 010 ..... 0011011 @r + +# Packed SIMD - Exchange Operations +pas_hx 1000000 ..... ..... 110 ..... 0111011 @r +psa_hx 1000010 ..... ..... 110 ..... 0111011 @r +psas_hx 1001000 ..... ..... 110 ..... 0111011 @r +pssa_hx 1001010 ..... ..... 110 ..... 0111011 @r +paas_hx 1001100 ..... ..... 110 ..... 0111011 @r +pasa_hx 1001110 ..... ..... 110 ..... 0111011 @r +pas_wx 1000001 ..... ..... 110 ..... 0111011 @r +psa_wx 1000011 ..... ..... 110 ..... 0111011 @r +psas_wx 1001001 ..... ..... 110 ..... 0111011 @r +pssa_wx 1001011 ..... ..... 110 ..... 0111011 @r +paas_wx 1001101 ..... ..... 110 ..... 0111011 @r +pasa_wx 1001111 ..... ..... 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 32b5de9f1b6..c991ac37e32 100644 --- a/target/riscv/tcg/insn_trans/trans_rvp.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvp.c.inc @@ -650,3 +650,17 @@ GEN_SIMD_TRANS_32_VXSAT(sshl) GEN_SIMD_TRANS_32_VXSAT(sshlr) GEN_SIMD_TRANS_64(shl) GEN_SIMD_TRANS_64(shlr) + +/* Packed SIMD - Exchange Operations */ +GEN_SIMD_TRANS(pas_hx) +GEN_SIMD_TRANS(psa_hx) +GEN_SIMD_TRANS_VXSAT(psas_hx) +GEN_SIMD_TRANS_VXSAT(pssa_hx) +GEN_SIMD_TRANS(paas_hx) +GEN_SIMD_TRANS(pasa_hx) +GEN_SIMD_TRANS_64(pas_wx) +GEN_SIMD_TRANS_64(psa_wx) +GEN_SIMD_TRANS_64_VXSAT(psas_wx) +GEN_SIMD_TRANS_64_VXSAT(pssa_wx) +GEN_SIMD_TRANS_64(paas_wx) +GEN_SIMD_TRANS_64(pasa_wx) diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c index cd110aa1cdc..0cb81151d79 100644 --- a/target/riscv/tcg/psimd_helper.c +++ b/target/riscv/tcg/psimd_helper.c @@ -2418,3 +2418,47 @@ GEN_PSIMD_VAR_USHLR(sshlr, uint32_t, uint32_t, uint64_t, GEN_PSIMD_VAR_SRL64(shl, PSIMD_DO_SRL64) GEN_PSIMD_VAR_SRL64(shlr, PSIMD_DO_RNDSRL64) + +/* Cross add/subtract operations */ + +GEN_PSIMD_XPAIR_BINOP(pas_hx, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_BINOP(psa_hx, target_ulong, int16_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_SAT_BINOP(psas_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD, signed_saturate_h) +GEN_PSIMD_XPAIR_SAT_BINOP(pssa_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB, signed_saturate_h) + +GEN_PSIMD_XPAIR_AVG_BINOP(paas_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_AVG_BINOP(pasa_hx, target_ulong, int16_t, int32_t, + EXTRACT16, INSERT16, ELEMS_H, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_BINOP(pas_wx, uint64_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_BINOP(psa_wx, uint64_t, int32_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB) + +GEN_PSIMD_XPAIR_SAT_BINOP(psas_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD, signed_saturate_w) +GEN_PSIMD_XPAIR_SAT_BINOP(pssa_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB, signed_saturate_w) + +GEN_PSIMD_XPAIR_AVG_BINOP(paas_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_SUB, PSIMD_DO_ADD) +GEN_PSIMD_XPAIR_AVG_BINOP(pasa_wx, uint64_t, int32_t, int64_t, + EXTRACT32, INSERT32, ELEMS_W, + PSIMD_DO_ADD, PSIMD_DO_SUB) -- 2.34.1
