[PATCH] target/riscv: reject FMV.X.W and FMV.W.X with Zfinx

Zephyr Li posted 1 patch 1 month, 2 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260813041304.7618-1-fritchleybohrer@gmail.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu@processmission.com>
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
[PATCH] target/riscv: reject FMV.X.W and FMV.W.X with Zfinx
Posted by Zephyr Li 1 month, 2 weeks ago
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 <fritchleybohrer@gmail.com>
---
 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
Re: [PATCH] target/riscv: reject FMV.X.W and FMV.W.X with Zfinx
Posted by Daniel Henrique Barboza 1 month ago
Hi,

Seems like this has been fixed by this patch that is currently on the
queue for merge:

[PULL v2 87/96] target/riscv: reject FMV.X.W/FMV.W.X under Zfinx

I'll send an email letting people know that we should comment in Gitlab
when a bug fix is sent.



Thanks,
Daniel

On 8/13/2026 1:13 AM, Zephyr Li wrote:
> 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 <fritchleybohrer@gmail.com>
> ---
>   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