aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-07-04 08:21:01 -0600
committerPeter Maydell <peter.maydell@linaro.org>2025-07-04 15:53:23 +0100
commitd2aa9a804ee678f0327bc5c6018a814caa424b77 (patch)
tree8c2edbf3de464d5cacf24359eea4032a8629f0f1
parent0e4ba0607b74c82525dcfc6ed1c4b89bb4cbb39b (diff)
downloadqemu-d2aa9a804ee678f0327bc5c6018a814caa424b77.zip
qemu-d2aa9a804ee678f0327bc5c6018a814caa424b77.tar.gz
qemu-d2aa9a804ee678f0327bc5c6018a814caa424b77.tar.bz2
target/arm: Implement LD1Q, ST1Q for SVE2p1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-99-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/arm/tcg/helper-sve.h16
-rw-r--r--target/arm/tcg/sve.decode8
-rw-r--r--target/arm/tcg/sve_helper.c6
-rw-r--r--target/arm/tcg/translate-sve.c34
4 files changed, 62 insertions, 2 deletions
diff --git a/target/arm/tcg/helper-sve.h b/target/arm/tcg/helper-sve.h
index ade76ff..c36090d 100644
--- a/target/arm/tcg/helper-sve.h
+++ b/target/arm/tcg/helper-sve.h
@@ -2155,6 +2155,10 @@ DEF_HELPER_FLAGS_6(sve_ldsds_le_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_ldsds_be_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_ldqq_le_zd, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_ldqq_be_zd, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_ldbsu_zsu_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
@@ -2264,6 +2268,10 @@ DEF_HELPER_FLAGS_6(sve_ldsds_le_zd_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_ldsds_be_zd_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_ldqq_le_zd_mte, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_ldqq_be_zd_mte, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_ldffbsu_zsu, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
@@ -2549,6 +2557,10 @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_stdd_be_zd, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_stqq_le_zd, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_stqq_be_zd, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_stbs_zsu_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
@@ -2616,6 +2628,10 @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_6(sve_stdd_be_zd_mte, TCG_CALL_NO_WG,
void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_stqq_le_zd_mte, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
+DEF_HELPER_FLAGS_6(sve_stqq_be_zd_mte, TCG_CALL_NO_WG,
+ void, env, ptr, ptr, ptr, tl, i32)
DEF_HELPER_FLAGS_4(sve2_sqdmull_zzz_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode
index 3eda029..2efd5f5 100644
--- a/target/arm/tcg/sve.decode
+++ b/target/arm/tcg/sve.decode
@@ -1340,6 +1340,10 @@ LD1_zprz 1100010 10 1. ..... 1.. ... ..... ..... \
LD1_zprz 1100010 11 1. ..... 11. ... ..... ..... \
@rprr_g_load_sc esz=3 msz=3 u=1
+# LD1Q
+LD1_zprz 1100 0100 000 rm:5 101 pg:3 rn:5 rd:5 \
+ &rprr_gather_load u=0 ff=0 xs=2 esz=4 msz=4 scale=0
+
# SVE 64-bit gather load (vector plus immediate)
LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
@rpri_g_load esz=3
@@ -1443,6 +1447,10 @@ ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
@rprr_scatter_store xs=2 esz=3 scale=0
+# ST1Q
+ST1_zprz 1110 0100 001 rm:5 001 pg:3 rn:5 rd:5 \
+ &rprr_scatter_store xs=2 msz=4 esz=4 scale=0
+
# SVE 64-bit scatter store (vector plus immediate)
ST1_zpiz 1110010 .. 10 ..... 101 ... ..... ..... \
@rpri_scatter_store esz=3
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
index 360114e..43b872c 100644
--- a/target/arm/tcg/sve_helper.c
+++ b/target/arm/tcg/sve_helper.c
@@ -7211,6 +7211,9 @@ DO_LD1_ZPZ_D(dd_be, zsu, MO_64)
DO_LD1_ZPZ_D(dd_be, zss, MO_64)
DO_LD1_ZPZ_D(dd_be, zd, MO_64)
+DO_LD1_ZPZ_D(qq_le, zd, MO_128)
+DO_LD1_ZPZ_D(qq_be, zd, MO_128)
+
#undef DO_LD1_ZPZ_S
#undef DO_LD1_ZPZ_D
@@ -7597,6 +7600,9 @@ DO_ST1_ZPZ_D(sd_be, zd, MO_32)
DO_ST1_ZPZ_D(dd_le, zd, MO_64)
DO_ST1_ZPZ_D(dd_be, zd, MO_64)
+DO_ST1_ZPZ_D(qq_le, zd, MO_128)
+DO_ST1_ZPZ_D(qq_be, zd, MO_128)
+
#undef DO_ST1_ZPZ_S
#undef DO_ST1_ZPZ_D
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 7dff028..7b57573 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -6121,13 +6121,23 @@ gather_load_fn64[2][2][2][3][2][4] = {
gen_helper_sve_ldffdd_be_zd_mte, } } } } },
};
+static gen_helper_gvec_mem_scatter * const
+gather_load_fn128[2][2] = {
+ { gen_helper_sve_ldqq_le_zd,
+ gen_helper_sve_ldqq_be_zd },
+ { gen_helper_sve_ldqq_le_zd_mte,
+ gen_helper_sve_ldqq_be_zd_mte }
+};
+
static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a)
{
gen_helper_gvec_mem_scatter *fn = NULL;
bool be = s->be_data == MO_BE;
bool mte = s->mte_active[0];
- if (!dc_isar_feature(aa64_sve, s)) {
+ if (a->esz < MO_128
+ ? !dc_isar_feature(aa64_sve, s)
+ : !dc_isar_feature(aa64_sve2p1, s)) {
return false;
}
s->is_nonstreaming = true;
@@ -6142,6 +6152,12 @@ static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a)
case MO_64:
fn = gather_load_fn64[mte][be][a->ff][a->xs][a->u][a->msz];
break;
+ case MO_128:
+ assert(!a->ff && a->u && a->xs == 2 && a->msz == MO_128);
+ fn = gather_load_fn128[mte][be];
+ break;
+ default:
+ g_assert_not_reached();
}
assert(fn != NULL);
@@ -6309,6 +6325,14 @@ static gen_helper_gvec_mem_scatter * const scatter_store_fn64[2][2][3][4] = {
gen_helper_sve_stdd_be_zd_mte, } } },
};
+static gen_helper_gvec_mem_scatter * const
+scatter_store_fn128[2][2] = {
+ { gen_helper_sve_stqq_le_zd,
+ gen_helper_sve_stqq_be_zd },
+ { gen_helper_sve_stqq_le_zd_mte,
+ gen_helper_sve_stqq_be_zd_mte }
+};
+
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a)
{
gen_helper_gvec_mem_scatter *fn;
@@ -6318,7 +6342,9 @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a)
if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
return false;
}
- if (!dc_isar_feature(aa64_sve, s)) {
+ if (a->esz < MO_128
+ ? !dc_isar_feature(aa64_sve, s)
+ : !dc_isar_feature(aa64_sve2p1, s)) {
return false;
}
s->is_nonstreaming = true;
@@ -6332,6 +6358,10 @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a)
case MO_64:
fn = scatter_store_fn64[mte][be][a->xs][a->msz];
break;
+ case MO_128:
+ assert(a->xs == 2 && a->msz == MO_128);
+ fn = scatter_store_fn128[mte][be];
+ break;
default:
g_assert_not_reached();
}