target/riscv: Create xl field in env
Current xlen has been used in helper functions and many other places. The computation of current xlen is not so trivial, so that we should recompute it as little as possible. Fortunately, xlen only changes in very seldom cases, such as exception, misa write, mstatus write, cpu reset, migration load. So that we can only recompute xlen in this places and cache it into CPURISCVState. Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20220120122050.41546-6-zhiwei_liu@c-sky.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
40f0c2046c
commit
440544e1cf
@ -413,6 +413,7 @@ static void riscv_cpu_reset(DeviceState *dev)
|
||||
/* mmte is supposed to have pm.current hardwired to 1 */
|
||||
env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
|
||||
#endif
|
||||
env->xl = riscv_cpu_mxl(env);
|
||||
cs->exception_index = RISCV_EXCP_NONE;
|
||||
env->load_res = -1;
|
||||
set_default_nan_mode(1, &env->fp_status);
|
||||
|
@ -146,6 +146,7 @@ struct CPURISCVState {
|
||||
uint32_t misa_mxl_max; /* max mxl for this cpu */
|
||||
uint32_t misa_ext; /* current extensions */
|
||||
uint32_t misa_ext_mask; /* max ext for this cpu */
|
||||
uint32_t xl; /* current xlen */
|
||||
|
||||
/* 128-bit helpers upper part return value */
|
||||
target_ulong retxh;
|
||||
@ -456,6 +457,36 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
|
||||
#else
|
||||
static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
|
||||
{
|
||||
RISCVMXL xl = env->misa_mxl;
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/*
|
||||
* When emulating a 32-bit-only cpu, use RV32.
|
||||
* When emulating a 64-bit cpu, and MXL has been reduced to RV32,
|
||||
* MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
|
||||
* back to RV64 for lower privs.
|
||||
*/
|
||||
if (xl != MXL_RV32) {
|
||||
switch (env->priv) {
|
||||
case PRV_M:
|
||||
break;
|
||||
case PRV_U:
|
||||
xl = get_field(env->mstatus, MSTATUS64_UXL);
|
||||
break;
|
||||
default: /* PRV_S | PRV_H */
|
||||
xl = get_field(env->mstatus, MSTATUS64_SXL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return xl;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encode LMUL to lmul as follows:
|
||||
* LMUL vlmul lmul
|
||||
|
@ -35,37 +35,6 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
|
||||
#endif
|
||||
}
|
||||
|
||||
static RISCVMXL cpu_get_xl(CPURISCVState *env)
|
||||
{
|
||||
#if defined(TARGET_RISCV32)
|
||||
return MXL_RV32;
|
||||
#elif defined(CONFIG_USER_ONLY)
|
||||
return MXL_RV64;
|
||||
#else
|
||||
RISCVMXL xl = riscv_cpu_mxl(env);
|
||||
|
||||
/*
|
||||
* When emulating a 32-bit-only cpu, use RV32.
|
||||
* When emulating a 64-bit cpu, and MXL has been reduced to RV32,
|
||||
* MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
|
||||
* back to RV64 for lower privs.
|
||||
*/
|
||||
if (xl != MXL_RV32) {
|
||||
switch (env->priv) {
|
||||
case PRV_M:
|
||||
break;
|
||||
case PRV_U:
|
||||
xl = get_field(env->mstatus, MSTATUS64_UXL);
|
||||
break;
|
||||
default: /* PRV_S | PRV_H */
|
||||
xl = get_field(env->mstatus, MSTATUS64_SXL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, uint32_t *pflags)
|
||||
{
|
||||
@ -148,7 +117,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
|
||||
}
|
||||
#endif
|
||||
|
||||
flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
|
||||
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
|
||||
|
||||
*pflags = flags;
|
||||
}
|
||||
@ -364,6 +333,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
|
||||
}
|
||||
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
|
||||
env->priv = newpriv;
|
||||
env->xl = cpu_recompute_xl(env);
|
||||
|
||||
/*
|
||||
* Clear the load reservation - otherwise a reservation placed in one
|
||||
|
@ -589,6 +589,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
|
||||
mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
|
||||
}
|
||||
env->mstatus = mstatus;
|
||||
env->xl = cpu_recompute_xl(env);
|
||||
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
@ -704,6 +705,7 @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
|
||||
/* flush translation cache */
|
||||
tb_flush(env_cpu(env));
|
||||
env->misa_ext = val;
|
||||
env->xl = riscv_cpu_mxl(env);
|
||||
return RISCV_EXCP_NONE;
|
||||
}
|
||||
|
||||
|
@ -214,10 +214,20 @@ static const VMStateDescription vmstate_kvmtimer = {
|
||||
}
|
||||
};
|
||||
|
||||
static int riscv_cpu_post_load(void *opaque, int version_id)
|
||||
{
|
||||
RISCVCPU *cpu = opaque;
|
||||
CPURISCVState *env = &cpu->env;
|
||||
|
||||
env->xl = cpu_recompute_xl(env);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const VMStateDescription vmstate_riscv_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.post_load = riscv_cpu_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
|
||||
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
|
||||
|
Loading…
Reference in New Issue
Block a user