mirror of
https://github.com/qemu/qemu.git
synced 2025-01-25 15:03:24 +08:00
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>
This commit is contained in:
parent
3ebc26e79d
commit
3d74825f4d
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user