target/arm: Implement EXPAND
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260618040718.572950-3-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Richard Henderson committed
Jun 17, 2026 at 21:07 UTC
5a3e71a7c20767c5013ad30af86d1c925bde81a8
4 files changed
+40
target/arm/tcg/helper-sve-defs.h
+5
@@ -3203,3 +3203,8 @@ DEF_HELPER_FLAGS_6(sve2_famin_s, TCG_CALL_NO_RWG,
3203
void, ptr, ptr, ptr, ptr, fpst, i32)
3204
DEF_HELPER_FLAGS_6(sve2_famin_d, TCG_CALL_NO_RWG,
3205
void, ptr, ptr, ptr, ptr, fpst, i32)
3206
+
3207
+DEF_HELPER_FLAGS_4(sve_expand_b, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
3208
+DEF_HELPER_FLAGS_4(sve_expand_h, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
3209
+DEF_HELPER_FLAGS_4(sve_expand_s, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
3210
+DEF_HELPER_FLAGS_4(sve_expand_d, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
target/arm/tcg/sve.decode
+2
@@ -742,6 +742,8 @@ SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
742
# SVE2 vector splice (predicated, constructive)
743
SPLICE_sve2 00000101 .. 101 101 100 ... ..... ..... @rd_pg_rn
744
745
+EXPAND 00000101 .. 110 001 100 ... ..... ..... @rd_pg_rn
746
+
747
### SVE Select Vectors Group
748
749
# SVE select vector elements (predicated)
target/arm/tcg/sve_helper.c
+26
@@ -3671,6 +3671,32 @@ void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
3671
}
3672
}
3673
3674
+#define DO_EXPAND(NAME, TYPE, H) \
3675
+void HELPER(NAME)(void *vd, void *vn, void *vg, uint32_t desc) \
3676
+{ \
3677
+ intptr_t oprsz = simd_oprsz(desc); \
3678
+ ARMVectorReg tmp_n = *(ARMVectorReg *)vn; \
3679
+ for (intptr_t i = 0, j = 0; i < oprsz; ) { \
3680
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
3681
+ do { \
3682
+ TYPE nn = 0; \
3683
+ if (pg & 1) { \
3684
+ nn = *(TYPE *)((void *)&tmp_n + H(j)); \
3685
+ j += sizeof(TYPE); \
3686
+ } \
3687
+ *(TYPE *)(vd + H(i)) = nn; \
3688
+ i += sizeof(TYPE); \
3689
+ pg >>= sizeof(TYPE); \
3690
+ } while (i & 15); \
3691
+ } \
3692
+}
3693
+
3694
+DO_EXPAND(sve_expand_b, uint8_t, H1)
3695
+DO_EXPAND(sve_expand_h, uint16_t, H1_2)
3696
+DO_EXPAND(sve_expand_s, uint32_t, H1_4)
3697
+DO_EXPAND(sve_expand_d, uint64_t, H1_8)
3698
+
3699
+#undef DO_EXPAND
3700
/* Similar to the ARM LastActiveElement pseudocode function, except the
3701
* result is multiplied by the element size. This includes the not found
3702
* indication; e.g. not found for esz=3 is -8.
target/arm/tcg/translate-sve.c
+7
@@ -6956,6 +6956,13 @@ static gen_helper_gvec_3 * const sqneg_fns[4] = {
6956
TRANS_FEAT(SQNEG_m, aa64_sme_or_sve2, gen_gvec_ool_arg_zpz, sqneg_fns[a->esz], a, 0)
6957
TRANS_FEAT(SQNEG_z, aa64_sme2p2_or_sve2p2, gen_gvec_ool_arg_zpz, sqneg_fns[a->esz], a, 1)
6958
6959
+static gen_helper_gvec_3 * const expand_fns[4] = {
6960
+ gen_helper_sve_expand_b, gen_helper_sve_expand_h,
6961
+ gen_helper_sve_expand_s, gen_helper_sve_expand_d,
6962
+};
6963
+TRANS_FEAT_STREAMING_IF(EXPAND, aa64_sme2p2_or_sve2p2, aa64_sme2p2,
6964
+ gen_gvec_ool_arg_zpz, expand_fns[a->esz], a, 0)
6965
+
6966
DO_ZPZZ(SQSHL, aa64_sme_or_sve2, sve2_sqshl)
6967
DO_ZPZZ(SQRSHL, aa64_sme_or_sve2, sve2_sqrshl)
6968
DO_ZPZZ(SRSHL, aa64_sme_or_sve2, sve2_srshl)