Implement RVV floating-point scalar moves

Closed
AL
2mo ago
+140-9

Implements the floating-point scalar moves from #734.

Adds vfmv.f.s and vfmv.s.f (V 1.0 §16.3) at the VWFUNARY0 and VRFUNARY0
sites of funct6=0x10, both previously rejected with a FIXME so they would
not be misdecoded as vmv.x.s / vmv.s.x.

Both transfer element 0 between a vector register and an f register and
ignore LMUL. Two spec details are easy to miss:

  • vfmv.f.s performs its operation even when vstart >= vl or vl is 0;
  • vfmv.s.f writes nothing when vstart >= vl, which with vl == 0 covers
    every vstart.

The masked encodings of both are reserved, and the sub-opcode field must be
zero; the decode tests cover those rejections and confirm vmv.x.s still
decodes from the same funct6.

Smoke coverage includes the vl == 0 case, which a mutation that drops the
vstart < vl guard is caught by.

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 RVV floating-point scalar moves vfmv.f.s and vfmv.s.f (V 1.0 §16.3). These transfer element 0 between a vector register and an f register, ignoring LMUL; previously their encodings were rejected to avoid misdecoding as vmv.x.s / vmv.s.x, and now they decode and execute.

Implementation notes

  • vfmv.f.s performs its operation even when vstart >= vl or vl == 0.
  • vfmv.s.f writes nothing when vstart >= vl, and with vl == 0 that covers every vstart.
  • Both instructions require SEW=32; masked encodings are reserved and rejected.
  • Added constopt entries and smoke tests covering the vl == 0 case.