From 68d5a63ce1b78c16042ab6720f4b7163b3148884 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 14 Oct 2023 12:34:25 +0200 Subject: [PATCH] snan: Fix the value of SNaNl() on i386, x86_64, ia64 CPUs. * lib/snan.h (construct_SNaNl): On i386, x86_64, ia64 CPUs, invert bit 62, not bit 63, of the mantissa. * m4/snan.m4 (gl_SNAN): Require gl_LONG_DOUBLE_VS_DOUBLE. * modules/snan (Files): Add m4/math_h.m4. --- ChangeLog | 8 ++++++++ lib/snan.h | 40 ++++++++++++++++++++++++++++++++++++++-- m4/snan.m4 | 3 ++- modules/snan | 1 + 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index db88ac9554..3abc21c442 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2023-10-14 Bruno Haible + + snan: Fix the value of SNaNl() on i386, x86_64, ia64 CPUs. + * lib/snan.h (construct_SNaNl): On i386, x86_64, ia64 CPUs, invert + bit 62, not bit 63, of the mantissa. + * m4/snan.m4 (gl_SNAN): Require gl_LONG_DOUBLE_VS_DOUBLE. + * modules/snan (Files): Add m4/math_h.m4. + 2023-10-13 Bruno Haible tests: Make use of signed signalling NaNs. diff --git a/lib/snan.h b/lib/snan.h index 2e271055c5..a65b12e713 100644 --- a/lib/snan.h +++ b/lib/snan.h @@ -41,6 +41,9 @@ mantissa bits are == 0, the number denotes ±Infinity. */ +/* 'float' = IEEE 754 single-precision + */ + #if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT # define HAVE_SNANF 1 @@ -79,6 +82,9 @@ SNaNf () #endif +/* 'double' = IEEE 754 double-precision + */ + #if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT # define HAVE_SNAND 1 @@ -115,6 +121,24 @@ SNaNd () #endif +/* 'long double' = + * if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE: + IEEE 754 double-precision + + * Otherwise: + - On i386, x86_64, ia64: + 80-bits extended-precision + + - On alpha, arm64, loongarch64, mips64, riscv64, s390x, sparc64: + IEEE 754 quadruple-precision + + - On powerpc, powerpc64, powerpc64le: + 2x64-bits double-double + + - On m68k: + 80-bits extended-precision, padded to 96 bits, with non-IEEE exponent + */ + #if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT # define HAVE_SNANL 1 @@ -140,11 +164,23 @@ construct_SNaNl (long double quiet_value) #define HNWORDS NWORDS #endif /* Turn the quiet NaN into a signalling NaN. */ - #if LDBL_EXPBIT0_BIT > 0 - m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1); + #if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE + /* In this representation, the leading 1 of the mantissa is explicitly + stored. */ + #if LDBL_EXPBIT0_BIT > 1 + m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 2); + #else + m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)] + ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 2); + #endif #else + /* In this representation, the leading 1 of the mantissa is implicit. */ + #if LDBL_EXPBIT0_BIT > 0 + m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1); + #else m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)] ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1); + #endif #endif /* Set some arbitrary mantissa bit. */ m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < HNWORDS / 2 ? 1 : - 1)] diff --git a/m4/snan.m4 b/m4/snan.m4 index b43beff4ac..2b072dcb26 100644 --- a/m4/snan.m4 +++ b/m4/snan.m4 @@ -1,4 +1,4 @@ -# snan.m4 serial 1 +# snan.m4 serial 2 dnl Copyright (C) 2023 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,4 +10,5 @@ AC_DEFUN_ONCE([gl_SNAN], gl_FLOAT_EXPONENT_LOCATION gl_DOUBLE_EXPONENT_LOCATION gl_LONG_DOUBLE_EXPONENT_LOCATION + AC_REQUIRE([gl_LONG_DOUBLE_VS_DOUBLE]) ]) diff --git a/modules/snan b/modules/snan index 2ccbb111db..26988bec33 100644 --- a/modules/snan +++ b/modules/snan @@ -7,6 +7,7 @@ m4/snan.m4 m4/exponentf.m4 m4/exponentd.m4 m4/exponentl.m4 +m4/math_h.m4 Depends-on: nan -- 2.39.5