target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags

We are close to running out of TB flags for AArch32; we could
start using the cs_base word, but before we do that we can
economise on our usage by sharing the same bits for the VFP
VECSTRIDE field and the XScale XSCALE_CPAR field. This
works because no XScale CPU ever had VFP.

Backports commit ea7ac69d124c94c6e5579145e727adec9ccbefef from qemu
This commit is contained in:
Peter Maydell 2019-04-30 10:43:46 -04:00 committed by Lioncash
parent 3c1f3548c4
commit 8d726490ff
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
4 changed files with 25 additions and 7 deletions

View file

@ -769,6 +769,13 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
set_feature(env, ARM_FEATURE_THUMB_DSP);
}
/*
* We rely on no XScale CPU having VFP so we can use the same bits in the
* TB flags field for VECSTRIDE and XSCALE_CPAR.
*/
assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
arm_feature(env, ARM_FEATURE_XSCALE)));
if (cpu->reset_hivecs) {
cpu->reset_sctlr |= (1 << 13);
}

View file

@ -3095,6 +3095,12 @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
FIELD(TBFLAG_A32, THUMB, 0, 1)
FIELD(TBFLAG_A32, VECLEN, 1, 3)
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
/*
* We store the bottom two bits of the CPAR as TB flags and handle
* checks on the other bits at runtime. This shares the same bits as
* VECSTRIDE, which is OK as no XScale CPU has VFP.
*/
FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
/*
* Indicates whether cp register reads and writes by guest code should access
* the secure or nonsecure bank of banked registers; note that this is not
@ -3104,10 +3110,6 @@ FIELD(TBFLAG_A32, NS, 6, 1)
FIELD(TBFLAG_A32, VFPEN, 7, 1)
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
/* We store the bottom two bits of the CPAR as TB flags and handle
* checks on the other bits at runtime
*/
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
/* For M profile only, Handler (ie not Thread) mode */
FIELD(TBFLAG_A32, HANDLER, 21, 1)
/* For M profile only, whether we should generate stack-limit checks */

View file

@ -13166,7 +13166,11 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
}
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
/* Note that XSCALE_CPAR shares bits with VECSTRIDE */
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
flags = FIELD_DP32(flags, TBFLAG_A32,
XSCALE_CPAR, env->cp15.c15_cpar);
}
}
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));

View file

@ -13509,8 +13509,13 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
dc->vec_stride = 0;
} else {
dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
dc->c15_cpar = 0;
}
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
regime_is_secure(env, dc->mmu_idx);