From: Richard Henderson <richard.hender...@linaro.org> Do not assume SME implies SVE. Ensure that the non-streaming check is present along the SME path, since it is not implied by sme_*_enabled_check.
Cc: qemu-sta...@nongnu.org Reviewed-by: Peter Maydell <peter.mayd...@linaro.org> Signed-off-by: Richard Henderson <richard.hender...@linaro.org> Message-id: 20250704142112.1018902-3-richard.hender...@linaro.org Signed-off-by: Peter Maydell <peter.mayd...@linaro.org> (cherry picked from commit b4b2e070f41dd8774a70c6186141678558d79a38) (Mjt: compensate for target/arm/translate-a64.c => target/arm/tcg/ files move by v7.2.0-1632-gf0984d4040c3) Signed-off-by: Michael Tokarev <m...@tls.msk.ru> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 74237ef6f9..7210a9cc4d 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1187,11 +1187,8 @@ static bool fp_access_check_only(DisasContext *s) return true; } -static bool fp_access_check(DisasContext *s) +static bool nonstreaming_check(DisasContext *s) { - if (!fp_access_check_only(s)) { - return false; - } if (s->sme_trap_nonstreaming && s->is_nonstreaming) { gen_exception_insn(s, 0, EXCP_UDEF, syn_smetrap(SME_ET_Streaming, false)); @@ -1200,6 +1197,11 @@ static bool fp_access_check(DisasContext *s) return true; } +static bool fp_access_check(DisasContext *s) +{ + return fp_access_check_only(s) && nonstreaming_check(s); +} + /* * Check that SVE access is enabled. If it is, return true. * If not, emit code to generate an appropriate exception and return false. @@ -1207,14 +1209,24 @@ static bool fp_access_check(DisasContext *s) */ bool sve_access_check(DisasContext *s) { - if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) { + if (dc_isar_feature(aa64_sme, s)) { bool ret; - assert(dc_isar_feature(aa64_sme, s)); - ret = sme_sm_enabled_check(s); + if (s->pstate_sm) { + ret = sme_enabled_check(s); + } else if (dc_isar_feature(aa64_sve, s)) { + goto continue_sve; + } else { + ret = sme_sm_enabled_check(s); + } + if (ret) { + ret = nonstreaming_check(s); + } s->sve_access_checked = (ret ? 1 : -1); return ret; } + + continue_sve: if (s->sve_excp_el) { /* Assert that we only raise one exception per instruction. */ assert(!s->sve_access_checked); -- 2.47.2