* [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max
@ 2026-06-24 13:37 Jim MacArthur
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
` (6 more replies)
0 siblings, 7 replies; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
This introduces new forms of FCVTXX instructions which convert floating
point to integer but place the results in SIMD & FP registers, and
forms of the [SU]CVTF instructions which convert from integer to FP
with a source in SIMD & FP registers. The logic for conversion and test
values are otherwise the same as the versions which use general-purpose
registers.
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
Changes in v2:
- New instructions are gated on FPRCVT flag
- do_cvtf_simd removed; changes folded into do_cvtf_f
- Some vector forms of instructions are now allowed in streaming mode (new patch)
- Tests restructured to avoid the duplication of fcvt.ref
- docs/system/arm/emulation.rst updated to indicate FPRCVT support
- linux-user/aarch64/elfload.c now reports FPRCVT
- Link to v1: https://lore.kernel.org/qemu-devel/20260618-jmac-fprcvt-v1-0-1b4475bacf51@linaro.org
---
Jim MacArthur (6):
target/arm/tcg: Implement new instructions for FPRCVT
target/arm/tcg: Allow vector FP conversions with FPRCVT
target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max
linux-user/aarch64/elfload.c: Add FPRCVT
docs/system/arm: Add FEAT_FPRCVT to A-profile support
tests/tcg/arm: Tests for new FPRCVT instructions
docs/system/arm/emulation.rst | 1 +
linux-user/aarch64/elfload.c | 1 +
target/arm/cpu-features.h | 5 +++
target/arm/tcg/a64.decode | 15 +++++++
target/arm/tcg/cpu64.c | 1 +
target/arm/tcg/translate-a64.c | 89 ++++++++++++++++++++++++++++++++++-----
tests/tcg/aarch64/Makefile.target | 14 +++++-
tests/tcg/arm/fcvt.c | 7 +++
8 files changed, 122 insertions(+), 11 deletions(-)
---
base-commit: b83371668192a705b878e909c5ae9c1233cbd5fb
change-id: 20260618-jmac-fprcvt-1554d4c80bc8
Best regards,
--
Jim MacArthur <jim.macarthur@linaro.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:34 ` Richard Henderson
2026-06-25 16:19 ` Alex Bennée
2026-06-24 13:37 ` [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT Jim MacArthur
` (5 subsequent siblings)
6 siblings, 2 replies; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
Adds the opcode format for the SIMD versions of FCVTXX and [US]CVTF.
These use very similar logic to the FP-to-general and general-to-FP
register versions which exist, but use another SIMD/FP register
as source or destination. The source and destination size rules are
slightly different.
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
target/arm/cpu-features.h | 5 +++
target/arm/tcg/a64.decode | 15 +++++++++
target/arm/tcg/translate-a64.c | 71 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
index a80b251589..aba95f4253 100644
--- a/target/arm/cpu-features.h
+++ b/target/arm/cpu-features.h
@@ -1665,6 +1665,11 @@ static inline bool isar_feature_aa64_f8mm4(const ARMISARegisters *id)
return FIELD_EX64_IDREG(id, ID_AA64FPFR0, F8MM4);
}
+static inline bool isar_feature_aa64_fprcvt(const ARMISARegisters *id)
+{
+ return FIELD_EX64_IDREG(id, ID_AA64ISAR3, FPRCVT);
+}
+
/*
* Combinations of feature tests, for ease of use with TRANS_FEAT.
*/
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 28cd1faf61..5b6f156d08 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -1456,6 +1456,21 @@ FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt
FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt
FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt
+# Conversion between floating-point and integer (SIMD & FP)
+SCVTF_simd . 0011110 .. 111100 000000 ..... ..... @icvt
+UCVTF_simd . 0011110 .. 111101 000000 ..... ..... @icvt
+
+FCVTAS_g_simd . 0011110 .. 111010 000000 ..... ..... @icvt
+FCVTAU_g_simd . 0011110 .. 111011 000000 ..... ..... @icvt
+FCVTMS_g_simd . 0011110 .. 110100 000000 ..... ..... @icvt
+FCVTMU_g_simd . 0011110 .. 110101 000000 ..... ..... @icvt
+FCVTNS_g_simd . 0011110 .. 101010 000000 ..... ..... @icvt
+FCVTNU_g_simd . 0011110 .. 101011 000000 ..... ..... @icvt
+FCVTPS_g_simd . 0011110 .. 110010 000000 ..... ..... @icvt
+FCVTPU_g_simd . 0011110 .. 110011 000000 ..... ..... @icvt
+FCVTZS_g_simd . 0011110 .. 110110 000000 ..... ..... @icvt
+FCVTZU_g_simd . 0011110 .. 110111 000000 ..... ..... @icvt
+
FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr
FMOV_ws 0 0011110 00 100110 000000 ..... ..... @rr
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 227719ef25..07f985a5f0 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -9905,12 +9905,14 @@ TRANS(SCVTF_g, do_cvtf_g, a, true)
TRANS(UCVTF_g, do_cvtf_g, a, false)
/*
- * [US]CVTF (vector), scalar version.
- * Which sounds weird, but really just means input from fp register
+ * [US]CVTF (vector), scalar or SIMD version.
+ * Which sounds weird, but really just means input from FP/SIMD register
* instead of input from general register. Input and output element
- * size are always equal.
+ * size are always equal for the scalar version and different for the
+ * SIMD version.
*/
-static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
+static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, MemOp src_mop_int,
+ bool is_signed)
{
TCGv_i64 tcg_int;
int check = fp_access_check_scalar_hsd(s, a->esz);
@@ -9918,14 +9920,18 @@ static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
if (check <= 0) {
return check == 0;
}
-
tcg_int = tcg_temp_new_i64();
- read_vec_element(s, tcg_int, a->rn, 0, a->esz | (is_signed ? MO_SIGN : 0));
+ read_vec_element(s, tcg_int, a->rn, 0,
+ src_mop_int | (is_signed ? MO_SIGN : 0));
return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed);
}
-TRANS(SCVTF_f, do_cvtf_f, a, true)
-TRANS(UCVTF_f, do_cvtf_f, a, false)
+TRANS(SCVTF_f, do_cvtf_f, a, a->esz, true)
+TRANS(UCVTF_f, do_cvtf_f, a, a->esz, false)
+TRANS_FEAT(SCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
+ a->sf ? MO_64 : MO_32, true)
+TRANS_FEAT(UCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
+ a->sf ? MO_64 : MO_32, false)
static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz,
TCGv_i64 tcg_out, int shift, int rn,
@@ -10044,6 +10050,34 @@ static bool do_fcvt_g(DisasContext *s, arg_fcvt *a,
return true;
}
+/*
+ * Floating point to int conversion, but puts the result
+ * in a SIMD register.
+ */
+static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
+ ARMFPRounding rmode, bool is_signed)
+{
+ TCGv_i64 tcg_int;
+ int check = fp_access_check_scalar_hsd(s, a->esz);
+
+ if (check <= 0) {
+ return check == 0;
+ }
+ /*
+ * a->sf should specify destination size (64 bit or 32 bit)
+ * a->esz specifies source size
+ */
+ tcg_int = tcg_temp_new_i64();
+ do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0),
+ a->esz, tcg_int, a->shift, a->rn, rmode);
+
+ if (!s->fpcr_nep) {
+ clear_vec(s, a->rd);
+ }
+ write_vec_element(s, tcg_int, a->rd, 0, (a->sf ? MO_64 : MO_32));
+ return true;
+}
+
TRANS(FCVTNS_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, true)
TRANS(FCVTNU_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, false)
TRANS(FCVTPS_g, do_fcvt_g, a, FPROUNDING_POSINF, true)
@@ -10055,6 +10089,27 @@ TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false)
TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true)
TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false)
+TRANS_FEAT(FCVTNS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_TIEEVEN, true)
+TRANS_FEAT(FCVTNU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_TIEEVEN, false)
+TRANS_FEAT(FCVTPS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_POSINF, true)
+TRANS_FEAT(FCVTPU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_POSINF, false)
+TRANS_FEAT(FCVTMS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_NEGINF, true)
+TRANS_FEAT(FCVTMU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_NEGINF, false)
+TRANS_FEAT(FCVTZS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_ZERO, true)
+TRANS_FEAT(FCVTZU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_ZERO, false)
+TRANS_FEAT(FCVTAS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_TIEAWAY, true)
+TRANS_FEAT(FCVTAU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
+ FPROUNDING_TIEAWAY, false)
+
/*
* FCVT* (vector), scalar version.
* Which sounds weird, but really just means output to fp register
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 17:09 ` Alex Bennée
2026-06-24 13:37 ` [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max Jim MacArthur
` (4 subsequent siblings)
6 siblings, 2 replies; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
FEAT_FPRCVT allows the vector forms of FCVTXX and [US]CVTF in streaming
mode which would otherwise only be available in nonstreaming mode.
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
target/arm/tcg/translate-a64.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 07f985a5f0..1a0868eaf0 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -9915,7 +9915,14 @@ static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, MemOp src_mop_int,
bool is_signed)
{
TCGv_i64 tcg_int;
- int check = fp_access_check_scalar_hsd(s, a->esz);
+ int check;
+
+ /* FEAT_FPRCVT allows vector forms in streaming mode */
+ if (dc_isar_feature(aa64_fprcvt, s)) {
+ s->is_nonstreaming = false;
+ }
+
+ check = fp_access_check_scalar_hsd(s, a->esz);
if (check <= 0) {
return check == 0;
@@ -10120,7 +10127,14 @@ static bool do_fcvt_f(DisasContext *s, arg_fcvt *a,
ARMFPRounding rmode, bool is_signed)
{
TCGv_i64 tcg_int;
- int check = fp_access_check_scalar_hsd(s, a->esz);
+ int check;
+
+ /* FEAT_FPRCVT allows vector forms in streaming mode */
+ if (dc_isar_feature(aa64_fprcvt, s)) {
+ s->is_nonstreaming = false;
+ }
+
+ check = fp_access_check_scalar_hsd(s, a->esz);
if (check <= 0) {
return check == 0;
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
2026-06-24 13:37 ` [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT Jim MacArthur
` (3 subsequent siblings)
6 siblings, 1 reply; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
target/arm/tcg/cpu64.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
index f7a920a202..f259e82dd3 100644
--- a/target/arm/tcg/cpu64.c
+++ b/target/arm/tcg/cpu64.c
@@ -1269,6 +1269,7 @@ void aarch64_max_tcg_initfn(Object *obj)
t = GET_IDREG(isar, ID_AA64ISAR3);
t = FIELD_DP64(t, ID_AA64ISAR3, FAMINMAX, 1); /* FEAT_FAMINMAX */
+ t = FIELD_DP64(t, ID_AA64ISAR3, FPRCVT, 1); /* FEAT_FPRCVT */
SET_IDREG(isar, ID_AA64ISAR3, t);
t = GET_IDREG(isar, ID_AA64PFR0);
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
` (2 preceding siblings ...)
2026-06-24 13:37 ` [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support Jim MacArthur
` (2 subsequent siblings)
6 siblings, 1 reply; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
linux-user/aarch64/elfload.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
index 4887a3a7b7..4487d047bb 100644
--- a/linux-user/aarch64/elfload.c
+++ b/linux-user/aarch64/elfload.c
@@ -173,6 +173,7 @@ abi_ulong get_elf_hwcap(CPUState *cs)
GET_FEATURE_ID(aa64_cmpbr, ARM_HWCAP_A64_CMPBR);
GET_FEATURE_ID(aa64_f8mm8, ARM_HWCAP_A64_F8MM8);
GET_FEATURE_ID(aa64_f8mm4, ARM_HWCAP_A64_F8MM4);
+ GET_FEATURE_ID(aa64_fprcvt, ARM_HWCAP_A64_FPRCVT);
return hwcaps;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
` (3 preceding siblings ...)
2026-06-24 13:37 ` [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:37 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
2026-06-26 8:47 ` [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Peter Maydell
6 siblings, 1 reply; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
docs/system/arm/emulation.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
index a8072ddb67..98c028f6a6 100644
--- a/docs/system/arm/emulation.rst
+++ b/docs/system/arm/emulation.rst
@@ -85,6 +85,7 @@ the following architecture extensions:
- FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
- FEAT_FPACC_SPEC (Speculative behavior of combined pointer authentication instructions)
- FEAT_FPMR (Floating-point Mode Register)
+- FEAT_FPRCVT (Floating-Point to/from Integer in Scalar FP register)
- FEAT_FRINTTS (Floating-point to integer instructions)
- FEAT_FlagM (Flag manipulation instructions v2)
- FEAT_FlagM2 (Enhancements to flag manipulation instructions)
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
` (4 preceding siblings ...)
2026-06-24 13:37 ` [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support Jim MacArthur
@ 2026-06-24 13:37 ` Jim MacArthur
2026-06-24 15:38 ` Richard Henderson
` (2 more replies)
2026-06-26 8:47 ` [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Peter Maydell
6 siblings, 3 replies; 22+ messages in thread
From: Jim MacArthur @ 2026-06-24 13:37 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, qemu-arm, Richard Henderson, Alex Bennee,
Jim MacArthur
We autodetect the presence of FPRCVT in the test cross compiler,
which is a recent feature in GCC and not supported by many distros
yet. If this is in place, we compile the existing fcvt.c test with
an extra compiler flag which uses the new SIMD instructions; the
output from the test is unchanged.
The existing [US]CVTF instructions do not have a test, so no new
tests are added for the SIMD versions. They have been tested manually
to check the new SIMD versions produce the same numerical results as
the existing versions.
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
tests/tcg/aarch64/Makefile.target | 14 +++++++++++++-
tests/tcg/arm/fcvt.c | 7 +++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
index 6203ac9b51..32f2689273 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -28,9 +28,21 @@ config-cc.mak: Makefile
$(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
$(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
$(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
- $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
+ $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME); \
+ $(call cc-option,-march=armv9-a+fprcvt, CROSS_CC_HAS_ARMV9_FPRCVT)) 3> config-cc.mak
-include config-cc.mak
+ifneq ($(CROSS_CC_HAS_ARMV9_FPRCVT),)
+AARCH64_TESTS += fcvt-fprcvt
+fcvt-fprcvt: LDFLAGS += -lm
+fcvt-fprcvt: CFLAGS += $(CROSS_CC_HAS_ARMV9_FPRCVT) -DFPRCVT
+fcvt-fprcvt: fcvt.c
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
+run-fcvt-fprcvt: fcvt-fprcvt
+ $(call run-test,$<,$(QEMU) $<)
+ $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
+endif
+
ifneq ($(CROSS_CC_HAS_ARMV8_2),)
AARCH64_TESTS += dcpop
dcpop: CFLAGS += $(CROSS_CC_HAS_ARMV8_2)
diff --git a/tests/tcg/arm/fcvt.c b/tests/tcg/arm/fcvt.c
index ecebbb0247..7c0cc4367e 100644
--- a/tests/tcg/arm/fcvt.c
+++ b/tests/tcg/arm/fcvt.c
@@ -171,8 +171,14 @@ static void convert_single_to_integer(void)
#if defined(__arm__)
/* asm("vcvt.s32.f32 %s0, %s1" : "=t" (output) : "t" (input)); */
output = input;
+#else
+#ifdef FPRCVT
+ asm("fcvtzs d0, %s1\r\n"
+ "fmov %0, d0" :
+ "=r" (output) : "w" (input));
#else
asm("fcvtzs %0, %s1" : "=r" (output) : "w" (input));
+#endif
#endif
print_int64(i, output);
}
@@ -425,6 +431,7 @@ int main(int argc, char *argv[argc])
convert_double_to_integer();
convert_half_to_integer();
+
/* And now with ARM alternative FP16 */
#if defined(__arm__)
asm("vmrs r1, fpscr\n\t"
--
2.43.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
@ 2026-06-24 15:34 ` Richard Henderson
2026-06-26 15:27 ` Jim MacArthur
2026-06-25 16:19 ` Alex Bennée
1 sibling, 1 reply; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:34 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> /*
> - * [US]CVTF (vector), scalar version.
> - * Which sounds weird, but really just means input from fp register
> + * [US]CVTF (vector), scalar or SIMD version.
> + * Which sounds weird, but really just means input from FP/SIMD register
> * instead of input from general register. Input and output element
> - * size are always equal.
> + * size are always equal for the scalar version and different for the
> + * SIMD version.
> */
> -static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
> +static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, MemOp src_mop_int,
> + bool is_signed)
> {
> TCGv_i64 tcg_int;
> int check = fp_access_check_scalar_hsd(s, a->esz);
> @@ -9918,14 +9920,18 @@ static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
> if (check <= 0) {
> return check == 0;
> }
> -
> tcg_int = tcg_temp_new_i64();
> - read_vec_element(s, tcg_int, a->rn, 0, a->esz | (is_signed ? MO_SIGN : 0));
> + read_vec_element(s, tcg_int, a->rn, 0,
> + src_mop_int | (is_signed ? MO_SIGN : 0));
> return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed);
> }
>
> -TRANS(SCVTF_f, do_cvtf_f, a, true)
> -TRANS(UCVTF_f, do_cvtf_f, a, false)
> +TRANS(SCVTF_f, do_cvtf_f, a, a->esz, true)
> +TRANS(UCVTF_f, do_cvtf_f, a, a->esz, false)
> +TRANS_FEAT(SCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
> + a->sf ? MO_64 : MO_32, true)
> +TRANS_FEAT(UCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
> + a->sf ? MO_64 : MO_32, false)
Good, thanks.
> +/*
> + * Floating point to int conversion, but puts the result
> + * in a SIMD register.
> + */
> +static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
> + ARMFPRounding rmode, bool is_signed)
> +{
> + TCGv_i64 tcg_int;
> + int check = fp_access_check_scalar_hsd(s, a->esz);
> +
> + if (check <= 0) {
> + return check == 0;
> + }
> + /*
> + * a->sf should specify destination size (64 bit or 32 bit)
> + * a->esz specifies source size
> + */
> + tcg_int = tcg_temp_new_i64();
> + do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0),
> + a->esz, tcg_int, a->shift, a->rn, rmode);
> +
> + if (!s->fpcr_nep) {
> + clear_vec(s, a->rd);
> + }
> + write_vec_element(s, tcg_int, a->rd, 0, (a->sf ? MO_64 : MO_32));
> + return true;
> +}
I had suggested that the same MemOp change be done to do_fcvt_f, for the destination.
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT
2026-06-24 13:37 ` [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT Jim MacArthur
@ 2026-06-24 15:35 ` Richard Henderson
2026-06-24 17:09 ` Alex Bennée
1 sibling, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:35 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> FEAT_FPRCVT allows the vector forms of FCVTXX and [US]CVTF in streaming
> mode which would otherwise only be available in nonstreaming mode.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> target/arm/tcg/translate-a64.c | 18 ++++++++++++++++--
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max
2026-06-24 13:37 ` [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max Jim MacArthur
@ 2026-06-24 15:35 ` Richard Henderson
0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:35 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> target/arm/tcg/cpu64.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
> index f7a920a202..f259e82dd3 100644
> --- a/target/arm/tcg/cpu64.c
> +++ b/target/arm/tcg/cpu64.c
> @@ -1269,6 +1269,7 @@ void aarch64_max_tcg_initfn(Object *obj)
>
> t = GET_IDREG(isar, ID_AA64ISAR3);
> t = FIELD_DP64(t, ID_AA64ISAR3, FAMINMAX, 1); /* FEAT_FAMINMAX */
> + t = FIELD_DP64(t, ID_AA64ISAR3, FPRCVT, 1); /* FEAT_FPRCVT */
> SET_IDREG(isar, ID_AA64ISAR3, t);
>
> t = GET_IDREG(isar, ID_AA64PFR0);
>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT
2026-06-24 13:37 ` [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT Jim MacArthur
@ 2026-06-24 15:35 ` Richard Henderson
0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:35 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> linux-user/aarch64/elfload.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
> index 4887a3a7b7..4487d047bb 100644
> --- a/linux-user/aarch64/elfload.c
> +++ b/linux-user/aarch64/elfload.c
> @@ -173,6 +173,7 @@ abi_ulong get_elf_hwcap(CPUState *cs)
> GET_FEATURE_ID(aa64_cmpbr, ARM_HWCAP_A64_CMPBR);
> GET_FEATURE_ID(aa64_f8mm8, ARM_HWCAP_A64_F8MM8);
> GET_FEATURE_ID(aa64_f8mm4, ARM_HWCAP_A64_F8MM4);
> + GET_FEATURE_ID(aa64_fprcvt, ARM_HWCAP_A64_FPRCVT);
>
> return hwcaps;
> }
>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support
2026-06-24 13:37 ` [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support Jim MacArthur
@ 2026-06-24 15:37 ` Richard Henderson
0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:37 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> docs/system/arm/emulation.rst | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
> index a8072ddb67..98c028f6a6 100644
> --- a/docs/system/arm/emulation.rst
> +++ b/docs/system/arm/emulation.rst
> @@ -85,6 +85,7 @@ the following architecture extensions:
> - FEAT_FPACCOMBINE (Faulting on combined pointer authentication instructions)
> - FEAT_FPACC_SPEC (Speculative behavior of combined pointer authentication instructions)
> - FEAT_FPMR (Floating-point Mode Register)
> +- FEAT_FPRCVT (Floating-Point to/from Integer in Scalar FP register)
> - FEAT_FRINTTS (Floating-point to integer instructions)
> - FEAT_FlagM (Flag manipulation instructions v2)
> - FEAT_FlagM2 (Enhancements to flag manipulation instructions)
>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
@ 2026-06-24 15:38 ` Richard Henderson
2026-06-25 8:54 ` Alex Bennée
2026-06-25 15:14 ` Alex Bennée
2 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-24 15:38 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel; +Cc: Peter Maydell, qemu-arm, Alex Bennee
On 6/24/26 06:37, Jim MacArthur wrote:
> +#ifdef FPRCVT
> + asm("fcvtzs d0, %s1\r\n"
> + "fmov %0, d0" :
> + "=r" (output) : "w" (input));
> #else
Missing d0 clobber, but better as
asm("fcvtzs %d0, %s0" : "=w"(output) : "w"(input))
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT
2026-06-24 13:37 ` [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
@ 2026-06-24 17:09 ` Alex Bennée
1 sibling, 0 replies; 22+ messages in thread
From: Alex Bennée @ 2026-06-24 17:09 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm, Richard Henderson
Jim MacArthur <jim.macarthur@linaro.org> writes:
> FEAT_FPRCVT allows the vector forms of FCVTXX and [US]CVTF in streaming
> mode which would otherwise only be available in nonstreaming mode.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
<snip>
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
2026-06-24 15:38 ` Richard Henderson
@ 2026-06-25 8:54 ` Alex Bennée
2026-06-25 14:53 ` Richard Henderson
2026-06-25 15:07 ` Alex Bennée
2026-06-25 15:14 ` Alex Bennée
2 siblings, 2 replies; 22+ messages in thread
From: Alex Bennée @ 2026-06-25 8:54 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm, Richard Henderson
Jim MacArthur <jim.macarthur@linaro.org> writes:
> We autodetect the presence of FPRCVT in the test cross compiler,
> which is a recent feature in GCC and not supported by many distros
> yet. If this is in place, we compile the existing fcvt.c test with
> an extra compiler flag which uses the new SIMD instructions; the
> output from the test is unchanged.
>
> The existing [US]CVTF instructions do not have a test, so no new
> tests are added for the SIMD versions. They have been tested manually
> to check the new SIMD versions produce the same numerical results as
> the existing versions.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> tests/tcg/aarch64/Makefile.target | 14 +++++++++++++-
> tests/tcg/arm/fcvt.c | 7 +++++++
> 2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
> index 6203ac9b51..32f2689273 100644
> --- a/tests/tcg/aarch64/Makefile.target
> +++ b/tests/tcg/aarch64/Makefile.target
> @@ -28,9 +28,21 @@ config-cc.mak: Makefile
> $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
> $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
> $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
> - $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
> + $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME); \
> + $(call cc-option,-march=armv9-a+fprcvt, CROSS_CC_HAS_ARMV9_FPRCVT)) 3> config-cc.mak
> -include config-cc.mak
>
> +ifneq ($(CROSS_CC_HAS_ARMV9_FPRCVT),)
> +AARCH64_TESTS += fcvt-fprcvt
> +fcvt-fprcvt: LDFLAGS += -lm
> +fcvt-fprcvt: CFLAGS += $(CROSS_CC_HAS_ARMV9_FPRCVT) -DFPRCVT
Do you actually need $(CROSS_CC_HAS_ARMV9_FPRCVT) in the compile?
-DFPRCVT handles the compilation.
> +fcvt-fprcvt: fcvt.c
> + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
> +run-fcvt-fprcvt: fcvt-fprcvt
> + $(call run-test,$<,$(QEMU) $<)
> + $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
> +endif
> +
> ifneq ($(CROSS_CC_HAS_ARMV8_2),)
> AARCH64_TESTS += dcpop
> dcpop: CFLAGS += $(CROSS_CC_HAS_ARMV8_2)
> diff --git a/tests/tcg/arm/fcvt.c b/tests/tcg/arm/fcvt.c
> index ecebbb0247..7c0cc4367e 100644
> --- a/tests/tcg/arm/fcvt.c
> +++ b/tests/tcg/arm/fcvt.c
> @@ -171,8 +171,14 @@ static void convert_single_to_integer(void)
> #if defined(__arm__)
> /* asm("vcvt.s32.f32 %s0, %s1" : "=t" (output) : "t" (input)); */
> output = input;
> +#else
> +#ifdef FPRCVT
> + asm("fcvtzs d0, %s1\r\n"
> + "fmov %0, d0" :
> + "=r" (output) : "w" (input));
> #else
> asm("fcvtzs %0, %s1" : "=r" (output) : "w" (input));
> +#endif
> #endif
> print_int64(i, output);
> }
> @@ -425,6 +431,7 @@ int main(int argc, char *argv[argc])
> convert_double_to_integer();
> convert_half_to_integer();
>
> +
stray space
Otherwise looks good with the clobber fix.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> /* And now with ARM alternative FP16 */
> #if defined(__arm__)
> asm("vmrs r1, fpscr\n\t"
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-25 8:54 ` Alex Bennée
@ 2026-06-25 14:53 ` Richard Henderson
2026-06-25 15:07 ` Alex Bennée
1 sibling, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-25 14:53 UTC (permalink / raw)
To: Alex Bennée, Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm
On 6/25/26 01:54, Alex Bennée wrote:
>> +ifneq ($(CROSS_CC_HAS_ARMV9_FPRCVT),)
>> +AARCH64_TESTS += fcvt-fprcvt
>> +fcvt-fprcvt: LDFLAGS += -lm
>> +fcvt-fprcvt: CFLAGS += $(CROSS_CC_HAS_ARMV9_FPRCVT) -DFPRCVT
>
> Do you actually need $(CROSS_CC_HAS_ARMV9_FPRCVT) in the compile?
> -DFPRCVT handles the compilation.
We should need the flag. If we don't, then we're assembling the wrong insn.
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-25 8:54 ` Alex Bennée
2026-06-25 14:53 ` Richard Henderson
@ 2026-06-25 15:07 ` Alex Bennée
1 sibling, 0 replies; 22+ messages in thread
From: Alex Bennée @ 2026-06-25 15:07 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm, Richard Henderson
Alex Bennée <alex.bennee@linaro.org> writes:
> Jim MacArthur <jim.macarthur@linaro.org> writes:
>
>> We autodetect the presence of FPRCVT in the test cross compiler,
>> which is a recent feature in GCC and not supported by many distros
>> yet. If this is in place, we compile the existing fcvt.c test with
>> an extra compiler flag which uses the new SIMD instructions; the
>> output from the test is unchanged.
>>
>> The existing [US]CVTF instructions do not have a test, so no new
>> tests are added for the SIMD versions. They have been tested manually
>> to check the new SIMD versions produce the same numerical results as
>> the existing versions.
>>
>> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
>> ---
>> tests/tcg/aarch64/Makefile.target | 14 +++++++++++++-
>> tests/tcg/arm/fcvt.c | 7 +++++++
>> 2 files changed, 20 insertions(+), 1 deletion(-)
>>
>> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
>> index 6203ac9b51..32f2689273 100644
>> --- a/tests/tcg/aarch64/Makefile.target
>> +++ b/tests/tcg/aarch64/Makefile.target
>> @@ -28,9 +28,21 @@ config-cc.mak: Makefile
>> $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
>> $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
>> $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
>> - $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
>> + $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME); \
>> + $(call cc-option,-march=armv9-a+fprcvt, CROSS_CC_HAS_ARMV9_FPRCVT)) 3> config-cc.mak
>> -include config-cc.mak
>>
>> +ifneq ($(CROSS_CC_HAS_ARMV9_FPRCVT),)
>> +AARCH64_TESTS += fcvt-fprcvt
>> +fcvt-fprcvt: LDFLAGS += -lm
>> +fcvt-fprcvt: CFLAGS += $(CROSS_CC_HAS_ARMV9_FPRCVT) -DFPRCVT
>
> Do you actually need $(CROSS_CC_HAS_ARMV9_FPRCVT) in the compile?
> -DFPRCVT handles the compilation.
Ignore that - I forgot about the march flags.
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
2026-06-24 15:38 ` Richard Henderson
2026-06-25 8:54 ` Alex Bennée
@ 2026-06-25 15:14 ` Alex Bennée
2 siblings, 0 replies; 22+ messages in thread
From: Alex Bennée @ 2026-06-25 15:14 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm, Richard Henderson
Jim MacArthur <jim.macarthur@linaro.org> writes:
> We autodetect the presence of FPRCVT in the test cross compiler,
> which is a recent feature in GCC and not supported by many distros
> yet. If this is in place, we compile the existing fcvt.c test with
> an extra compiler flag which uses the new SIMD instructions; the
> output from the test is unchanged.
>
> The existing [US]CVTF instructions do not have a test, so no new
> tests are added for the SIMD versions. They have been tested manually
> to check the new SIMD versions produce the same numerical results as
> the existing versions.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> tests/tcg/aarch64/Makefile.target | 14 +++++++++++++-
> tests/tcg/arm/fcvt.c | 7 +++++++
> 2 files changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
> index 6203ac9b51..32f2689273 100644
> --- a/tests/tcg/aarch64/Makefile.target
> +++ b/tests/tcg/aarch64/Makefile.target
> @@ -28,9 +28,21 @@ config-cc.mak: Makefile
> $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
> $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
> $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
> - $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME)) 3> config-cc.mak
> + $(call cc-option,-Wa$(COMMA)-march=armv9-a+sme $$fnia, CROSS_AS_HAS_ARMV9_SME); \
> + $(call cc-option,-march=armv9-a+fprcvt, CROSS_CC_HAS_ARMV9_FPRCVT)) 3> config-cc.mak
> -include config-cc.mak
>
> +ifneq ($(CROSS_CC_HAS_ARMV9_FPRCVT),)
> +AARCH64_TESTS += fcvt-fprcvt
> +fcvt-fprcvt: LDFLAGS += -lm
> +fcvt-fprcvt: CFLAGS += $(CROSS_CC_HAS_ARMV9_FPRCVT) -DFPRCVT
> +fcvt-fprcvt: fcvt.c
> + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
> +run-fcvt-fprcvt: fcvt-fprcvt
> + $(call run-test,$<,$(QEMU) $<)
> + $(call diff-out,$<,$(AARCH64_SRC)/fcvt.ref)
> +endif
> +
> ifneq ($(CROSS_CC_HAS_ARMV8_2),)
> AARCH64_TESTS += dcpop
> dcpop: CFLAGS += $(CROSS_CC_HAS_ARMV8_2)
> diff --git a/tests/tcg/arm/fcvt.c b/tests/tcg/arm/fcvt.c
> index ecebbb0247..7c0cc4367e 100644
> --- a/tests/tcg/arm/fcvt.c
> +++ b/tests/tcg/arm/fcvt.c
> @@ -171,8 +171,14 @@ static void convert_single_to_integer(void)
> #if defined(__arm__)
> /* asm("vcvt.s32.f32 %s0, %s1" : "=t" (output) : "t" (input)); */
> output = input;
> +#else
> +#ifdef FPRCVT
> + asm("fcvtzs d0, %s1\r\n"
> + "fmov %0, d0" :
> + "=r" (output) : "w" (input));
> #else
> asm("fcvtzs %0, %s1" : "=r" (output) : "w" (input));
> +#endif
> #endif
> print_int64(i, output);
> }
> @@ -425,6 +431,7 @@ int main(int argc, char *argv[argc])
> convert_double_to_integer();
> convert_half_to_integer();
>
> +
> /* And now with ARM alternative FP16 */
> #if defined(__arm__)
> asm("vmrs r1, fpscr\n\t"
Ok with the following:
--8<---------------cut here---------------start------------->8---
modified target/arm/tcg/translate-a64.c
@@ -9882,6 +9882,9 @@ static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift,
static bool do_cvtf_g(DisasContext *s, arg_fcvt *a, bool is_signed)
{
TCGv_i64 tcg_int;
+ g_assert(s->is_nonstreaming == false);
+
+ g_assert_not_reached();
int check = fp_access_check_scalar_hsd(s, a->esz);
if (check <= 0) {
@@ -9917,6 +9920,10 @@ static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, MemOp src_mop_int,
TCGv_i64 tcg_int;
int check;
+ g_assert(s->is_nonstreaming == false);
+
+ g_assert_not_reached();
+
/* FEAT_FPRCVT allows vector forms in streaming mode */
if (dc_isar_feature(aa64_fprcvt, s)) {
s->is_nonstreaming = false;
@@ -10065,6 +10072,11 @@ static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
ARMFPRounding rmode, bool is_signed)
{
TCGv_i64 tcg_int;
+
+ g_assert(s->is_nonstreaming == false);
+
+ /* g_assert_not_reached(); */
+
int check = fp_access_check_scalar_hsd(s, a->esz);
--8<---------------cut here---------------end--------------->8---
I could verify that do_fcvt_simd is called and is_nonstreaming is set by
the "hidden" decode logic. However the other two cases don't get
touched. What would we need to expand the test to them?
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
2026-06-24 15:34 ` Richard Henderson
@ 2026-06-25 16:19 ` Alex Bennée
2026-06-25 17:30 ` Richard Henderson
1 sibling, 1 reply; 22+ messages in thread
From: Alex Bennée @ 2026-06-25 16:19 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm, Richard Henderson
Jim MacArthur <jim.macarthur@linaro.org> writes:
> Adds the opcode format for the SIMD versions of FCVTXX and [US]CVTF.
> These use very similar logic to the FP-to-general and general-to-FP
> register versions which exist, but use another SIMD/FP register
> as source or destination. The source and destination size rules are
> slightly different.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> target/arm/cpu-features.h | 5 +++
> target/arm/tcg/a64.decode | 15 +++++++++
> target/arm/tcg/translate-a64.c | 71 +++++++++++++++++++++++++++++++++++++-----
> 3 files changed, 83 insertions(+), 8 deletions(-)
>
> diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
> index a80b251589..aba95f4253 100644
> --- a/target/arm/cpu-features.h
> +++ b/target/arm/cpu-features.h
> @@ -1665,6 +1665,11 @@ static inline bool isar_feature_aa64_f8mm4(const ARMISARegisters *id)
> return FIELD_EX64_IDREG(id, ID_AA64FPFR0, F8MM4);
> }
>
> +static inline bool isar_feature_aa64_fprcvt(const ARMISARegisters *id)
> +{
> + return FIELD_EX64_IDREG(id, ID_AA64ISAR3, FPRCVT);
> +}
> +
> /*
> * Combinations of feature tests, for ease of use with TRANS_FEAT.
> */
> diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
> index 28cd1faf61..5b6f156d08 100644
> --- a/target/arm/tcg/a64.decode
> +++ b/target/arm/tcg/a64.decode
> @@ -1456,6 +1456,21 @@ FCVTZU_g . 0011110 .. 111001 000000 ..... ..... @icvt
> FCVTAS_g . 0011110 .. 100100 000000 ..... ..... @icvt
> FCVTAU_g . 0011110 .. 100101 000000 ..... ..... @icvt
>
> +# Conversion between floating-point and integer (SIMD & FP)
> +SCVTF_simd . 0011110 .. 111100 000000 ..... ..... @icvt
> +UCVTF_simd . 0011110 .. 111101 000000 ..... ..... @icvt
> +
> +FCVTAS_g_simd . 0011110 .. 111010 000000 ..... ..... @icvt
> +FCVTAU_g_simd . 0011110 .. 111011 000000 ..... ..... @icvt
> +FCVTMS_g_simd . 0011110 .. 110100 000000 ..... ..... @icvt
> +FCVTMU_g_simd . 0011110 .. 110101 000000 ..... ..... @icvt
> +FCVTNS_g_simd . 0011110 .. 101010 000000 ..... ..... @icvt
> +FCVTNU_g_simd . 0011110 .. 101011 000000 ..... ..... @icvt
> +FCVTPS_g_simd . 0011110 .. 110010 000000 ..... ..... @icvt
> +FCVTPU_g_simd . 0011110 .. 110011 000000 ..... ..... @icvt
> +FCVTZS_g_simd . 0011110 .. 110110 000000 ..... ..... @icvt
> +FCVTZU_g_simd . 0011110 .. 110111 000000 ..... ..... @icvt
> +
> FJCVTZS 0 0011110 01 111110 000000 ..... ..... @rr
>
> FMOV_ws 0 0011110 00 100110 000000 ..... ..... @rr
> diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
> index 227719ef25..07f985a5f0 100644
> --- a/target/arm/tcg/translate-a64.c
> +++ b/target/arm/tcg/translate-a64.c
> @@ -9905,12 +9905,14 @@ TRANS(SCVTF_g, do_cvtf_g, a, true)
> TRANS(UCVTF_g, do_cvtf_g, a, false)
>
> /*
> - * [US]CVTF (vector), scalar version.
> - * Which sounds weird, but really just means input from fp register
> + * [US]CVTF (vector), scalar or SIMD version.
> + * Which sounds weird, but really just means input from FP/SIMD register
> * instead of input from general register. Input and output element
> - * size are always equal.
> + * size are always equal for the scalar version and different for the
> + * SIMD version.
> */
> -static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
> +static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, MemOp src_mop_int,
> + bool is_signed)
> {
> TCGv_i64 tcg_int;
> int check = fp_access_check_scalar_hsd(s, a->esz);
> @@ -9918,14 +9920,18 @@ static bool do_cvtf_f(DisasContext *s, arg_fcvt *a, bool is_signed)
> if (check <= 0) {
> return check == 0;
> }
> -
> tcg_int = tcg_temp_new_i64();
> - read_vec_element(s, tcg_int, a->rn, 0, a->esz | (is_signed ? MO_SIGN : 0));
> + read_vec_element(s, tcg_int, a->rn, 0,
> + src_mop_int | (is_signed ? MO_SIGN : 0));
> return do_cvtf_scalar(s, a->esz, a->rd, a->shift, tcg_int, is_signed);
> }
>
> -TRANS(SCVTF_f, do_cvtf_f, a, true)
> -TRANS(UCVTF_f, do_cvtf_f, a, false)
> +TRANS(SCVTF_f, do_cvtf_f, a, a->esz, true)
> +TRANS(UCVTF_f, do_cvtf_f, a, a->esz, false)
> +TRANS_FEAT(SCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
> + a->sf ? MO_64 : MO_32, true)
> +TRANS_FEAT(UCVTF_simd, aa64_fprcvt, do_cvtf_f, a,
> + a->sf ? MO_64 : MO_32, false)
>
> static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz,
> TCGv_i64 tcg_out, int shift, int rn,
> @@ -10044,6 +10050,34 @@ static bool do_fcvt_g(DisasContext *s, arg_fcvt *a,
> return true;
> }
>
> +/*
> + * Floating point to int conversion, but puts the result
> + * in a SIMD register.
> + */
> +static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
> + ARMFPRounding rmode, bool is_signed)
> +{
> + TCGv_i64 tcg_int;
> + int check = fp_access_check_scalar_hsd(s, a->esz);
> +
I did test with:
g_assert(s->is_nonstreaming == false);
which shows trans_FAIL or aarch64_tr_translate_insn setting had done
whatever it was supposed to.
> + if (check <= 0) {
> + return check == 0;
> + }
> + /*
> + * a->sf should specify destination size (64 bit or 32 bit)
> + * a->esz specifies source size
> + */
> + tcg_int = tcg_temp_new_i64();
> + do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0),
> + a->esz, tcg_int, a->shift, a->rn, rmode);
> +
> + if (!s->fpcr_nep) {
> + clear_vec(s, a->rd);
> + }
> + write_vec_element(s, tcg_int, a->rd, 0, (a->sf ? MO_64 : MO_32));
> + return true;
> +}
> +
> TRANS(FCVTNS_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, true)
> TRANS(FCVTNU_g, do_fcvt_g, a, FPROUNDING_TIEEVEN, false)
> TRANS(FCVTPS_g, do_fcvt_g, a, FPROUNDING_POSINF, true)
> @@ -10055,6 +10089,27 @@ TRANS(FCVTZU_g, do_fcvt_g, a, FPROUNDING_ZERO, false)
> TRANS(FCVTAS_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, true)
> TRANS(FCVTAU_g, do_fcvt_g, a, FPROUNDING_TIEAWAY, false)
>
> +TRANS_FEAT(FCVTNS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_TIEEVEN, true)
> +TRANS_FEAT(FCVTNU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_TIEEVEN, false)
> +TRANS_FEAT(FCVTPS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_POSINF, true)
> +TRANS_FEAT(FCVTPU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_POSINF, false)
> +TRANS_FEAT(FCVTMS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_NEGINF, true)
> +TRANS_FEAT(FCVTMU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_NEGINF, false)
> +TRANS_FEAT(FCVTZS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_ZERO, true)
> +TRANS_FEAT(FCVTZU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_ZERO, false)
> +TRANS_FEAT(FCVTAS_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_TIEAWAY, true)
> +TRANS_FEAT(FCVTAU_g_simd, aa64_fprcvt, do_fcvt_simd, a,
> + FPROUNDING_TIEAWAY, false)
> +
> /*
> * FCVT* (vector), scalar version.
> * Which sounds weird, but really just means output to fp register
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT
2026-06-25 16:19 ` Alex Bennée
@ 2026-06-25 17:30 ` Richard Henderson
0 siblings, 0 replies; 22+ messages in thread
From: Richard Henderson @ 2026-06-25 17:30 UTC (permalink / raw)
To: Alex Bennée, Jim MacArthur; +Cc: qemu-devel, Peter Maydell, qemu-arm
On 6/25/26 09:19, Alex Bennée wrote:
>> +/*
>> + * Floating point to int conversion, but puts the result
>> + * in a SIMD register.
>> + */
>> +static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
>> + ARMFPRounding rmode, bool is_signed)
>> +{
>> + TCGv_i64 tcg_int;
>> + int check = fp_access_check_scalar_hsd(s, a->esz);
>> +
>
> I did test with:
>
> g_assert(s->is_nonstreaming == false);
>
> which shows trans_FAIL or aarch64_tr_translate_insn setting had done
> whatever it was supposed to.
By default -cpu max will never set is_nonstreaming, because FEAT_SME_FA64 is enabled. We
do have an sme_fa64=off property exactly for such testing.
r~
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
` (5 preceding siblings ...)
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
@ 2026-06-26 8:47 ` Peter Maydell
6 siblings, 0 replies; 22+ messages in thread
From: Peter Maydell @ 2026-06-26 8:47 UTC (permalink / raw)
To: Jim MacArthur; +Cc: qemu-devel, qemu-arm, Richard Henderson, Alex Bennee
On Wed, 24 Jun 2026 at 14:37, Jim MacArthur <jim.macarthur@linaro.org> wrote:
>
> This introduces new forms of FCVTXX instructions which convert floating
> point to integer but place the results in SIMD & FP registers, and
> forms of the [SU]CVTF instructions which convert from integer to FP
> with a source in SIMD & FP registers. The logic for conversion and test
> values are otherwise the same as the versions which use general-purpose
> registers.
>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> Changes in v2:
Since it looks like you'll need to respin this anyway,
a minor patch structuring nit:
> Jim MacArthur (6):
> target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max
> linux-user/aarch64/elfload.c: Add FPRCVT
> docs/system/arm: Add FEAT_FPRCVT to A-profile support
We generally put all of these in one patch, since they're
just single lines needed to expose the feature to the
guest and document that we've done it. Compare e.g.
commit c45b02cb24ee. So you can just squash these together.
thanks
-- PMM
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT
2026-06-24 15:34 ` Richard Henderson
@ 2026-06-26 15:27 ` Jim MacArthur
0 siblings, 0 replies; 22+ messages in thread
From: Jim MacArthur @ 2026-06-26 15:27 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
On Wed, Jun 24, 2026 at 08:34:23AM -0700, Richard Henderson wrote:
> > +/*
> > + * Floating point to int conversion, but puts the result
> > + * in a SIMD register.
> > + */
> > +static bool do_fcvt_simd(DisasContext *s, arg_fcvt *a,
> > + ARMFPRounding rmode, bool is_signed)
> > +{
> > + TCGv_i64 tcg_int;
> > + int check = fp_access_check_scalar_hsd(s, a->esz);
> > +
> > + if (check <= 0) {
> > + return check == 0;
> > + }
> > + /*
> > + * a->sf should specify destination size (64 bit or 32 bit)
> > + * a->esz specifies source size
> > + */
> > + tcg_int = tcg_temp_new_i64();
> > + do_fcvt_scalar(s, (a->sf ? MO_64 : MO_32) | (is_signed ? MO_SIGN : 0),
> > + a->esz, tcg_int, a->shift, a->rn, rmode);
> > +
> > + if (!s->fpcr_nep) {
> > + clear_vec(s, a->rd);
> > + }
> > + write_vec_element(s, tcg_int, a->rd, 0, (a->sf ? MO_64 : MO_32));
> > + return true;
> > +}
>
> I had suggested that the same MemOp change be done to do_fcvt_f, for the destination.
Yes you did, apologies. It'll be in the next version.
(Resent due to missing mailing list CC)
Jim
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-06-26 15:28 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-24 13:37 [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Jim MacArthur
2026-06-24 13:37 ` [PATCH v2 1/6] target/arm/tcg: Implement new instructions for FPRCVT Jim MacArthur
2026-06-24 15:34 ` Richard Henderson
2026-06-26 15:27 ` Jim MacArthur
2026-06-25 16:19 ` Alex Bennée
2026-06-25 17:30 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 2/6] target/arm/tcg: Allow vector FP conversions with FPRCVT Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 17:09 ` Alex Bennée
2026-06-24 13:37 ` [PATCH v2 3/6] target/arm/tcg/cpu64.c: Add FEAT_FPRCVT to cpu_max Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 4/6] linux-user/aarch64/elfload.c: Add FPRCVT Jim MacArthur
2026-06-24 15:35 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 5/6] docs/system/arm: Add FEAT_FPRCVT to A-profile support Jim MacArthur
2026-06-24 15:37 ` Richard Henderson
2026-06-24 13:37 ` [PATCH v2 6/6] tests/tcg/arm: Tests for new FPRCVT instructions Jim MacArthur
2026-06-24 15:38 ` Richard Henderson
2026-06-25 8:54 ` Alex Bennée
2026-06-25 14:53 ` Richard Henderson
2026-06-25 15:07 ` Alex Bennée
2026-06-25 15:14 ` Alex Bennée
2026-06-26 8:47 ` [PATCH v2 0/6] Implement FEAT_FPRCVT in cpu_max Peter Maydell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.