target/arm: Add SVE state to TB->FLAGS
Add both SVE exception state and vector length. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20180123035349.24538-6-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
5be5e8eda7
commit
1db5e96c54
@ -2678,6 +2678,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
|
||||
#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
|
||||
#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */
|
||||
#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
|
||||
#define ARM_TBFLAG_SVEEXC_EL_SHIFT 2
|
||||
#define ARM_TBFLAG_SVEEXC_EL_MASK (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
|
||||
#define ARM_TBFLAG_ZCR_LEN_SHIFT 4
|
||||
#define ARM_TBFLAG_ZCR_LEN_MASK (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
|
||||
|
||||
/* some convenience accessor macros */
|
||||
#define ARM_TBFLAG_AARCH64_STATE(F) \
|
||||
@ -2714,6 +2718,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
|
||||
(((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
|
||||
#define ARM_TBFLAG_TBI1(F) \
|
||||
(((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
|
||||
#define ARM_TBFLAG_SVEEXC_EL(F) \
|
||||
(((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
|
||||
#define ARM_TBFLAG_ZCR_LEN(F) \
|
||||
(((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
|
||||
|
||||
static inline bool bswap_code(bool sctlr_b)
|
||||
{
|
||||
|
@ -12059,14 +12059,37 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, uint32_t *pflags)
|
||||
{
|
||||
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
|
||||
int fp_el = fp_exception_el(env);
|
||||
uint32_t flags;
|
||||
|
||||
if (is_a64(env)) {
|
||||
int sve_el = sve_exception_el(env);
|
||||
uint32_t zcr_len;
|
||||
|
||||
*pc = env->pc;
|
||||
flags = ARM_TBFLAG_AARCH64_STATE_MASK;
|
||||
/* Get control bits for tagged addresses */
|
||||
flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
|
||||
flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
|
||||
flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
|
||||
|
||||
/* If SVE is disabled, but FP is enabled,
|
||||
then the effective len is 0. */
|
||||
if (sve_el != 0 && fp_el == 0) {
|
||||
zcr_len = 0;
|
||||
} else {
|
||||
int current_el = arm_current_el(env);
|
||||
|
||||
zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
|
||||
zcr_len &= 0xf;
|
||||
if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
|
||||
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
|
||||
}
|
||||
if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
|
||||
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
|
||||
}
|
||||
}
|
||||
flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
|
||||
} else {
|
||||
*pc = env->regs[15];
|
||||
flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
|
||||
@ -12109,7 +12132,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|
||||
if (arm_cpu_data_is_big_endian(env)) {
|
||||
flags |= ARM_TBFLAG_BE_DATA_MASK;
|
||||
}
|
||||
flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
|
||||
flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
|
||||
|
||||
if (arm_v7m_is_handler_mode(env)) {
|
||||
flags |= ARM_TBFLAG_HANDLER_MASK;
|
||||
|
@ -12058,6 +12058,8 @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
|
||||
dc->user = (dc->current_el == 0);
|
||||
#endif
|
||||
dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
|
||||
dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
|
||||
dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
|
||||
dc->vec_len = 0;
|
||||
dc->vec_stride = 0;
|
||||
dc->cp_regs = arm_cpu->cp_regs;
|
||||
|
@ -29,6 +29,8 @@ typedef struct DisasContext {
|
||||
bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
|
||||
bool ns; /* Use non-secure CPREG bank on access */
|
||||
int fp_excp_el; /* FP exception EL or 0 if enabled */
|
||||
int sve_excp_el; /* SVE exception EL or 0 if enabled */
|
||||
int sve_len; /* SVE vector length in bytes */
|
||||
/* Flag indicating that exceptions from secure mode are routed to EL3. */
|
||||
bool secure_routed_to_el3;
|
||||
bool vfp_enabled; /* FP enabled via FPSCR.EN */
|
||||
|
Loading…
Reference in New Issue
Block a user