@@ -314,7 +314,8 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
int csrno = dump_csrs[i];
target_ulong val = 0;
- RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+ RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0,
+ false);
/*
* Rely on the smode, hmode, etc, predicates within csr.c
@@ -624,22 +624,24 @@ void riscv_cpu_update_mask(CPURISCVState *env);
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask);
+ target_ulong new_value, target_ulong write_mask,
+ bool write_op);
RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value,
- target_ulong write_mask);
+ target_ulong write_mask, bool write_op);
static inline void riscv_csr_write(CPURISCVState *env, int csrno,
target_ulong val)
{
- riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS));
+ riscv_csrrw(env, csrno, NULL, val, MAKE_64BIT_MASK(0, TARGET_LONG_BITS),
+ true);
}
static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
{
target_ulong val = 0;
- riscv_csrrw(env, csrno, &val, 0, 0);
+ riscv_csrrw(env, csrno, &val, 0, 0, false);
return val;
}
@@ -656,7 +658,8 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
Int128 *ret_value,
- Int128 new_value, Int128 write_mask);
+ Int128 new_value, Int128 write_mask,
+ bool write_op);
typedef RISCVException (*riscv_csr_read128_fn)(CPURISCVState *env, int csrno,
Int128 *ret_value);
@@ -2973,7 +2973,8 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
int csrno,
bool write_mask,
- RISCVCPU *cpu)
+ RISCVCPU *cpu,
+ bool write_op)
{
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
int read_only = get_field(csrno, 0xC00) == 3;
@@ -2996,7 +2997,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
return RISCV_EXCP_ILLEGAL_INST;
}
#endif
- if (write_mask && read_only) {
+ if (write_op && read_only) {
return RISCV_EXCP_ILLEGAL_INST;
}
@@ -3020,7 +3021,7 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value,
- target_ulong write_mask)
+ target_ulong write_mask, bool write_op)
{
RISCVException ret;
target_ulong old_value;
@@ -3040,8 +3041,8 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
return ret;
}
- /* write value if writable and write mask set, otherwise drop writes */
- if (write_mask) {
+ /* write value if writable and write_op set, otherwise drop writes */
+ if (write_op) {
new_value = (old_value & ~write_mask) | (new_value & write_mask);
if (csr_ops[csrno].write) {
ret = csr_ops[csrno].write(env, csrno, new_value);
@@ -3061,22 +3062,25 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
target_ulong *ret_value,
- target_ulong new_value, target_ulong write_mask)
+ target_ulong new_value, target_ulong write_mask,
+ bool write_op)
{
RISCVCPU *cpu = env_archcpu(env);
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu);
+ RISCVException ret = riscv_csrrw_check(env, csrno, write_mask, cpu,
+ write_op);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
- return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask);
+ return riscv_csrrw_do64(env, csrno, ret_value, new_value, write_mask,
+ write_op);
}
static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
Int128 *ret_value,
Int128 new_value,
- Int128 write_mask)
+ Int128 write_mask, bool write_op)
{
RISCVException ret;
Int128 old_value;
@@ -3087,8 +3091,8 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
return ret;
}
- /* write value if writable and write mask set, otherwise drop writes */
- if (int128_nz(write_mask)) {
+ /* write value if writable and write_op set, otherwise drop writes */
+ if (write_op) {
new_value = int128_or(int128_and(old_value, int128_not(write_mask)),
int128_and(new_value, write_mask));
if (csr_ops[csrno].write128) {
@@ -3115,18 +3119,20 @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
Int128 *ret_value,
- Int128 new_value, Int128 write_mask)
+ Int128 new_value, Int128 write_mask,
+ bool write_op)
{
RISCVException ret;
RISCVCPU *cpu = env_archcpu(env);
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu);
+ ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask), cpu, write_op);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
if (csr_ops[csrno].read128) {
- return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask);
+ return riscv_csrrw_do128(env, csrno, ret_value, new_value, write_mask,
+ write_op);
}
/*
@@ -3138,7 +3144,7 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
target_ulong old_value;
ret = riscv_csrrw_do64(env, csrno, &old_value,
int128_getlo(new_value),
- int128_getlo(write_mask));
+ int128_getlo(write_mask), write_op);
if (ret == RISCV_EXCP_NONE && ret_value) {
*ret_value = int128_make64(old_value);
}
@@ -3152,13 +3158,13 @@ RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
RISCVException riscv_csrrw_debug(CPURISCVState *env, int csrno,
target_ulong *ret_value,
target_ulong new_value,
- target_ulong write_mask)
+ target_ulong write_mask, bool write_op)
{
RISCVException ret;
#if !defined(CONFIG_USER_ONLY)
env->debugger = true;
#endif
- ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask);
+ ret = riscv_csrrw(env, csrno, ret_value, new_value, write_mask, write_op);
#if !defined(CONFIG_USER_ONLY)
env->debugger = false;
#endif
@@ -124,7 +124,7 @@ static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
* This also works for CSR_FRM and CSR_FCSR.
*/
result = riscv_csrrw_debug(env, n - 32, &val,
- 0, 0);
+ 0, 0, false);
if (result == RISCV_EXCP_NONE) {
return gdb_get_regl(buf, val);
}
@@ -147,7 +147,7 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
* This also works for CSR_FRM and CSR_FCSR.
*/
result = riscv_csrrw_debug(env, n - 32, NULL,
- val, -1);
+ val, -1, true);
if (result == RISCV_EXCP_NONE) {
return sizeof(target_ulong);
}
@@ -209,7 +209,7 @@ static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
}
target_ulong val = 0;
- int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+ int result = riscv_csrrw_debug(env, csrno, &val, 0, 0, false);
if (result == 0) {
return gdb_get_regl(buf, val);
@@ -236,7 +236,7 @@ static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
}
target_ulong val = ldtul_p(mem_buf);
- int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
+ int result = riscv_csrrw_debug(env, csrno, NULL, val, -1, true);
if (result == 0) {
return sizeof(target_ulong);
@@ -251,7 +251,7 @@ static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
target_ulong val = 0;
int result;
- result = riscv_csrrw_debug(env, n, &val, 0, 0);
+ result = riscv_csrrw_debug(env, n, &val, 0, 0, false);
if (result == RISCV_EXCP_NONE) {
return gdb_get_regl(buf, val);
}
@@ -265,7 +265,7 @@ static int riscv_gdb_set_csr(CPURISCVState *env, uint8_t *mem_buf, int n)
target_ulong val = ldtul_p(mem_buf);
int result;
- result = riscv_csrrw_debug(env, n, NULL, val, -1);
+ result = riscv_csrrw_debug(env, n, NULL, val, -1, true);
if (result == RISCV_EXCP_NONE) {
return sizeof(target_ulong);
}
@@ -40,7 +40,7 @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
target_ulong helper_csrr(CPURISCVState *env, int csr)
{
target_ulong val = 0;
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
+ RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0, false);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -51,7 +51,7 @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
{
target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
- RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
+ RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask, true);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -62,7 +62,7 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
target_ulong src, target_ulong write_mask)
{
target_ulong val = 0;
- RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
+ RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask, true);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -75,7 +75,7 @@ target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
Int128 rv = int128_zero();
RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
int128_zero(),
- int128_zero());
+ int128_zero(), false);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -90,7 +90,7 @@ void helper_csrw_i128(CPURISCVState *env, int csr,
{
RISCVException ret = riscv_csrrw_i128(env, csr, NULL,
int128_make128(srcl, srch),
- UINT128_MAX);
+ UINT128_MAX, true);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());
@@ -104,7 +104,7 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
Int128 rv = int128_zero();
RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
int128_make128(srcl, srch),
- int128_make128(maskl, maskh));
+ int128_make128(maskl, maskh), true);
if (ret != RISCV_EXCP_NONE) {
riscv_raise_exception(env, ret, GETPC());