diff mbox series

[03/13] target/arm: Fix FJCVTZS vs flush-to-zero

Message ID 20240625050810.1475643-4-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm: AdvSIMD conversion, part 2 | expand

Commit Message

Richard Henderson June 25, 2024, 5:08 a.m. UTC
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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/vfp_helper.c           | 18 +++++++++---------
 tests/tcg/aarch64/test-2375.c     | 20 ++++++++++++++++++++
 tests/tcg/aarch64/Makefile.target |  3 ++-
 3 files changed, 31 insertions(+), 10 deletions(-)
 create mode 100644 tests/tcg/aarch64/test-2375.c

Comments

Peter Maydell June 25, 2024, 11:56 a.m. UTC | #1
On Tue, 25 Jun 2024 at 06:09, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> 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
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

> --- /dev/null
> +++ b/tests/tcg/aarch64/test-2375.c
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */

Not a project requirement, I guess, but on the Linaro end I
think we want a
 /* Copyright (c) 2024 Linaro Ltd */

too.

> +
> +#include <assert.h>
> +
> +int main()

Missing "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;
> +}

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

(If these are the only issues in the patchset I'll fix them
up when I apply it.)

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index ce26b8a71a..50d7042fa9 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -1091,8 +1091,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);
@@ -1100,13 +1100,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/test-2375.c b/tests/tcg/aarch64/test-2375.c
new file mode 100644
index 0000000000..f83af8b3ea
--- /dev/null
+++ b/tests/tcg/aarch64/test-2375.c
@@ -0,0 +1,20 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
+
+#include <assert.h>
+
+int main()
+{
+   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;
+}
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].