diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2025-07-04 08:20:51 -0600 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2025-07-04 15:52:22 +0100 |
commit | a4a49a31f499adb8ba2fca6b048d4f51f41e178a (patch) | |
tree | 0e953844dcb096f49a6517ccf4f28f1b1ad6fd78 | |
parent | 47810f99e846501c817fb77ebd03b6914342f7e5 (diff) | |
download | qemu-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.decode | 6 | ||||
-rw-r--r-- | target/arm/tcg/translate-sve.c | 21 |
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); |