diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2022-07-08 20:45:10 +0530 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2022-07-11 13:19:35 +0100 |
commit | 3d74825f4d68a54cf1cd772dda8b502695b2d783 (patch) | |
tree | 6861efa8cc2e0de75d28191cdc5acdab570c7d8d /target | |
parent | 3ebc26e79d05cf53129e283529cf3bc8a5c5953e (diff) |
target/arm: Add SME enablement checks
These functions will be used to verify that the cpu
is in the correct state for a given instruction.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220708151540.18136-16-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/translate-a64.c | 34 | ||||
-rw-r--r-- | target/arm/translate-a64.h | 21 |
2 files changed, 55 insertions, 0 deletions
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 7fab7f64f8..b16d81bf19 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -1216,6 +1216,40 @@ static bool sme_access_check(DisasContext *s) return true; } +/* This function corresponds to CheckSMEEnabled. */ +bool sme_enabled_check(DisasContext *s) +{ + /* + * Note that unlike sve_excp_el, we have not constrained sme_excp_el + * to be zero when fp_excp_el has priority. This is because we need + * sme_excp_el by itself for cpregs access checks. + */ + if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) { + s->fp_access_checked = true; + return sme_access_check(s); + } + return fp_access_check_only(s); +} + +/* Common subroutine for CheckSMEAnd*Enabled. */ +bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req) +{ + if (!sme_enabled_check(s)) { + return false; + } + if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) { + gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + syn_smetrap(SME_ET_NotStreaming, false)); + return false; + } + if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) { + gen_exception_insn(s, s->pc_curr, EXCP_UDEF, + syn_smetrap(SME_ET_InactiveZA, false)); + return false; + } + return true; +} + /* * This utility function is for doing register extension with an * optional shift. You will likely want to pass a temporary for the diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h index 789b6e8e78..02fb95e019 100644 --- a/target/arm/translate-a64.h +++ b/target/arm/translate-a64.h @@ -29,6 +29,27 @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v); bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn, unsigned int imms, unsigned int immr); bool sve_access_check(DisasContext *s); +bool sme_enabled_check(DisasContext *s); +bool sme_enabled_check_with_svcr(DisasContext *s, unsigned); + +/* This function corresponds to CheckStreamingSVEEnabled. */ +static inline bool sme_sm_enabled_check(DisasContext *s) +{ + return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK); +} + +/* This function corresponds to CheckSMEAndZAEnabled. */ +static inline bool sme_za_enabled_check(DisasContext *s) +{ + return sme_enabled_check_with_svcr(s, R_SVCR_ZA_MASK); +} + +/* Note that this function corresponds to CheckStreamingSVEAndZAEnabled. */ +static inline bool sme_smza_enabled_check(DisasContext *s) +{ + return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK | R_SVCR_ZA_MASK); +} + TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr); TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write, bool tag_checked, int log2_size); |