aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-07-04 08:20:52 -0600
committerPeter Maydell <peter.maydell@linaro.org>2025-07-04 15:52:22 +0100
commit3b5257c8602b3002540c4dbdd3929251bd3acc85 (patch)
tree3abe2c9f161e96234fa004899a0fa3e905c0b93c
parenta4a49a31f499adb8ba2fca6b048d4f51f41e178a (diff)
downloadqemu-3b5257c8602b3002540c4dbdd3929251bd3acc85.zip
qemu-3b5257c8602b3002540c4dbdd3929251bd3acc85.tar.gz
qemu-3b5257c8602b3002540c4dbdd3929251bd3acc85.tar.bz2
target/arm: Implement EXTQ for SME2p1/SVE2p1
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-90-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/arm/tcg/sve.decode2
-rw-r--r--target/arm/tcg/translate-sve.c49
2 files changed, 51 insertions, 0 deletions
diff --git a/target/arm/tcg/sve.decode b/target/arm/tcg/sve.decode
index 2650e00..af4fb96 100644
--- a/target/arm/tcg/sve.decode
+++ b/target/arm/tcg/sve.decode
@@ -583,6 +583,8 @@ 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
+EXTQ 00000101 0110 imm:4 001001 rn:5 rd:5 &rri
+
# 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 e33b2eb..a918da3 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -2202,6 +2202,55 @@ static bool do_EXT(DisasContext *s, int rd, int rn, int rm, int imm)
TRANS_FEAT(EXT, aa64_sve, do_EXT, a->rd, a->rn, a->rm, a->imm)
TRANS_FEAT(EXT_sve2, aa64_sve2, do_EXT, a->rd, a->rn, (a->rn + 1) % 32, a->imm)
+static bool trans_EXTQ(DisasContext *s, arg_EXTQ *a)
+{
+ unsigned vl, dofs, sofs0, sofs1, sofs2, imm;
+
+ if (!dc_isar_feature(aa64_sme2p1_or_sve2p1, s)) {
+ return false;
+ }
+ if (!sve_access_check(s)) {
+ return true;
+ }
+
+ imm = a->imm;
+ if (imm == 0) {
+ /* So far we never optimize Zdn with MOVPRFX, so zd = zn is a nop. */
+ return true;
+ }
+
+ vl = vec_full_reg_size(s);
+ dofs = vec_full_reg_offset(s, a->rd);
+ sofs2 = vec_full_reg_offset(s, a->rn);
+
+ if (imm & 8) {
+ sofs0 = dofs + 8;
+ sofs1 = sofs2;
+ sofs2 += 8;
+ } else {
+ sofs0 = dofs;
+ sofs1 = dofs + 8;
+ }
+ imm = (imm & 7) << 3;
+
+ for (unsigned i = 0; i < vl; i += 16) {
+ TCGv_i64 s0 = tcg_temp_new_i64();
+ TCGv_i64 s1 = tcg_temp_new_i64();
+ TCGv_i64 s2 = tcg_temp_new_i64();
+
+ tcg_gen_ld_i64(s0, tcg_env, sofs0 + i);
+ tcg_gen_ld_i64(s1, tcg_env, sofs1 + i);
+ tcg_gen_ld_i64(s2, tcg_env, sofs2 + i);
+
+ tcg_gen_extract2_i64(s0, s0, s1, imm);
+ tcg_gen_extract2_i64(s1, s1, s2, imm);
+
+ tcg_gen_st_i64(s0, tcg_env, dofs + i);
+ tcg_gen_st_i64(s1, tcg_env, dofs + i + 8);
+ }
+ return true;
+}
+
/*
*** SVE Permute - Unpredicated Group
*/