riscv: preserve fflags when rejecting a reserved frm value - #280
riscv: preserve fflags when rejecting a reserved frm value#280carlosqwqqwq wants to merge 2 commits into
Conversation
| return; | ||
| // Invalid rounding mode written: keep the old FRM value per | ||
| // WARL semantics, but still apply the other fields of fcsr | ||
| new_fcsr = bit_replace(new_fcsr, 5, 3, old_frm); |
There was a problem hiding this comment.
Maybe reconstruct new_fcsr from the patched new_frm/new_fflags once at writeback so that this isn't a path uncovered by most tests?
There was a problem hiding this comment.
Thanks! Reworked: fcsr is now reconstructed from the patched frm/fflags once at writeback (vm->csr.fcsr = (new_fcsr & ~CSR_FCSR_MASK) | new_fflags | (new_frm << 5)), so the reserved-frm path shares the same writeback as every other path. Rebuilt cleanly and force-pushed.
93b0a47 to
9e96a86
Compare
|
I reworked this at head |
| vm->csr.fcsr = new_fcsr; | ||
| // Reconstruct fcsr from the patched frm/fflags so every path shares | ||
| // the same writeback (reserved frm keeps the old value via WARL) | ||
| vm->csr.fcsr = (new_fcsr & ~CSR_FCSR_MASK) | new_fflags | (new_frm << 5); |
There was a problem hiding this comment.
Is (new_fcsr & ~CSR_FCSR_MASK) | necessary here? I would assume all of those bits are either zero or zeroed on read, would you be able to verify whether that's the case?
There was a problem hiding this comment.
Yes, this mask is necessary for architectural compatibility.
The current RISC-V F extension specification defines fcsr[31:8] as reserved for other standard extensions and explicitly says that standard software should preserve those bits. An implementation without those extensions may read them as zero, but RVVM must not discard them during a read-modify-write path when a future/implemented extension uses them. CSR_FCSR_MASK is 0x000000ff, so:
(new_fcsr & ~CSR_FCSR_MASK) | new_fflags | (new_frm << 5)
preserves the non-F-extension portion while replacing only frm and fflags with their validated values. I also removed the misleading WARL wording from the comments; the code preserves RVVM's existing invalid-frm policy while still applying the remaining fields.
The updated head is 18014ab. It builds successfully with make -j2 in the x86_64 lab container.
Reference: https://github.com/riscv/riscv-isa-manual/blob/main/src/unpriv/f-st-ext.adoc
There was a problem hiding this comment.
We already mask it here though, so only handling the mask in this location doesn't look sufficient. Regardless, I think the intention of CSR_FCSR_MASK is to contain all important bits, including those provided by extensions, so keeping bits outside of the mask is useless anyway.
It's reasonable to ask if this snippet can be written in such a way that it won't have to be updated if extensions are implemented, but since this is the function that handles FCSR changes, that looks like exactly the place that should worry about the entirety of defined bits. So I think it's fine to just drop the masking here, under the assumption that if a new extension is added, this function is going to be the first place that we'll need to touch anyway.
|
Pushed follow-up commit The functional writeback remains:
This preserves Please re-review the updated head when convenient. |
riscv: preserve fflags when rejecting a reserved frm value
Fixes #274
Commit message
Description
riscv_update_fcsr()currently returns before committing the writablefflagsfield when the incomingfrmvalue is reserved. Keep the old/WARLfrmvalue and continue applying the independentfflagsbits. The change is limited tosrc/cpu/riscv_csr.c; the probe and research logs are not part of the upstream change.Validation