[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC 33/65] target/riscv: rvv-0.9: single-width averaging add and subtra
From: |
frank . chang |
Subject: |
[RFC 33/65] target/riscv: rvv-0.9: single-width averaging add and subtract instructions |
Date: |
Fri, 10 Jul 2020 18:48:47 +0800 |
From: Frank Chang <frank.chang@sifive.com>
Signed-off-by: Frank Chang <frank.chang@sifive.com>
---
target/riscv/helper.h | 16 ++++++
target/riscv/insn32.decode | 13 +++--
target/riscv/insn_trans/trans_rvv.inc.c | 5 +-
target/riscv/vector_helper.c | 74 +++++++++++++++++++++++++
4 files changed, 102 insertions(+), 6 deletions(-)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e53fad1fd5..b253fee76d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -676,18 +676,34 @@ DEF_HELPER_6(vaadd_vv_b, void, ptr, ptr, ptr, ptr, env,
i32)
DEF_HELPER_6(vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
DEF_HELPER_6(vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 5c31936a92..0521ca4ab4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -439,11 +439,14 @@ vssubu_vv 100010 . ..... ..... 000 ..... 1010111
@r_vm
vssubu_vx 100010 . ..... ..... 100 ..... 1010111 @r_vm
vssub_vv 100011 . ..... ..... 000 ..... 1010111 @r_vm
vssub_vx 100011 . ..... ..... 100 ..... 1010111 @r_vm
-vaadd_vv 100100 . ..... ..... 000 ..... 1010111 @r_vm
-vaadd_vx 100100 . ..... ..... 100 ..... 1010111 @r_vm
-vaadd_vi 100100 . ..... ..... 011 ..... 1010111 @r_vm
-vasub_vv 100110 . ..... ..... 000 ..... 1010111 @r_vm
-vasub_vx 100110 . ..... ..... 100 ..... 1010111 @r_vm
+vaadd_vv 001001 . ..... ..... 010 ..... 1010111 @r_vm
+vaadd_vx 001001 . ..... ..... 110 ..... 1010111 @r_vm
+vaaddu_vv 001000 . ..... ..... 010 ..... 1010111 @r_vm
+vaaddu_vx 001000 . ..... ..... 110 ..... 1010111 @r_vm
+vasub_vv 001011 . ..... ..... 010 ..... 1010111 @r_vm
+vasub_vx 001011 . ..... ..... 110 ..... 1010111 @r_vm
+vasubu_vv 001010 . ..... ..... 010 ..... 1010111 @r_vm
+vasubu_vx 001010 . ..... ..... 110 ..... 1010111 @r_vm
vsmul_vv 100111 . ..... ..... 000 ..... 1010111 @r_vm
vsmul_vx 100111 . ..... ..... 100 ..... 1010111 @r_vm
vwsmaccu_vv 111100 . ..... ..... 000 ..... 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c
b/target/riscv/insn_trans/trans_rvv.inc.c
index dc9064e868..d90820ff6a 100644
--- a/target/riscv/insn_trans/trans_rvv.inc.c
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
@@ -2062,10 +2062,13 @@ GEN_OPIVI_TRANS(vsadd_vi, 0, vsadd_vx, opivx_check)
/* Vector Single-Width Averaging Add and Subtract */
GEN_OPIVV_TRANS(vaadd_vv, opivv_check)
+GEN_OPIVV_TRANS(vaaddu_vv, opivv_check)
GEN_OPIVV_TRANS(vasub_vv, opivv_check)
+GEN_OPIVV_TRANS(vasubu_vv, opivv_check)
GEN_OPIVX_TRANS(vaadd_vx, opivx_check)
+GEN_OPIVX_TRANS(vaaddu_vx, opivx_check)
GEN_OPIVX_TRANS(vasub_vx, opivx_check)
-GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check)
+GEN_OPIVX_TRANS(vasubu_vx, opivx_check)
/* Vector Single-Width Fractional Multiply with Rounding and Saturation */
GEN_OPIVV_TRANS(vsmul_vv, opivv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 70a4505736..17cc1a96e9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2658,6 +2658,43 @@ GEN_VEXT_VX_RM(vaadd_vx_h, 2, 2, clearh)
GEN_VEXT_VX_RM(vaadd_vx_w, 4, 4, clearl)
GEN_VEXT_VX_RM(vaadd_vx_d, 8, 8, clearq)
+static inline uint32_t aaddu32(CPURISCVState *env, int vxrm,
+ uint32_t a, uint32_t b)
+{
+ uint64_t res = (uint64_t)a + b;
+ uint8_t round = get_round(vxrm, res, 1);
+
+ return (res >> 1) + round;
+}
+
+static inline uint64_t aaddu64(CPURISCVState *env, int vxrm,
+ uint64_t a, uint64_t b)
+{
+ uint64_t res = a + b;
+ uint8_t round = get_round(vxrm, res, 1);
+ uint64_t over = res < a ? ((uint64_t)1 << 63) : 0;
+
+ return ((res >> 1) | over) + round;
+}
+
+RVVCALL(OPIVV2_RM, vaaddu_vv_b, OP_UUU_B, H1, H1, H1, aaddu32)
+RVVCALL(OPIVV2_RM, vaaddu_vv_h, OP_UUU_H, H2, H2, H2, aaddu32)
+RVVCALL(OPIVV2_RM, vaaddu_vv_w, OP_UUU_W, H4, H4, H4, aaddu32)
+RVVCALL(OPIVV2_RM, vaaddu_vv_d, OP_UUU_D, H8, H8, H8, aaddu64)
+GEN_VEXT_VV_RM(vaaddu_vv_b, 1, 1, clearb)
+GEN_VEXT_VV_RM(vaaddu_vv_h, 2, 2, clearh)
+GEN_VEXT_VV_RM(vaaddu_vv_w, 4, 4, clearl)
+GEN_VEXT_VV_RM(vaaddu_vv_d, 8, 8, clearq)
+
+RVVCALL(OPIVX2_RM, vaaddu_vx_b, OP_UUU_B, H1, H1, aaddu32)
+RVVCALL(OPIVX2_RM, vaaddu_vx_h, OP_UUU_H, H2, H2, aaddu32)
+RVVCALL(OPIVX2_RM, vaaddu_vx_w, OP_UUU_W, H4, H4, aaddu32)
+RVVCALL(OPIVX2_RM, vaaddu_vx_d, OP_UUU_D, H8, H8, aaddu64)
+GEN_VEXT_VX_RM(vaaddu_vx_b, 1, 1, clearb)
+GEN_VEXT_VX_RM(vaaddu_vx_h, 2, 2, clearh)
+GEN_VEXT_VX_RM(vaaddu_vx_w, 4, 4, clearl)
+GEN_VEXT_VX_RM(vaaddu_vx_d, 8, 8, clearq)
+
static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t
b)
{
int64_t res = (int64_t)a - b;
@@ -2694,6 +2731,43 @@ GEN_VEXT_VX_RM(vasub_vx_h, 2, 2, clearh)
GEN_VEXT_VX_RM(vasub_vx_w, 4, 4, clearl)
GEN_VEXT_VX_RM(vasub_vx_d, 8, 8, clearq)
+static inline uint32_t asubu32(CPURISCVState *env, int vxrm,
+ uint32_t a, uint32_t b)
+{
+ int64_t res = (int64_t)a - b;
+ uint8_t round = get_round(vxrm, res, 1);
+
+ return (res >> 1) + round;
+}
+
+static inline uint64_t asubu64(CPURISCVState *env, int vxrm,
+ uint64_t a, uint64_t b)
+{
+ uint64_t res = (uint64_t)a - b;
+ uint8_t round = get_round(vxrm, res, 1);
+ uint64_t over = res > a ? ((uint64_t)1 << 63) : 0;
+
+ return ((res >> 1) | over) + round;
+}
+
+RVVCALL(OPIVV2_RM, vasubu_vv_b, OP_UUU_B, H1, H1, H1, asubu32)
+RVVCALL(OPIVV2_RM, vasubu_vv_h, OP_UUU_H, H2, H2, H2, asubu32)
+RVVCALL(OPIVV2_RM, vasubu_vv_w, OP_UUU_W, H4, H4, H4, asubu32)
+RVVCALL(OPIVV2_RM, vasubu_vv_d, OP_UUU_D, H8, H8, H8, asubu64)
+GEN_VEXT_VV_RM(vasubu_vv_b, 1, 1, clearb)
+GEN_VEXT_VV_RM(vasubu_vv_h, 2, 2, clearh)
+GEN_VEXT_VV_RM(vasubu_vv_w, 4, 4, clearl)
+GEN_VEXT_VV_RM(vasubu_vv_d, 8, 8, clearq)
+
+RVVCALL(OPIVX2_RM, vasubu_vx_b, OP_UUU_B, H1, H1, asubu32)
+RVVCALL(OPIVX2_RM, vasubu_vx_h, OP_UUU_H, H2, H2, asubu32)
+RVVCALL(OPIVX2_RM, vasubu_vx_w, OP_UUU_W, H4, H4, asubu32)
+RVVCALL(OPIVX2_RM, vasubu_vx_d, OP_UUU_D, H8, H8, asubu64)
+GEN_VEXT_VX_RM(vasubu_vx_b, 1, 1, clearb)
+GEN_VEXT_VX_RM(vasubu_vx_h, 2, 2, clearh)
+GEN_VEXT_VX_RM(vasubu_vx_w, 4, 4, clearl)
+GEN_VEXT_VX_RM(vasubu_vx_d, 8, 8, clearq)
+
/* Vector Single-Width Fractional Multiply with Rounding and Saturation */
static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
{
--
2.17.1
- Re: [RFC 09/65] target/riscv: rvv-0.9: add vlenb register, (continued)
- [RFC 13/65] target/riscv: rvv-0.9: configure instructions, frank . chang, 2020/07/10
- [RFC 15/65] target/riscv: rvv-0.9: index load and store instructions, frank . chang, 2020/07/10
- [RFC 20/65] target/riscv: rvv-0.9: update vext_max_elems() for load/store insns, frank . chang, 2020/07/10
- [RFC 21/65] target/riscv: rvv-0.9: take fractional LMUL into vector max elements calculation, frank . chang, 2020/07/10
- [RFC 22/65] target/riscv: rvv-0.9: floating-point square-root instruction, frank . chang, 2020/07/10
- [RFC 28/65] target/riscv: rvv-0.9: element index instruction, frank . chang, 2020/07/10
- [RFC 32/65] target/riscv: rvv-0.9: integer extension instructions, frank . chang, 2020/07/10
- [RFC 33/65] target/riscv: rvv-0.9: single-width averaging add and subtract instructions,
frank . chang <=
- [RFC 35/65] target/riscv: rvv-0.9: narrowing integer right shift instructions, frank . chang, 2020/07/10
- [RFC 38/65] target/riscv: rvv-0.9: integer merge and move instructions, frank . chang, 2020/07/10
- [RFC 39/65] target/riscv: rvv-0.9: single-width saturating add and subtract instructions, frank . chang, 2020/07/10
- [RFC 40/65] target/riscv: rvv-0.9: integer comparison instructions, frank . chang, 2020/07/10
- [RFC 43/65] target/riscv: rvv-0.9: widening integer reduction instructions, frank . chang, 2020/07/10
- [RFC 50/65] target/riscv: rvv-0.9: floating-point/integer type-convert instructions, frank . chang, 2020/07/10
- [RFC 54/65] target/riscv: rvv-0.9: remove widening saturating scaled multiply-add, frank . chang, 2020/07/10
- [RFC 55/65] target/riscv: rvv-0.9: remove vmford.vv and vmford.vf, frank . chang, 2020/07/10
- [RFC 60/65] softfloat: add fp16 and uint8/int8 interconvert functions, frank . chang, 2020/07/10