@@ -297,7 +297,7 @@ static RISCVException read_vxrm(CPURISCVState *env, int csrno,
static RISCVException write_vxrm(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->vxrm = val;
+ env->vxrm = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
return RISCV_EXCP_NONE;
}
@@ -311,7 +311,7 @@ static RISCVException read_vxsat(CPURISCVState *env, int csrno,
static RISCVException write_vxsat(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->vxsat = val;
+ env->vxsat = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
return RISCV_EXCP_NONE;
}
@@ -325,7 +325,7 @@ static RISCVException read_vstart(CPURISCVState *env, int csrno,
static RISCVException write_vstart(CPURISCVState *env, int csrno,
target_ulong val)
{
- env->vstart = val;
+ env->vstart = riscv_cpu_is_uxl32(env) ? val & UINT32_MAX : val;
return RISCV_EXCP_NONE;
}
@@ -493,6 +493,36 @@ static int validate_vm(CPURISCVState *env, target_ulong vm)
}
}
+static void uxl32_switch(CPURISCVState *env, target_ulong val)
+{
+ uint32_t old = get_field(env->mstatus, MSTATUS64_UXL);
+ uint32_t new = get_field(val, MSTATUS64_UXL);
+
+ if (old == new) {
+ return;
+ }
+
+ /*
+ * For the read-only bits of the previous-width CSR, the bits at the
+ * same positions in the temporary register are set to zeros.
+ */
+ if (env->misa & RVV) {
+ env->vl = 0;
+ env->vtype = 0;
+ }
+
+ /*
+ * If the new width W is narrower than the previous width, the
+ * least-significant W bits of the temporary register are retained and
+ * the more-significant bits are discarded.
+ */
+ if ((old == 2) && (new == 1)) {
+ if (env->misa & RVV) {
+ env->vtype &= UINT32_MAX;
+ }
+ }
+}
+
static RISCVException write_mstatus(CPURISCVState *env, int csrno,
target_ulong val)
{
@@ -502,13 +532,13 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
/* flush tlb on mstatus fields that affect VM */
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
- MSTATUS_MPRV | MSTATUS_SUM)) {
+ MSTATUS_MPRV | MSTATUS_SUM | MSTATUS64_UXL)) {
tlb_flush(env_cpu(env));
}
mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
- MSTATUS_TW;
+ MSTATUS_TW | MSTATUS64_UXL;
if (!riscv_cpu_is_32bit(env)) {
/*
@@ -518,6 +548,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
mask |= MSTATUS_MPV | MSTATUS_GVA;
}
+ uxl32_switch(env, val);
+
mstatus = (mstatus & ~mask) | (val & mask);
dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> --- target/riscv/csr.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-)