Skip to content

fpu: round integer-to-float conversions with RMM ties-away - #269

Open
carlosqwqqwq wants to merge 1 commit into
LekKit:stagingfrom
carlosqwqqwq:fix/fcvt-int2float-rmm
Open

carlosqwqqwq wants to merge 1 commit into
LekKit:stagingfrom
carlosqwqqwq:fix/fcvt-int2float-rmm

Conversation

@carlosqwqqwq

@carlosqwqqwq carlosqwqqwq commented Aug 12, 2026 •

Copy link
Copy Markdown

fpu: round integer-to-float conversions with RMM ties-away

Fixes #264

Commit message

fpu: round integer-to-float conversions with RMM ties-away

Description

The integer-to-float conversions (fcvt.s.w[u]/l[u], fcvt.d.w[u]/l[u]) use plain host casts, which only provide RNE. Under RMM (static rm=RMM or dyn + frm=RMM) the exact-halfway cases must round away from zero; the current code returns the RNE neighbour. Add magnitude-based RMM conversion helpers in src/util/fpu_lib.h (exact for inputs that fit, otherwise one rounded significand with ties-away and explicit NX), and select them from src/cpu/riscv_fpu.c when the effective mode is RMM. fcvt.d.l also now passes the resolved dynamic mode to the existing fpu_round_i64_to_f64. This is a separate source path from the float-to-integer conversion fix (the conversion direction and helpers differ), from the arithmetic RMM synthesis, and from the FMA rounding repairs.

Validation

  • Halfway-input probes under static RMM and dyn + frm=RMM match native RISC-V hardware and QEMU.
  • RNE/RDN/RUP controls and the existing conversion boundary cases are unchanged.

@carlosqwqqwq
carlosqwqqwq force-pushed the fix/fcvt-int2float-rmm branch from 4aadf14 to 14eb554 Compare September 6, 2026 06:38
@LekKit

LekKit commented Sep 22, 2026

Copy link
Copy Markdown
Owner

fpu_fcvt_mag_to_f32_rmm() only normalizes the significand on the exp > 23 branch. When the magnitude fits into 24 bits, sig is emitted as-is with the leading bit not aligned to bit 23, so every integer below 2^24 converts to garbage under RMM (static rm=rmm or dyn with frm=RMM):

fcvt.s.w   35  rmm    got 0x42000023 (~32.00002)   expected 0x420c0000 (35.0)
fcvt.s.w   -1  rmm    got 0xbf800001               expected 0xbf800000
fcvt.s.wu  35  rmm    got 0x42000023               expected 0x420c0000

Fix (mirrors fpu_round_i64_to_f64()):

uint64_t sig = (exp <= 23) ? (mag << (23 - exp)) : mag;

With that change all four helpers pass the same probe with zero mismatches.

Nitpick: don't add five single-mode functions. Generalize the existing fpu_round_i64_to_f64() into a (magnitude, sign, rm) helper for f64 and add the f32 counterpart, then call it from all eight fcvt.{s,d}.{w,wu,l,lu} cases whenever the effective mode is RMM. fcvt.d.w/fcvt.d.wu are exact and need nothing, as the PR already assumes.

Style: ((rm == 0x07) ? vm->csr.fcsr >> 5 : rm) is repeated six times; compute eff_rm once (#260 already introduces it, use when merged).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RV64 fcvt.* rounds exact halfway inputs as RNE under RMM

2 participants