qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH for-7.0 v2] target/ppc: do not silence SNaN in xscvspdpn


From: matheus . ferst
Subject: [PATCH for-7.0 v2] target/ppc: do not silence SNaN in xscvspdpn
Date: Tue, 14 Dec 2021 11:44:59 -0300

From: Matheus Ferst <matheus.ferst@eldorado.org.br>

The non-signalling versions of VSX scalar convert to shorter/longer
precision insns doesn't silence SNaNs in the hardware. To better match
this behavior, use the non-arithmatic conversion of helper_todouble
instead of float32_to_float64. A test is added to prevent future
regressions.

Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
v2:
- helper_todouble instead of changing softfloat
- Basic test for SNaN->SNaN case of xscvspdpn/xscvdpspn and SNaN->Inf
  case of xscvdpspn
---
 target/ppc/fpu_helper.c                 |  5 +---
 tests/tcg/ppc64/Makefile.target         |  4 +--
 tests/tcg/ppc64le/Makefile.target       |  4 +--
 tests/tcg/ppc64le/non_signalling_xscv.c | 36 +++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 8 deletions(-)
 create mode 100644 tests/tcg/ppc64le/non_signalling_xscv.c

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index c4896cecc8..65d57d8df8 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2745,10 +2745,7 @@ uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb)
 
 uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
 {
-    float_status tstat = env->fp_status;
-    set_float_exception_flags(0, &tstat);
-
-    return float32_to_float64(xb >> 32, &tstat);
+    return helper_todouble(xb >> 32);
 }
 
 /*
diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target
index 6ab7934fdf..39d9e9c85e 100644
--- a/tests/tcg/ppc64/Makefile.target
+++ b/tests/tcg/ppc64/Makefile.target
@@ -6,9 +6,9 @@ VPATH += $(SRC_PATH)/tests/tcg/ppc64
 VPATH += $(SRC_PATH)/tests/tcg/ppc64le
 
 ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER8_VECTOR),)
-PPC64_TESTS=bcdsub
+PPC64_TESTS=bcdsub non_signalling_xscv
 endif
-bcdsub: CFLAGS += -mpower8-vector
+$(PPC64_TESTS): CFLAGS += -mpower8-vector
 
 PPC64_TESTS += byte_reverse
 ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),)
diff --git a/tests/tcg/ppc64le/Makefile.target 
b/tests/tcg/ppc64le/Makefile.target
index ba2fde5ff1..84448ae1f5 100644
--- a/tests/tcg/ppc64le/Makefile.target
+++ b/tests/tcg/ppc64le/Makefile.target
@@ -5,9 +5,9 @@
 VPATH += $(SRC_PATH)/tests/tcg/ppc64le
 
 ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER8_VECTOR),)
-PPC64LE_TESTS=bcdsub
+PPC64LE_TESTS=bcdsub non_signalling_xscv
 endif
-bcdsub: CFLAGS += -mpower8-vector
+$(PPC64LE_TESTS): CFLAGS += -mpower8-vector
 
 ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_POWER10),)
 PPC64LE_TESTS += byte_reverse
diff --git a/tests/tcg/ppc64le/non_signalling_xscv.c 
b/tests/tcg/ppc64le/non_signalling_xscv.c
new file mode 100644
index 0000000000..77f0703333
--- /dev/null
+++ b/tests/tcg/ppc64le/non_signalling_xscv.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#define TEST(INSN, B_HI, B_LO, T_HI, T_LO) \
+    do {                                                                \
+        __uint128_t t, b = B_HI;                                        \
+        b <<= 64;                                                       \
+        b |= B_LO;                                                      \
+        asm(INSN " %x0, %x1\n\t"                                        \
+            : "=wa" (t)                                                 \
+            : "wa" (b));                                                \
+        printf(INSN "(0x%016" PRIx64 "%016" PRIx64 ") = 0x%016" PRIx64  \
+               "%016" PRIx64 "\n", (uint64_t)(b >> 64), (uint64_t)b,    \
+               (uint64_t)(t >> 64), (uint64_t)t);                       \
+        assert((uint64_t)(t >> 64) == T_HI && (uint64_t)t == T_LO);     \
+    } while (0)
+
+int main(void)
+{
+#ifndef __SIZEOF_INT128__
+    puts("__uint128_t not available, skipping...\n");
+#else
+    /* SNaN shouldn't be silenced */
+    TEST("xscvspdpn", 0x7fbfffff00000000ULL, 0x0, 0x7ff7ffffe0000000ULL, 0x0);
+    TEST("xscvdpspn", 0x7ff7ffffffffffffULL, 0x0, 0x7fbfffff7fbfffffULL, 0x0);
+
+    /*
+     * SNaN inputs having no significant bits in the upper 23 bits of the
+     * signifcand will return Infinity as the result.
+     */
+    TEST("xscvdpspn", 0x7ff000001fffffffULL, 0x0, 0x7f8000007f800000ULL, 0x0);
+#endif
+    return 0;
+}
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]