Implement the MVE VHCADD insn, which is similar to VCADD but performs a halving step. This one overlaps with VADC.
Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> --- target/arm/helper-mve.h | 8 ++++++++ target/arm/mve.decode | 6 +++++- target/arm/mve_helper.c | 5 +++++ target/arm/translate-mve.c | 4 +++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h index 6e345470cbb..3f056e67871 100644 --- a/target/arm/helper-mve.h +++ b/target/arm/helper-mve.h @@ -259,6 +259,14 @@ DEF_HELPER_FLAGS_4(mve_vcadd270b, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) DEF_HELPER_FLAGS_4(mve_vcadd270h, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) DEF_HELPER_FLAGS_4(mve_vcadd270w, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vhcadd90b, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vhcadd90h, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vhcadd90w, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) + +DEF_HELPER_FLAGS_4(mve_vhcadd270b, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vhcadd270h, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) +DEF_HELPER_FLAGS_4(mve_vhcadd270w, TCG_CALL_NO_WG, void, env, ptr, ptr, ptr) + DEF_HELPER_FLAGS_4(mve_vadd_scalarb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vadd_scalarh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vadd_scalarw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) diff --git a/target/arm/mve.decode b/target/arm/mve.decode index c0979f3941b..23ae12b7a38 100644 --- a/target/arm/mve.decode +++ b/target/arm/mve.decode @@ -163,7 +163,11 @@ VQDMULLT 111 . 1110 0 . 11 ... 0 ... 1 1111 . 0 . 0 ... 1 @2op_sz28 VRHADD_S 111 0 1111 0 . .. ... 0 ... 0 0001 . 1 . 0 ... 0 @2op VRHADD_U 111 1 1111 0 . .. ... 0 ... 0 0001 . 1 . 0 ... 0 @2op -VADC 1110 1110 0 . 11 ... 0 ... . 1111 . 0 . 0 ... 0 @vadc +{ + VHCADD90 1110 1110 0 . .. ... 0 ... 0 1111 . 0 . 0 ... 0 @2op + VHCADD270 1110 1110 0 . .. ... 0 ... 1 1111 . 0 . 0 ... 0 @2op + VADC 1110 1110 0 . 11 ... 0 ... . 1111 . 0 . 0 ... 0 @vadc +} { VCADD90 1111 1110 0 . .. ... 0 ... 0 1111 . 0 . 0 ... 0 @2op diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index 2c8ef25b208..3477d2bb191 100644 --- a/target/arm/mve_helper.c +++ b/target/arm/mve_helper.c @@ -638,8 +638,13 @@ DO_VADC(vsbc, DO_NOT) DO_VCADD(OP##h, 2, int16_t, H1, FN0, FN1) \ DO_VCADD(OP##w, 4, int32_t, H1, FN0, FN1) +#define DO_HADD(N, M) (((int64_t)(N) + (int64_t)(M)) >> 1) +#define DO_HSUB(N, M) (((int64_t)(N) - (int64_t)(M)) >> 1) + DO_VCADD_ALL(vcadd90, DO_SUB, DO_ADD) DO_VCADD_ALL(vcadd270, DO_ADD, DO_SUB) +DO_VCADD_ALL(vhcadd90, DO_HSUB, DO_HADD) +DO_VCADD_ALL(vhcadd270, DO_HADD, DO_HSUB) static inline int32_t do_sat_bhw(int64_t val, int64_t min, int64_t max, bool *s) { diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c index 8e3989b0176..b2020bd90b1 100644 --- a/target/arm/translate-mve.c +++ b/target/arm/translate-mve.c @@ -443,10 +443,12 @@ DO_2OP(VRHADD_U, vrhaddu) /* * VCADD Qd == Qm at size MO_32 is UNPREDICTABLE; we choose not to diagnose * so we can reuse the DO_2OP macro. (Our implementation calculates the - * "expected" results in this case.) + * "expected" results in this case.) Similarly for VHCADD. */ DO_2OP(VCADD90, vcadd90) DO_2OP(VCADD270, vcadd270) +DO_2OP(VHCADD90, vhcadd90) +DO_2OP(VHCADD270, vhcadd270) static bool trans_VQDMULLB(DisasContext *s, arg_2op *a) { -- 2.20.1