Zfinx excludes FMV.X.W and FMV.W.X, but QEMU currently accepts both instructions when Zfinx is enabled without the F extension.
Require the F extension for these instructions so they raise an illegal instruction exception on Zfinx-only CPUs. Add TCG regression tests for both instructions. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/4108 Signed-off-by: Zephyr Li <[email protected]> --- target/riscv/tcg/insn_trans/trans_rvf.c.inc | 4 +-- tests/tcg/riscv64/Makefile.target | 10 +++++++ tests/tcg/riscv64/test-zfinx-fmv-w-x.S | 33 +++++++++++++++++++++ tests/tcg/riscv64/test-zfinx-fmv-x-w.S | 33 +++++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/riscv64/test-zfinx-fmv-w-x.S create mode 100644 tests/tcg/riscv64/test-zfinx-fmv-x-w.S diff --git a/target/riscv/tcg/insn_trans/trans_rvf.c.inc b/target/riscv/tcg/insn_trans/trans_rvf.c.inc index e935523c93..70c66e9e25 100644 --- a/target/riscv/tcg/insn_trans/trans_rvf.c.inc +++ b/target/riscv/tcg/insn_trans/trans_rvf.c.inc @@ -428,7 +428,7 @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a) { /* NOTE: This was FMV.X.S in an earlier version of the ISA spec! */ REQUIRE_FPU; - REQUIRE_ZFINX_OR_F(ctx); + REQUIRE_EXT(ctx, RVF); TCGv dest = dest_gpr(ctx, a->rd); TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1); @@ -531,7 +531,7 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a) { /* NOTE: This was FMV.S.X in an earlier version of the ISA spec! */ REQUIRE_FPU; - REQUIRE_ZFINX_OR_F(ctx); + REQUIRE_EXT(ctx, RVF); TCGv_i64 dest = dest_fpr(ctx, a->rd); TCGv src = get_gpr(ctx, a->rs1, EXT_ZERO); diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target index 4da5b9a3b3..23e1152a10 100644 --- a/tests/tcg/riscv64/Makefile.target +++ b/tests/tcg/riscv64/Makefile.target @@ -18,3 +18,13 @@ TESTS += test-fcvtmod test-fcvtmod: CFLAGS += -march=rv64imafdc test-fcvtmod: LDFLAGS += -static run-test-fcvtmod: QEMU_OPTS += -cpu rv64,d=true,zfa=true + +TESTS += test-zfinx-fmv-x-w +test-zfinx-fmv-x-w: LDFLAGS = -nostdlib -static +run-test-zfinx-fmv-x-w: QEMU_OPTS += \ + -cpu rv64,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true + +TESTS += test-zfinx-fmv-w-x +test-zfinx-fmv-w-x: LDFLAGS = -nostdlib -static +run-test-zfinx-fmv-w-x: QEMU_OPTS += \ + -cpu rv64,f=false,d=false,zfa=false,zfh=false,zfhmin=false,zfinx=true diff --git a/tests/tcg/riscv64/test-zfinx-fmv-w-x.S b/tests/tcg/riscv64/test-zfinx-fmv-w-x.S new file mode 100644 index 0000000000..73c5c2b2bf --- /dev/null +++ b/tests/tcg/riscv64/test-zfinx-fmv-w-x.S @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include <asm/unistd.h> + + .text + .globl _start +_start: + .option norvc + + li a0, 4 + la a1, sa + li a2, 0 + li a3, 8 + li a7, __NR_rt_sigaction + scall + + .word 0xf0030453 + + li a0, 1 + j exit + +pass: + li a0, 0 + +exit: + li a7, __NR_exit + scall + + .data + .type sa, @object + .size sa, 32 +sa: + .dword pass + .zero 24 diff --git a/tests/tcg/riscv64/test-zfinx-fmv-x-w.S b/tests/tcg/riscv64/test-zfinx-fmv-x-w.S new file mode 100644 index 0000000000..c4e853036f --- /dev/null +++ b/tests/tcg/riscv64/test-zfinx-fmv-x-w.S @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include <asm/unistd.h> + + .text + .globl _start +_start: + .option norvc + + li a0, 4 + la a1, sa + li a2, 0 + li a3, 8 + li a7, __NR_rt_sigaction + scall + + .word 0xe0030453 + + li a0, 1 + j exit + +pass: + li a0, 0 + +exit: + li a7, __NR_exit + scall + + .data + .type sa, @object + .size sa, 32 +sa: + .dword pass + .zero 24 -- 2.43.0
