riscv: RV32 Zfinx accepts excluded FMV.X.W / FMV.W.X instructions
Host environment
- Operating system: Ubuntu 24.04.4 LTS
- OS/kernel version: 6.18.33.2-microsoft-standard-WSL2
- Architecture: x86_64
- QEMU flavor: qemu-riscv32 linux-user
- QEMU version: qemu-riscv32 version 11.0.91
- QEMU command line:
./qemu-riscv32 -cpu rv32,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true ./target_fmv_x_w.elf
Emulated/Virtualized environment
- Operating system: static RV32 test ELFs executed through Linux user mode
- Architecture: riscv32
- CPU configuration:
rv32,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true
Description of problem
Zfinx keeps floating-point computation on integer registers, but it does not
include FMV.X.W or FMV.W.X. The attached witnesses stay on that exact
boundary: one legal control uses the Zfinx register-move seam through
sign injection, and two target cases use the excluded FMV encodings.
Current qemu-riscv32 accepts FMV.X.W and FMV.W.X on the standard
Zfinx CPU surface even though Zfinx explicitly excludes both instructions.
Observed:
| case | raw word | observed |
|---|---|---|
control_fsgnj_s_move.elf |
0x20630453 |
exit=0, stdout=OK |
target_fmv_x_w.elf |
0xe0030453 |
exit=1, stdout=FAIL |
target_fmv_w_x.elf |
0xf0030453 |
exit=1, stdout=FAIL |
Expected:
- the legal
fsgnj.scontrol should retire FMV.X.Wshould be rejected on the Zfinx surfaceFMV.W.Xshould be rejected on the Zfinx surface
Steps to reproduce
-
Save the three attached source files.
-
Build each with:
riscv64-linux-gnu-gcc -nostdlib -static -march=rv32i_zicsr -mabi=ilp32 -Wl,--build-id=none -o <name>.elf <name>.S -
Run each with:
./qemu-riscv32 -cpu rv32,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true ./<name>.elf -
Observe that the legal control prints
OKand both excluded FMV targets printFAIL.
Additional information
- Reproduced on current upstream build:
(
qemu-riscv32 version 11.0.91) - The control is the legal Zfinx register-move seam through sign injection. Both excluded FMV instructions retire and reach the failure path.
- Relevant current source locations:
target/riscv/tcg/insn_trans/trans_rvf.c.inc:427-442target/riscv/tcg/insn_trans/trans_rvf.c.inc:530-543
- Current translator code accepts both through
REQUIRE_ZFINX_OR_F(ctx). - Relevant ISA boundary:
Zfinx excludes
FMV.W.XandFMV.X.W, while register transfers stay on the legal sign-injection/integer path.