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-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/tcg/translate-a64.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index bb49a2ce90..d7b0c81773 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1387,11 +1387,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));
@@ -1400,6 +1397,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);
+}
+
/*
* Return <0 for non-supported element sizes, with MO_16 controlled by
* FEAT_FP16; return 0 for fp disabled; otherwise return >0 for success.
@@ -1450,11 +1452,20 @@ static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz)
*/
bool sve_access_check(DisasContext *s)
{
- if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
- bool ret;
+ bool ret;
- assert(dc_isar_feature(aa64_sme, s));
- ret = sme_sm_enabled_check(s);
+ switch (dc_isar_feature(aa64_sme, s)) {
+ case true:
+ if (s->pstate_sm) {
+ ret = sme_enabled_check(s);
+ } else if (!dc_isar_feature(aa64_sve, s)) {
+ ret = sme_sm_enabled_check(s);
+ } else {
+ break;
+ }
+ if (ret) {
+ ret = nonstreaming_check(s);
+ }
s->sve_access_checked = (ret ? 1 : -1);
return ret;
}
--
2.43.0
On Sun, 22 Jun 2025 at 22:36, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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-stable@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> target/arm/tcg/translate-a64.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
> index bb49a2ce90..d7b0c81773 100644
> --- a/target/arm/tcg/translate-a64.c
> +++ b/target/arm/tcg/translate-a64.c
> @@ -1387,11 +1387,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));
> @@ -1400,6 +1397,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);
> +}
> +
> /*
> * Return <0 for non-supported element sizes, with MO_16 controlled by
> * FEAT_FP16; return 0 for fp disabled; otherwise return >0 for success.
> @@ -1450,11 +1452,20 @@ static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz)
> */
> bool sve_access_check(DisasContext *s)
> {
> - if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
> - bool ret;
> + bool ret;
>
> - assert(dc_isar_feature(aa64_sme, s));
> - ret = sme_sm_enabled_check(s);
> + switch (dc_isar_feature(aa64_sme, s)) {
> + case true:
Why this rather than
if (dc_isar_feature(aa64_sme, s)) {
?
> + if (s->pstate_sm) {
> + ret = sme_enabled_check(s);
> + } else if (!dc_isar_feature(aa64_sve, s)) {
> + ret = sme_sm_enabled_check(s);
> + } else {
> + break;
> + }
> + if (ret) {
> + ret = nonstreaming_check(s);
> + }
> s->sve_access_checked = (ret ? 1 : -1);
> return ret;
> }
Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
On 6/24/25 06:58, Peter Maydell wrote:
>> + switch (dc_isar_feature(aa64_sme, s)) {
>> + case true:
>
> Why this rather than
> if (dc_isar_feature(aa64_sme, s)) {
>
> ?
>
>> + if (s->pstate_sm) {
>> + ret = sme_enabled_check(s);
>> + } else if (!dc_isar_feature(aa64_sve, s)) {
>> + ret = sme_sm_enabled_check(s);
>> + } else {
>> + break;
>> + }
I used break instead of a goto, or replicating
>> + if (ret) {
>> + ret = nonstreaming_check(s);
>> + }
>> s->sve_access_checked = (ret ? 1 : -1);
>> return ret;
this block.
r~
© 2016 - 2025 Red Hat, Inc.