Signed-off-by: Richard Henderson <[email protected]>
---
target/arm/tcg/helper-sve-defs.h | 5 +++++
target/arm/tcg/sve_helper.c | 28 ++++++++++++++++++++++++++++
target/arm/tcg/translate-sve.c | 7 +++++++
target/arm/tcg/sve.decode | 2 ++
4 files changed, 42 insertions(+)
diff --git a/target/arm/tcg/helper-sve-defs.h b/target/arm/tcg/helper-sve-defs.h
index de2254bb19..75c0fc919d 100644
--- a/target/arm/tcg/helper-sve-defs.h
+++ b/target/arm/tcg/helper-sve-defs.h
@@ -3203,3 +3203,8 @@ DEF_HELPER_FLAGS_6(sve2_famin_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, fpst, i32)
DEF_HELPER_FLAGS_6(sve2_famin_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, fpst, i32)
+
+DEF_HELPER_FLAGS_4(sve2p2_expand_b, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sve2p2_expand_h, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sve2p2_expand_s, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(sve2p2_expand_d, TCG_CALL_NO_WG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index c2b3162084..a13ccf4b85 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -8669,3 +8669,31 @@ void HELPER(pext)(void *vd, uint32_t png, uint32_t desc)
do_whilel(vd, mask, MIN(b_count, vl), vl);
}
}
+
+#define DO_EXPAND(NAME, TYPE, H) \
+void HELPER(NAME)(void *vd, void *vn, void *vg, uint32_t desc) \
+{ \
+ intptr_t oprsz = simd_oprsz(desc); \
+ ARMVectorReg tn = *(ARMVectorReg *)vn; \
+ intptr_t i = 0, j = 0; \
+ do { \
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
+ do { \
+ TYPE nn = 0; \
+ if (pg & 1) { \
+ nn = *(TYPE *)((void *)&tn + H(j)); \
+ j += sizeof(TYPE); \
+ } \
+ *(TYPE *)(vd + H(i)) = nn; \
+ i += sizeof(TYPE); \
+ pg >>= sizeof(TYPE); \
+ } while (i & 15); \
+ } while (i < oprsz); \
+}
+
+DO_EXPAND(sve2p2_expand_b, uint8_t, H1)
+DO_EXPAND(sve2p2_expand_h, uint16_t, H1_2)
+DO_EXPAND(sve2p2_expand_s, uint32_t, H1_4)
+DO_EXPAND(sve2p2_expand_d, uint64_t, H1_8)
+
+#undef DO_EXPAND
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 315ebe82f9..3101f572fa 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -6956,6 +6956,13 @@ static gen_helper_gvec_3 * const sqneg_fns[4] = {
TRANS_FEAT(SQNEG_m, aa64_sme_or_sve2, gen_gvec_ool_arg_zpz, sqneg_fns[a->esz],
a, 0)
TRANS_FEAT(SQNEG_z, aa64_sme2p2_or_sve2p2, gen_gvec_ool_arg_zpz,
sqneg_fns[a->esz], a, 1)
+static gen_helper_gvec_3 * const expand_fns[4] = {
+ gen_helper_sve2p2_expand_b, gen_helper_sve2p2_expand_h,
+ gen_helper_sve2p2_expand_s, gen_helper_sve2p2_expand_d,
+};
+TRANS_FEAT_STREAMING_IF(EXPAND, aa64_sme2p2_or_sve2p2, aa64_sme2p2,
+ gen_gvec_ool_arg_zpz, expand_fns[a->esz], a, 0)
+
DO_ZPZZ(SQSHL, aa64_sme_or_sve2, sve2_sqshl)
DO_ZPZZ(SQRSHL, aa64_sme_or_sve2, sve2_sqrshl)
DO_ZPZZ(SRSHL, aa64_sme_or_sve2, sve2_srshl)
diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode
index 2795c2ec7f..5ec1d420c2 100644
--- a/target/arm/tcg/sve.decode
+++ b/target/arm/tcg/sve.decode
@@ -742,6 +742,8 @@ SPLICE 00000101 .. 101 100 100 ... ..... .....
@rdn_pg_rm
# SVE2 vector splice (predicated, constructive)
SPLICE_sve2 00000101 .. 101 101 100 ... ..... ..... @rd_pg_rn
+EXPAND 00000101 .. 110 001 100 ... ..... ..... @rd_pg_rn
+
### SVE Select Vectors Group
# SVE select vector elements (predicated)
--
2.43.0