From 3394116f47d12bb577ee44493d3d61a30ec9dd68 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 28 Jun 2021 14:58:25 +0100 Subject: [PATCH] target/arm: Implement MVE vector shift right by immediate insns Implement the MVE vector shift right by immediate insns VSHRI and VRSHRI. As with Neon, we implement these by using helper functions which perform left shifts but allow negative shift counts to indicate right shifts. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 20210628135835.6690-9-peter.maydell@linaro.org --- target/arm/helper-mve.h | 12 ++++++++++++ target/arm/mve.decode | 28 ++++++++++++++++++++++++++++ target/arm/mve_helper.c | 7 +++++++ target/arm/translate-mve.c | 5 +++++ target/arm/translate-neon.c | 18 ------------------ target/arm/translate.h | 20 ++++++++++++++++++++ 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h index 8cd7c6a0d8..288a8faf4e 100644 --- a/target/arm/helper-mve.h +++ b/target/arm/helper-mve.h @@ -360,6 +360,10 @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64) DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64) DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64) +DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) @@ -375,3 +379,11 @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) + +DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) +DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32) diff --git a/target/arm/mve.decode b/target/arm/mve.decode index 183eb731d2..8be04589a6 100644 --- a/target/arm/mve.decode +++ b/target/arm/mve.decode @@ -64,6 +64,18 @@ @2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1 @2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2 +# Right shifts are encoded as N - shift, where N is the element size in bits. +%rshift_i5 16:5 !function=rsub_32 +%rshift_i4 16:4 !function=rsub_16 +%rshift_i3 16:3 !function=rsub_8 + +@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \ + size=0 shift=%rshift_i3 +@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \ + size=1 shift=%rshift_i4 +@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \ + size=2 shift=%rshift_i5 + # Vector loads and stores # Widening loads and narrowing stores: @@ -298,3 +310,19 @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w + +VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b +VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h +VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w + +VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b +VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h +VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w + +VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b +VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h +VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w + +VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b +VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h +VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c index 285c8b56f7..ac720c9ee0 100644 --- a/target/arm/mve_helper.c +++ b/target/arm/mve_helper.c @@ -1229,6 +1229,10 @@ DO_VADDV(vaddvuw, 4, uint32_t) DO_2SHIFT(OP##b, 1, uint8_t, FN) \ DO_2SHIFT(OP##h, 2, uint16_t, FN) \ DO_2SHIFT(OP##w, 4, uint32_t, FN) +#define DO_2SHIFT_S(OP, FN) \ + DO_2SHIFT(OP##b, 1, int8_t, FN) \ + DO_2SHIFT(OP##h, 2, int16_t, FN) \ + DO_2SHIFT(OP##w, 4, int32_t, FN) #define DO_2SHIFT_SAT_U(OP, FN) \ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \ @@ -1240,6 +1244,9 @@ DO_VADDV(vaddvuw, 4, uint32_t) DO_2SHIFT_SAT(OP##w, 4, int32_t, FN) DO_2SHIFT_U(vshli_u, DO_VSHLU) +DO_2SHIFT_S(vshli_s, DO_VSHLS) DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP) DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP) DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP) +DO_2SHIFT_U(vrshli_u, DO_VRSHLU) +DO_2SHIFT_S(vrshli_s, DO_VRSHLS) diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c index fc8a2da6e1..4030ee07f0 100644 --- a/target/arm/translate-mve.c +++ b/target/arm/translate-mve.c @@ -888,3 +888,8 @@ DO_2SHIFT(VSHLI, vshli_u, false) DO_2SHIFT(VQSHLI_S, vqshli_s, false) DO_2SHIFT(VQSHLI_U, vqshli_u, false) DO_2SHIFT(VQSHLUI, vqshlui_s, false) +/* These right shifts use a left-shift helper with negated shift count */ +DO_2SHIFT(VSHRI_S, vshli_s, true) +DO_2SHIFT(VSHRI_U, vshli_u, true) +DO_2SHIFT(VRSHRI_S, vrshli_s, true) +DO_2SHIFT(VRSHRI_U, vrshli_u, true) diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c index f915f70970..a45616cb63 100644 --- a/target/arm/translate-neon.c +++ b/target/arm/translate-neon.c @@ -33,24 +33,6 @@ static inline int plus1(DisasContext *s, int x) return x + 1; } -static inline int rsub_64(DisasContext *s, int x) -{ - return 64 - x; -} - -static inline int rsub_32(DisasContext *s, int x) -{ - return 32 - x; -} -static inline int rsub_16(DisasContext *s, int x) -{ - return 16 - x; -} -static inline int rsub_8(DisasContext *s, int x) -{ - return 8 - x; -} - static inline int neon_3same_fp_size(DisasContext *s, int x) { /* Convert 0==fp32, 1==fp16 into a MO_* value */ diff --git a/target/arm/translate.h b/target/arm/translate.h index e2f056c32c..4b5db937ef 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -161,6 +161,26 @@ static inline int times_2_plus_1(DisasContext *s, int x) return x * 2 + 1; } +static inline int rsub_64(DisasContext *s, int x) +{ + return 64 - x; +} + +static inline int rsub_32(DisasContext *s, int x) +{ + return 32 - x; +} + +static inline int rsub_16(DisasContext *s, int x) +{ + return 16 - x; +} + +static inline int rsub_8(DisasContext *s, int x) +{ + return 8 - x; +} + static inline int arm_dc_feature(DisasContext *dc, int feature) { return (dc->features & (1ULL << feature)) != 0;