diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:36:01 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:36:01 +0100 |
commit | ea7ac69d124c94c6e5579145e727adec9ccbefef (patch) | |
tree | bbfab88c96e2aca57c559f5c0a19797d0f8f919c | |
parent | 7fbb535f7aeb22896fedfcf18a1eeff48165f1d7 (diff) | |
download | qemu-ea7ac69d124c94c6e5579145e727adec9ccbefef.zip qemu-ea7ac69d124c94c6e5579145e727adec9ccbefef.tar.gz qemu-ea7ac69d124c94c6e5579145e727adec9ccbefef.tar.bz2 |
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.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
-rw-r--r-- | target/arm/cpu.c | 7 | ||||
-rw-r--r-- | target/arm/cpu.h | 10 | ||||
-rw-r--r-- | target/arm/helper.c | 6 | ||||
-rw-r--r-- | target/arm/translate.c | 9 |
4 files changed, 25 insertions, 7 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index be81e19..7deccda 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1034,6 +1034,13 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) 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 (arm_feature(env, ARM_FEATURE_V7) && !arm_feature(env, ARM_FEATURE_M) && !arm_feature(env, ARM_FEATURE_PMSA)) { diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0ea4480..99ccb48 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3139,6 +3139,12 @@ 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 * the same thing as the current security state of the processor! @@ -3147,10 +3153,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 */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 14604f4..9be5fe5 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -13370,7 +13370,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)); diff --git a/target/arm/translate.c b/target/arm/translate.c index 0747f78..ffaa4f1 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -13330,8 +13330,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); |