target/arm/cpu-features.h | 5 +++++ linux-user/aarch64/elfload.c | 1 + target/arm/tcg/cpu64.c | 1 + target/arm/tcg/translate-sve.c | 2 +- docs/system/arm/emulation.rst | 1 + 5 files changed, 9 insertions(+), 1 deletion(-)
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/cpu-features.h | 5 +++++
linux-user/aarch64/elfload.c | 1 +
target/arm/tcg/cpu64.c | 1 +
target/arm/tcg/translate-sve.c | 2 +-
docs/system/arm/emulation.rst | 1 +
5 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index c3eeecbea9..bdeb72bd77 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -1580,6 +1580,11 @@ static inline bool isar_feature_aa64_sme_mop4(const ARMISARegisters *id)
return FIELD_EX64_IDREG(id, ID_AA64SMFR0, SMOP4);
}
+static inline bool isar_feature_aa64_ssve_fexpa(const ARMISARegisters *id)
+{
+ return FIELD_EX64_IDREG(id, ID_AA64SMFR0, SFEXPA);
+}
+
static inline bool isar_feature_aa64_ssve_aes(const ARMISARegisters *id)
{
return FIELD_EX64_IDREG(id, ID_AA64SMFR0, AES);
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
index 9b93969850..cea286cce0 100644
--- a/linux-user/aarch64/elfload.c
+++ b/linux-user/aarch64/elfload.c
@@ -174,6 +174,7 @@ abi_ulong get_elf_hwcap(CPUState *cs)
GET_FEATURE_ID(aa64_f8mm8, ARM_HWCAP_A64_F8MM8);
GET_FEATURE_ID(aa64_f8mm4, ARM_HWCAP_A64_F8MM4);
GET_FEATURE_ID(aa64_ssve_aes, ARM_HWCAP_A64_SME_AES);
+ GET_FEATURE_ID(aa64_ssve_fexpa, ARM_HWCAP_A64_SME_SFEXPA);
GET_FEATURE_ID(aa64_sme_mop4, ARM_HWCAP_A64_SME_SMOP4);
GET_FEATURE_ID(aa64_sve2p2, ARM_HWCAP_A64_SVE2P2);
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index 2cf335c956..7151c509f9 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1384,6 +1384,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = GET_IDREG(isar, ID_AA64SMFR0);
t = FIELD_DP64(t, ID_AA64SMFR0, SMOP4, 1); /* FEAT_SME_MOP4 */
+ t = FIELD_DP64(t, ID_AA64SMFR0, SFEXPA, 1); /* FEAT_SSVE_FEXPA */
t = FIELD_DP64(t, ID_AA64SMFR0, AES, 1); /* FEAT_SSVE_AES */
t = FIELD_DP64(t, ID_AA64SMFR0, SF8DP2, 1); /* FEAT_SSVE_FP8DOT2 */
t = FIELD_DP64(t, ID_AA64SMFR0, SF8DP4, 1); /* FEAT_SSVE_FP8DOT4 */
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
index 79e8e16b24..5de9ee7d4f 100644
--- a/target/arm/tcg/translate-sve.c
+++ b/target/arm/tcg/translate-sve.c
@@ -1373,7 +1373,7 @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
NULL, gen_helper_sve_fexpa_h,
gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
};
-TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
+TRANS_FEAT_STREAMING_IF(FEXPA, aa64_sve, aa64_ssve_fexpa, gen_gvec_ool_zz,
fexpa_fns[a->esz], a->rd, a->rn, s->fpcr_ah)
static gen_helper_gvec_3 * const ftssel_fns[4] = {
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index 3ef5b53e8a..a12471aafe 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -175,6 +175,7 @@ the following architecture extensions:
- FEAT_SME_LUTv2 (Lookup table instructions with 4-bit indices and 8-bit elements)
- FEAT_SME_MOP4 (Quarter-tile outer product instructions)
- FEAT_SSVE_AES (Streaming SVE Mode Advanced Encryption Standard and 128-bit polynomial multiply long instructions)
+- FEAT_SSVE_FEXPA (Streaming FEXPA instruction)
- FEAT_SSVE_FP8DOT2 (SVE2 FP8 2-way dot product to half-precision instructions in Streaming SVE mode)
- FEAT_SSVE_FP8DOT4 (SVE2 FP8 4-way dot product to single-precision instructions in Streaming SVE mode)
- FEAT_SSVE_FP8FMA (SVE2 FP8 multiply-accumulate to half-precision and single-precision instructions in Streaming SVE mode)
--
2.43.0
On Thu, 25 Jun 2026 at 23:48, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> --- a/target/arm/tcg/translate-sve.c
> +++ b/target/arm/tcg/translate-sve.c
> @@ -1373,7 +1373,7 @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
> NULL, gen_helper_sve_fexpa_h,
> gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
> };
> -TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
> +TRANS_FEAT_STREAMING_IF(FEXPA, aa64_sve, aa64_ssve_fexpa, gen_gvec_ool_zz,
> fexpa_fns[a->esz], a->rd, a->rn, s->fpcr_ah)
The FEXPA feature gate also changes to FEAT_SVE || FEAT_SSVE_FEXPA,
so I think we need the second argument to be a new feature
check function aa64_sve_or_ssve_fexpa.
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
On 6/26/26 02:31, Peter Maydell wrote:
> On Thu, 25 Jun 2026 at 23:48, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>
>
>> --- a/target/arm/tcg/translate-sve.c
>> +++ b/target/arm/tcg/translate-sve.c
>> @@ -1373,7 +1373,7 @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
>> NULL, gen_helper_sve_fexpa_h,
>> gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
>> };
>> -TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
>> +TRANS_FEAT_STREAMING_IF(FEXPA, aa64_sve, aa64_ssve_fexpa, gen_gvec_ool_zz,
>> fexpa_fns[a->esz], a->rd, a->rn, s->fpcr_ah)
>
> The FEXPA feature gate also changes to FEAT_SVE || FEAT_SSVE_FEXPA,
> so I think we need the second argument to be a new feature
> check function aa64_sve_or_ssve_fexpa.
Oh, right, for the !SVE case. Thanks.
r~
© 2016 - 2026 Red Hat, Inc.