riscv-isa-manual
riscv-isa-manual copied to clipboard
Unspecified behaviour with explicit writes to minstret on RV32
On RV32 if minstret the lower 32 bits of instret is 0xFFFFFFFF, and minstreth (the upper 32 bits) is 0. And then you do
csrw minstret, zero
What value would you expect minstreth to get? 0 or 1?
The two possibilities are:
0: You have explicitly written to instret, therefore the automatic increment is suppressed. As sort of indicated by this text:
Some CSRs, such as the instructions-retired counter, instret, may be modified as side effects of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the value prior to the execution of the instruction. If a CSR access instruction writes such a CSR, the write is done instead of the increment. In particular, a value written to instret by one instruction will be the value read by the following instruction. ... Furthermore, an explicit CSR read returns the CSR state before the execution of the instruction, while an explicit CSR write suppresses and overrides any implicit writes or modifications to the same CSR by the same instruction.
1: The instruction completes as usual, incrementing the counter, and then the write takes effect. As sort of indicated by this text:
Any CSR write takes effect after the writing instruction has otherwise completed.
I suspect the answer is 0, but it's not really clear because it talks about instret (which isn't actually the name of a CSR), and "the same CSR" - but is minstret the same CSR as minstreth on RV32?
The arch spec says:
Some CSRs, such as the instructions-retired counter, instret, may be modified as side effects of instruction execution. In these cases, if a CSR access instruction reads a CSR, it reads the value prior to the execution of the instruction. If a CSR access instruction writes such a CSR, the write is done instead of the increment. In particular, a value written to instret by one instruction will be the value read by the following instruction.
Yes I quoted that section. It's very clear for RV64 where instret (which isn't really a CSR) is exactly equal to minstret. But on RV32 it is split between minstret and minstreth, so the intended behaviour is not fully specified.