RISC-V Floating-Point Context: Save fcsr and Registers Under the FS State Contract
Two tasks use floating-point arithmetic correctly in isolation, but results change after a context switch. Saving the floating-point data registers is necessary, yet incomplete if rounding mode and accrued exception flags remain owned by the previous task.
On RISC-V, the FS status field tracks the broader floating-point context. It is a context-management contract, not a command that clears registers or a precise history of arithmetic operations.
Include fcsr in the context definition
The F 2.2 specification defines the floating-point registers and fcsr. The latter contains the dynamic rounding mode and accrued exception flags, also exposed through frm and fflags.
A task can therefore alter floating-point behavior without leaving a distinctive new value in the data register a test happens to inspect. Saving only f0 through f31 can leak rounding state or flags between contexts. Match the saved register width to the implemented floating-point configuration; this F-only discussion does not prescribe a complete save layout for every wider extension.
Use tasks with deliberately different supported rounding settings and register patterns in a proposed context-switch test. Check the control state and exception flags as well as numerical output. An ordinary arithmetic example using the default rounding mode can miss an incomplete save path.
Interpret Off, Initial, Clean and Dirty correctly
The Machine-Level ISA extension-status rules include fcsr, frm, fflags and the floating-point registers in FS-managed state.
With FS Off, instructions that access that state raise an illegal-instruction exception. Initial means the context should have its initial constant state. Clean means it matches the last saved context, while Dirty means it may have changed since that save.
Changing FS itself does not change the register contents. Setting FS to Initial does not clear data left by another context, and setting it Off does not erase that state. A restore path choosing Initial must actually establish the defined initial values before exposing the unit to a new context.
This distinction is especially important in lazy ownership schemes. A first-use trap is an opportunity for the runtime to establish ownership and restore or initialize state; it is not evidence that the hardware already created a clean task context.

Dirty is a conservative save signal
The architecture permits imprecise dirty tracking. An implementation may mark state Dirty even when its contents did not change. Some implementations support only Off and Dirty, turning attempts to select Initial or Clean into Dirty.
Treat a dirty result as a reason to preserve the state required by the runtime's policy, not as an exact count or proof of floating-point computation. An optimization that assumes Clean must remain readable after a write is not portable without checking the implemented behavior.
Likewise, a save/restore implementation must inspect the relevant pre-save state before its own instructions alter it. The state-management code itself can access floating-point registers and control state, so ordering and ownership matter.
Distinguish call preservation from asynchronous preemption
A function-call convention describes which registers a callee must preserve at a call boundary. A task can be preempted between arbitrary instructions, including while values in caller-saved registers are live. A context switch cannot simply reuse the callee-saved subset as if every interruption were a normal call.
Review interrupt and exception paths that may use floating-point instructions while another task owns the hardware state. They need an explicit runtime policy, whether avoiding such use or preserving and restoring the affected context. Merely restoring FS afterward cannot undo overwritten data or fcsr.
The proposed acceptance check follows task ownership through initial use, dirty save, clean restore and intervening privileged code, with all relevant register and control state preserved. No scheduler, floating-point instruction or context-switch test was executed for this article.