[PATCH 0/2] target/riscv: Fix mstatus.FS dirty tracking for FP exception-raising instructions

Max Chou posted 2 patches 1 month, 2 weeks ago
Failed in applying to current master (apply log)
target/riscv/cpu.h           |   1 +
target/riscv/fpu_helper.c    | 157 +++++++++++++++++++----
target/riscv/vector_helper.c | 241 +++++++++++++++++++----------------
3 files changed, 258 insertions(+), 141 deletions(-)
[PATCH 0/2] target/riscv: Fix mstatus.FS dirty tracking for FP exception-raising instructions
Posted by Max Chou 1 month, 2 weeks ago
The RISC-V privileged architecture specification 3.1.6 defines
mstatus.FS that

  "The FS field encodes the status of the floating-point unit state,
   including the floating-point registers f0–f31 and the CSRs fcsr,
   frm, and fflags."

Any instruction that modifies this state must transition mstatus.FS
to dirty. In particular, fflags is part of the tracked state, so any
instruction that sets a new bit in fflags (e.g. raises a FP exception
flag — must set mstatus.FS to dirty).

But current implementation was failing to set mstatus.FS to dirty:

1. Scalar FP instructions that write integer registers (comparisons
   and FP-to-integer conversions):

Instructions such as FEQ.S, FLT.D, FLE.H, FCVT.W.S, FCVT.WU.D,
and FCVTMOD.W.D write their results to integer registers, so
mark_fs_dirty is correctly not called to set fs to dirty at
translation time. However, following scalar instructions may raise FP
exception flags:
- Comparisons: fle/fleq/flt/fltq/feq
  — raise NV on NaN operands
- FP-to-integer: fcvt.[w|wu|l|lu]/fcvtmod.w.d
  — raise NX on inexact or NV on out-of-range

2. Vector FP instructions (all arithmetic, comparison, conversion, and
   reduction operations in the V extension):

When a vector FP instruction raises a FP exception (e.g., vfdiv.vv
producing a divide-by-zero, or vmflt.vv comparing NaN values), it
modifies fflags — an FP CSR — but current implementation did not dirty
mstatus.FS.

This patchset fixes this issue by
1. Save float_exception_flags before the softfloat operation
2. Perform the operation
3. If any new exception bits are set, set fs to dirty

Max Chou (2):
  target/riscv: Set mstatus.FS dirty when scalar FP raises exceptions
  target/riscv: rvv: Set mstatus.FS dirty when vector FP raises
    exceptions

 target/riscv/cpu.h           |   1 +
 target/riscv/fpu_helper.c    | 157 +++++++++++++++++++----
 target/riscv/vector_helper.c | 241 +++++++++++++++++++----------------
 3 files changed, 258 insertions(+), 141 deletions(-)

-- 
2.43.7


Re: [PATCH 0/2] target/riscv: Fix mstatus.FS dirty tracking for FP exception-raising instructions
Posted by Alistair Francis 1 month, 2 weeks ago
On Thu, Jun 11, 2026 at 8:52 PM Max Chou <max.chou@sifive.com> wrote:
>
> The RISC-V privileged architecture specification 3.1.6 defines
> mstatus.FS that
>
>   "The FS field encodes the status of the floating-point unit state,
>    including the floating-point registers f0–f31 and the CSRs fcsr,
>    frm, and fflags."
>
> Any instruction that modifies this state must transition mstatus.FS
> to dirty. In particular, fflags is part of the tracked state, so any
> instruction that sets a new bit in fflags (e.g. raises a FP exception
> flag — must set mstatus.FS to dirty).
>
> But current implementation was failing to set mstatus.FS to dirty:
>
> 1. Scalar FP instructions that write integer registers (comparisons
>    and FP-to-integer conversions):
>
> Instructions such as FEQ.S, FLT.D, FLE.H, FCVT.W.S, FCVT.WU.D,
> and FCVTMOD.W.D write their results to integer registers, so
> mark_fs_dirty is correctly not called to set fs to dirty at
> translation time. However, following scalar instructions may raise FP
> exception flags:
> - Comparisons: fle/fleq/flt/fltq/feq
>   — raise NV on NaN operands
> - FP-to-integer: fcvt.[w|wu|l|lu]/fcvtmod.w.d
>   — raise NX on inexact or NV on out-of-range
>
> 2. Vector FP instructions (all arithmetic, comparison, conversion, and
>    reduction operations in the V extension):
>
> When a vector FP instruction raises a FP exception (e.g., vfdiv.vv
> producing a divide-by-zero, or vmflt.vv comparing NaN values), it
> modifies fflags — an FP CSR — but current implementation did not dirty
> mstatus.FS.
>
> This patchset fixes this issue by
> 1. Save float_exception_flags before the softfloat operation
> 2. Perform the operation
> 3. If any new exception bits are set, set fs to dirty
>
> Max Chou (2):
>   target/riscv: Set mstatus.FS dirty when scalar FP raises exceptions
>   target/riscv: rvv: Set mstatus.FS dirty when vector FP raises
>     exceptions

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  target/riscv/cpu.h           |   1 +
>  target/riscv/fpu_helper.c    | 157 +++++++++++++++++++----
>  target/riscv/vector_helper.c | 241 +++++++++++++++++++----------------
>  3 files changed, 258 insertions(+), 141 deletions(-)
>
> --
> 2.43.7
>
>