Summary
fadd, fmul and fdiv preserve the input qNaN payload in the result instead of returning the canonical NaN required by the RISC-V specification. fsub returns a canonical NaN in the same probe, which shows this is a shared writeback-path problem rather than a global NaN-handling gap.
Expected behavior
Native RISC-V hardware and QEMU return the canonical NaN for fadd, fsub, fmul, fdiv and fsqrt:
single: 0xffffffff7fc00000
double: 0x7ff8000000000000
Observed behavior
single: fadd=0xffffffff7fc01234 fsub=0xffffffff7fc00000
fmul=0xffffffff7fc01234 fdiv=0xffffffff7fc01234
double: fadd=0x7ff8000000001234 fsub=0x7ff8000000000000
fmul=0x7ff8000000001234 fdiv=0x7ff8000000001234
Root cause
In src/cpu/riscv_fpu.c, fadd/fmul/fdiv use the riscv_emit_s/riscv_emit_d write path, while fsub uses riscv_write_s/riscv_write_d. The write helpers canonicalize NaNs before writeback; the emit helpers do not.
Suggested fix
Route the arithmetic writebacks through the same canonicalizing writers used by fsub.
No existing report for this behavior was found in the issue tracker.
Summary
fadd,fmulandfdivpreserve the input qNaN payload in the result instead of returning the canonical NaN required by the RISC-V specification.fsubreturns a canonical NaN in the same probe, which shows this is a shared writeback-path problem rather than a global NaN-handling gap.Expected behavior
Native RISC-V hardware and QEMU return the canonical NaN for
fadd,fsub,fmul,fdivandfsqrt:Observed behavior
Root cause
In
src/cpu/riscv_fpu.c,fadd/fmul/fdivuse theriscv_emit_s/riscv_emit_dwrite path, whilefsubusesriscv_write_s/riscv_write_d. The write helpers canonicalize NaNs before writeback; the emit helpers do not.Suggested fix
Route the arithmetic writebacks through the same canonicalizing writers used by
fsub.No existing report for this behavior was found in the issue tracker.