fcvtmod.w.d commits rd before raising illegal instruction
Affected revision
RVVM staging branch, verified against the current staging snapshot on
2026-09-06; x86-64 host, RV64 guest user-mode execution.
Summary
RVVM's default ISA string includes zfa, so the legal fcvtmod.w.d code point 0xc2801553 must retire normally. RVVM instead writes the computed result into the destination register and then falls through to its own illegal-instruction path, producing a write-then-trap state transition.
Witness
The static guest probe loads 3.5 as a double into ft0 and executes 0xc2801553 (fcvtmod.w.d a0, ft0, rtz). QEMU with Zfa enabled:
Pristine RVVM reports its internal exception after the destination register has already been populated:
WARN: Exception 2 (tval c2801553) at PC ...
WARN: X10: 0000000000000003
X10 is guest a0, and 3 is exactly the expected integer result of fcvtmod.w.d 3.5, rtz — the register was written before the illegal path.
Cause
In src/cpu/riscv_fpu.c:
case 0x08: // fcvtmod.w.d (Zfa)
if (likely(rm == 0x01)) {
riscv_write_reg(vm, rds, (int32_t)fpu_fcvt_f64_to_i32(riscv_view_d(vm, rs1)));
}
break;
The handler writes rd but does not return, so execution falls through to the later illegal-instruction handling path after the architectural writeback.
Why this is a real defect
The QEMU Zfa reference retires the instruction, while pristine RVVM reaches its illegal path after writing rd. The exception dump proves the internal control-flow fall-through. A native RV64 reference without Zfa is only a capability boundary and is not the expected oracle for RVVM's Zfa-enabled guest. This is narrower than a generic unsupported-extension report and is distinct from userland trap delivery.
Existing reports
I searched the public issue tracker and found no existing report for this defect.
fcvtmod.w.dcommitsrdbefore raising illegal instructionAffected revision
RVVM
stagingbranch, verified against the current staging snapshot on2026-09-06; x86-64 host, RV64 guest user-mode execution.
Summary
RVVM's default ISA string includes
zfa, so the legalfcvtmod.w.dcode point0xc2801553must retire normally. RVVM instead writes the computed result into the destination register and then falls through to its own illegal-instruction path, producing a write-then-trap state transition.Witness
The static guest probe loads
3.5as a double intoft0and executes0xc2801553(fcvtmod.w.d a0, ft0, rtz). QEMU with Zfa enabled:Pristine RVVM reports its internal exception after the destination register has already been populated:
X10is guesta0, and3is exactly the expected integer result offcvtmod.w.d 3.5, rtz— the register was written before the illegal path.Cause
In
src/cpu/riscv_fpu.c:The handler writes
rdbut does notreturn, so execution falls through to the later illegal-instruction handling path after the architectural writeback.Why this is a real defect
The QEMU Zfa reference retires the instruction, while pristine RVVM reaches its illegal path after writing
rd. The exception dump proves the internal control-flow fall-through. A native RV64 reference without Zfa is only a capability boundary and is not the expected oracle for RVVM's Zfa-enabled guest. This is narrower than a generic unsupported-extension report and is distinct from userland trap delivery.Existing reports
I searched the public issue tracker and found no existing report for this defect.