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.

The revised implementation uses one magnitude/sign/rm helper per precision, normalizes the significand for magnitudes below 2^24, and reuses the already resolved eff_rm value for both static and dynamic rounding modes.

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.

The revised patch was applied to current staging and rebuilt with -Werror. QEMU and both RVVM execution modes agree on the focused static and dynamic cases: 35 -> 0x420c0000 and -1 -> 0xbf800000.

@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).

@carlosqwqqwq
carlosqwqqwq force-pushed the fix/fcvt-int2float-rmm branch from 14eb554 to 5fcf4f6 Compare October 8, 2026 14:10
@carlosqwqqwq
carlosqwqqwq force-pushed the fix/fcvt-int2float-rmm branch from 5fcf4f6 to 3ce1c34 Compare October 13, 2026 07:48
@carlosqwqqwq

Copy link
Copy Markdown
Author

Rebased onto current staging (e7214efa) and force-updated the branch to 3ce1c343. The requested shared magnitude/sign helpers are retained, including significand normalization for magnitudes below 2^24 and the single eff_rm path. The Linux x86_64 make bin build passes; please re-review the updated head.

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