target/riscv: don't read CSR in riscv_csrrw_do64

As per ISA:

"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
shall not cause any of the side effects that might occur on a CSR read."

trans_csrrwi() and trans_csrrw() call do_csrw() if rd=x0, do_csrw() calls
riscv_csrrw_do64(), via helper_csrw() passing NULL as *ret_value.

Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Nikita Shubin 2023-08-08 12:09:14 +03:00 committed by Alistair Francis
parent 4df282335b
commit e7a03409f2
1 changed files with 15 additions and 9 deletions

View File

@ -3917,21 +3917,27 @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
target_ulong write_mask) target_ulong write_mask)
{ {
RISCVException ret; RISCVException ret;
target_ulong old_value; target_ulong old_value = 0;
/* execute combined read/write operation if it exists */ /* execute combined read/write operation if it exists */
if (csr_ops[csrno].op) { if (csr_ops[csrno].op) {
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask); return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
} }
/* if no accessor exists then return failure */ /*
if (!csr_ops[csrno].read) { * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
return RISCV_EXCP_ILLEGAL_INST; * and we can't throw side effects caused by CSR reads.
} */
/* read old value */ if (ret_value) {
ret = csr_ops[csrno].read(env, csrno, &old_value); /* if no accessor exists then return failure */
if (ret != RISCV_EXCP_NONE) { if (!csr_ops[csrno].read) {
return ret; return RISCV_EXCP_ILLEGAL_INST;
}
/* read old value */
ret = csr_ops[csrno].read(env, csrno, &old_value);
if (ret != RISCV_EXCP_NONE) {
return ret;
}
} }
/* write value if writable and write mask set, otherwise drop writes */ /* write value if writable and write mask set, otherwise drop writes */