aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-07-04 08:20:51 -0600
committerPeter Maydell <peter.maydell@linaro.org>2025-07-04 15:52:22 +0100
commita4a49a31f499adb8ba2fca6b048d4f51f41e178a (patch)
tree0e953844dcb096f49a6517ccf4f28f1b1ad6fd78
parent47810f99e846501c817fb77ebd03b6914342f7e5 (diff)
downloadqemu-a4a49a31f499adb8ba2fca6b048d4f51f41e178a.zip
qemu-a4a49a31f499adb8ba2fca6b048d4f51f41e178a.tar.gz
qemu-a4a49a31f499adb8ba2fca6b048d4f51f41e178a.tar.bz2
target/arm: Implement DUPQ for SME2p1/SVE2p1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-89-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/arm/tcg/sve.decode6
-rw-r--r--target/arm/tcg/translate-sve.c21
2 files changed, 27 insertions, 0 deletions
diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode
index db16849..2650e00 100644
--- a/target/arm/tcg/sve.decode
+++ b/target/arm/tcg/sve.decode
@@ -577,6 +577,12 @@ DUP_s 00000101 .. 1 00000 001110 ..... ..... @rd_rn
DUP_x 00000101 .. 1 ..... 001000 rn:5 rd:5 \
&rri imm=%imm7_22_16
+# SVE Permute Vector - one source quadwords
+DUPQ 00000101 001 imm:4 1 001001 rn:5 rd:5 &rri_esz esz=0
+DUPQ 00000101 001 imm:3 10 001001 rn:5 rd:5 &rri_esz esz=1
+DUPQ 00000101 001 imm:2 100 001001 rn:5 rd:5 &rri_esz esz=2
+DUPQ 00000101 001 imm:1 1000 001001 rn:5 rd:5 &rri_esz esz=3
+
# SVE insert SIMD&FP scalar register
INSR_f 00000101 .. 1 10100 001110 ..... ..... @rdn_rm
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 53db885..e33b2eb 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -2249,6 +2249,27 @@ static bool trans_DUP_x(DisasContext *s, arg_DUP_x *a)
return true;
}
+static bool trans_DUPQ(DisasContext *s, arg_DUPQ *a)
+{
+ unsigned vl, dofs, nofs;
+
+ if (!dc_isar_feature(aa64_sme2p1_or_sve2p1, s)) {
+ return false;
+ }
+ if (!sve_access_check(s)) {
+ return true;
+ }
+
+ vl = vec_full_reg_size(s);
+ dofs = vec_full_reg_offset(s, a->rd);
+ nofs = vec_reg_offset(s, a->rn, a->imm, a->esz);
+
+ for (unsigned i = 0; i < vl; i += 16) {
+ tcg_gen_gvec_dup_mem(a->esz, dofs + i, nofs + i, 16, 16);
+ }
+ return true;
+}
+
static void do_insr_i64(DisasContext *s, arg_rrr_esz *a, TCGv_i64 val)
{
typedef void gen_insr(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_i32);