diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2024-06-25 11:35:26 -0700 |
---|---|---|
committer | Michael Tokarev <mjt@tls.msk.ru> | 2024-07-02 09:49:20 +0300 |
commit | 10f230bd6177cc892677bf76dba3387262123af2 (patch) | |
tree | bbb27f9d6dec2eb8459c1ccfd9002534d097a962 | |
parent | 10b9e0c546de7e73f6cfe9594cbdaf36384e6888 (diff) |
target/arm: Fix FJCVTZS vs flush-to-zero
Input denormals cause the Javascript inexact bit
(output to Z) to be set.
Cc: qemu-stable@nongnu.org
Fixes: 6c1f6f2733a ("target/arm: Implement ARMv8.3-JSConv")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20240625183536.1672454-4-richard.henderson@linaro.org
[PMM: fixed hardcoded tab in test case]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 7619129f0d4a14d918227c5c47ad7433662e9ccc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r-- | target/arm/vfp_helper.c | 18 | ||||
-rw-r--r-- | tests/tcg/aarch64/Makefile.target | 3 | ||||
-rw-r--r-- | tests/tcg/aarch64/test-2375.c | 21 |
3 files changed, 32 insertions, 10 deletions
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 3e5e37abbe..ff59bc5522 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -1121,8 +1121,8 @@ const FloatRoundMode arm_rmode_to_sf_map[] = { uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus) { float_status *status = vstatus; - uint32_t inexact, frac; - uint32_t e_old, e_new; + uint32_t frac, e_old, e_new; + bool inexact; e_old = get_float_exception_flags(status); set_float_exception_flags(0, status); @@ -1130,13 +1130,13 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus) e_new = get_float_exception_flags(status); set_float_exception_flags(e_old | e_new, status); - if (value == float64_chs(float64_zero)) { - /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ - inexact = 1; - } else { - /* Normal inexact or overflow or NaN */ - inexact = e_new & (float_flag_inexact | float_flag_invalid); - } + /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */ + inexact = e_new & (float_flag_inexact | + float_flag_input_denormal | + float_flag_invalid); + + /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ + inexact |= value == float64_chs(float64_zero); /* Pack the result and the env->ZF representation of Z together. */ return deposit64(frac, 32, 32, inexact); diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index 70d728ae9a..4ecbca6a41 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -41,8 +41,9 @@ endif # Pauth Tests ifneq ($(CROSS_CC_HAS_ARMV8_3),) -AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 +AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375 pauth-%: CFLAGS += -march=armv8.3-a +test-2375: CFLAGS += -march=armv8.3-a run-pauth-1: QEMU_OPTS += -cpu max run-pauth-2: QEMU_OPTS += -cpu max # Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45]. diff --git a/tests/tcg/aarch64/test-2375.c b/tests/tcg/aarch64/test-2375.c new file mode 100644 index 0000000000..84c7e7de71 --- /dev/null +++ b/tests/tcg/aarch64/test-2375.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright (c) 2024 Linaro Ltd */ +/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */ + +#include <assert.h> + +int main(void) +{ + int r, z; + + asm("msr fpcr, %2\n\t" + "fjcvtzs %w0, %d3\n\t" + "cset %1, eq" + : "=r"(r), "=r"(z) + : "r"(0x01000000L), /* FZ = 1 */ + "w"(0xfcff00L)); /* denormal */ + + assert(r == 0); + assert(z == 0); + return 0; +} |