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.s control should retire
  • FMV.X.W should be rejected on the Zfinx surface
  • FMV.W.X should be rejected on the Zfinx surface

Steps to reproduce

  1. Save the three attached source files.

  2. Build each with:

    riscv64-linux-gnu-gcc -nostdlib -static -march=rv32i_zicsr -mabi=ilp32 -Wl,--build-id=none -o <name>.elf <name>.S

  3. Run each with:

    ./qemu-riscv32 -cpu rv32,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true ./<name>.elf

  4. Observe that the legal control prints OK and both excluded FMV targets print FAIL.

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-442
    • target/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.X and FMV.X.W, while register transfers stay on the legal sign-injection/integer path.

Attachments

Edited by carlos