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>
/* 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);
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;
}
#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
#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)
{
}
#endif
- flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
+ flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
*pflags = flags;
}
}
/* 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
mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
}
env->mstatus = mstatus;
+ env->xl = cpu_recompute_xl(env);
return RISCV_EXCP_NONE;
}
/* flush translation cache */
tb_flush(env_cpu(env));
env->misa_ext = val;
+ env->xl = riscv_cpu_mxl(env);
return RISCV_EXCP_NONE;
}
}
};
+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),