Implement RVV narrowing floating-point conversions

Closed
AL
2mo ago
+287-2

Implements the narrowing conversions from #734. Third of three PRs sharing
the VFUNARY0 decode site; best taken after #770 and #771.

Adds the eight vfncvt forms (V 1.0 §13.19), producing a 32-bit destination
element from a 64-bit source.

Unlike the widening direction, narrowing shares the overlap constraints of
the other narrowing instructions, so the existing
rvv_cross_eew_overlap_illegal() applies unchanged and this follows the
vnsrl_wv pattern.

vfncvt.rod.f.f.w rounds towards odd. SoftFloat is already built with
-D SOFTFLOAT_ROUND_ODD (mk/softfloat.mk), so softfloat_round_odd can be
selected directly; that was confirmed against the library before relying on
it. The three rounding behaviours (dynamic frm, RTZ, ROD) are dispatched by
a parameter rather than duplicating the RVOP body.

The rod smoke test uses a double that lies exactly halfway between two
floats (1.0 + 2^-24): RNE gives 0x3f800000 and ROD gives 0x3f800001. An
ordinary value produces the same result under both modes and would not
exercise the path at all.

make check passes; the build was checked in the default, EXT_V,
JIT+EXT_V and EXT_V-without-EXT_F configurations. clang-format 20.1.7
clean.


Summary by cubic

Implements the eight vfncvt narrowing floating-point conversions from V 1.0 §13.19, so RVV code can convert 64-bit source elements to 32-bit destination elements. These encodings were previously rejected; they now execute using the same overlap constraints as the other narrowing instructions.

Details

  • Rounding follows frm except vfncvt.rod.f.f.w (round towards odd) and the .rtz forms (truncate).
  • The single-width and widening VFUNARY0 forms remain unimplemented and are still rejected.
  • Smoke tests cover tie-to-even vs round-towards-odd behavior and signed vs unsigned 64-bit integer sources.