Skip to content

fadd/fmul/fdiv leak qNaN payloads instead of returning canonical NaNs #254

Description

@carlosqwqqwq

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions