target/riscv: Fix rmw_sip, rmw_vsip, rmw_hsip vs write-only operation

We distinguish write-only by passing ret_value as NULL.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 20210823195529.560295-17-richard.henderson@linaro.org
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Richard Henderson 2021-08-23 12:55:21 -07:00 committed by Alistair Francis
parent 6ecf39e2dd
commit 33979526ca

View File

@ -937,9 +937,12 @@ static RISCVException rmw_vsip(CPURISCVState *env, int csrno,
/* Shift the S bits to their VS bit location in mip */ /* Shift the S bits to their VS bit location in mip */
int ret = rmw_mip(env, 0, ret_value, new_value << 1, int ret = rmw_mip(env, 0, ret_value, new_value << 1,
(write_mask << 1) & vsip_writable_mask & env->hideleg); (write_mask << 1) & vsip_writable_mask & env->hideleg);
*ret_value &= VS_MODE_INTERRUPTS;
/* Shift the VS bits to their S bit location in vsip */ if (ret_value) {
*ret_value >>= 1; *ret_value &= VS_MODE_INTERRUPTS;
/* Shift the VS bits to their S bit location in vsip */
*ret_value >>= 1;
}
return ret; return ret;
} }
@ -956,7 +959,9 @@ static RISCVException rmw_sip(CPURISCVState *env, int csrno,
write_mask & env->mideleg & sip_writable_mask); write_mask & env->mideleg & sip_writable_mask);
} }
*ret_value &= env->mideleg; if (ret_value) {
*ret_value &= env->mideleg;
}
return ret; return ret;
} }
@ -1072,8 +1077,9 @@ static RISCVException rmw_hvip(CPURISCVState *env, int csrno,
int ret = rmw_mip(env, 0, ret_value, new_value, int ret = rmw_mip(env, 0, ret_value, new_value,
write_mask & hvip_writable_mask); write_mask & hvip_writable_mask);
*ret_value &= hvip_writable_mask; if (ret_value) {
*ret_value &= hvip_writable_mask;
}
return ret; return ret;
} }
@ -1084,8 +1090,9 @@ static RISCVException rmw_hip(CPURISCVState *env, int csrno,
int ret = rmw_mip(env, 0, ret_value, new_value, int ret = rmw_mip(env, 0, ret_value, new_value,
write_mask & hip_writable_mask); write_mask & hip_writable_mask);
*ret_value &= hip_writable_mask; if (ret_value) {
*ret_value &= hip_writable_mask;
}
return ret; return ret;
} }