target/arm: Add arm_rebuild_hflags

This function assumes nothing about the current state of the cpu,
and writes the computed value to env->hflags.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20191023150057.25731-13-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2019-10-23 11:00:45 -04:00 committed by Peter Maydell
parent 0a54d68e21
commit 3d74e2e9ff
2 changed files with 28 additions and 8 deletions

View file

@ -3297,6 +3297,12 @@ void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void
*opaque);
/**
* arm_rebuild_hflags:
* Rebuild the cached TBFLAGS for arbitrary changed processor state.
*/
void arm_rebuild_hflags(CPUARMState *env);
/**
* aa32_vfp_dreg:
* Return a pointer to the Dn register within env in 32-bit mode.

View file

@ -11198,17 +11198,35 @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
}
static uint32_t rebuild_hflags_internal(CPUARMState *env)
{
int el = arm_current_el(env);
int fp_el = fp_exception_el(env, el);
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
if (is_a64(env)) {
return rebuild_hflags_a64(env, el, fp_el, mmu_idx);
} else if (arm_feature(env, ARM_FEATURE_M)) {
return rebuild_hflags_m32(env, fp_el, mmu_idx);
} else {
return rebuild_hflags_a32(env, fp_el, mmu_idx);
}
}
void arm_rebuild_hflags(CPUARMState *env)
{
env->hflags = rebuild_hflags_internal(env);
}
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *pflags)
{
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
int current_el = arm_current_el(env);
int fp_el = fp_exception_el(env, current_el);
uint32_t flags, pstate_for_ss;
flags = rebuild_hflags_internal(env);
if (is_a64(env)) {
*pc = env->pc;
flags = rebuild_hflags_a64(env, current_el, fp_el, mmu_idx);
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
}
@ -11217,8 +11235,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
*pc = env->regs[15];
if (arm_feature(env, ARM_FEATURE_M)) {
flags = rebuild_hflags_m32(env, fp_el, mmu_idx);
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
!= env->v7m.secure) {
@ -11242,8 +11258,6 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
}
} else {
flags = rebuild_hflags_a32(env, fp_el, mmu_idx);
/*
* Note that XSCALE_CPAR shares bits with VECSTRIDE.
* Note that VECLEN+VECSTRIDE are RES0 for M-profile.