[PATCH 2/5] x86 long double: Support pseudo numbers in isnanl
Siddhesh Poyarekar
siddhesh@sourceware.org
Tue Dec 15 14:13:36 GMT 2020
Sync up with gcc behaviour. This change splits out the core isnanl
logic so that it can be reused.
---
sysdeps/i386/fpu/s_isnanl.c | 10 ++--------
sysdeps/x86/fpu/isnanl_common.h | 32 ++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 8 deletions(-)
create mode 100644 sysdeps/x86/fpu/isnanl_common.h
diff --git a/sysdeps/i386/fpu/s_isnanl.c b/sysdeps/i386/fpu/s_isnanl.c
index fb97317bc9..6824f31d96 100644
--- a/sysdeps/i386/fpu/s_isnanl.c
+++ b/sysdeps/i386/fpu/s_isnanl.c
@@ -25,19 +25,13 @@ static char rcsid[] = "$NetBSD: $";
#include <math.h>
#include <math_private.h>
+#include "sysdeps/x86/fpu/isnanl_common.h"
int __isnanl(long double x)
{
int32_t se,hx,lx;
GET_LDOUBLE_WORDS(se,hx,lx,x);
- se = (se & 0x7fff) << 1;
- /* The additional & 0x7fffffff is required because Intel's
- extended format has the normally implicit 1 explicit
- present. Sigh! */
- lx |= hx & 0x7fffffff;
- se |= (uint32_t)(lx|(-lx))>>31;
- se = 0xfffe - se;
- return (int)((uint32_t)(se))>>16;
+ return x86_isnanl (se, hx, lx);
}
hidden_def (__isnanl)
weak_alias (__isnanl, isnanl)
diff --git a/sysdeps/x86/fpu/isnanl_common.h b/sysdeps/x86/fpu/isnanl_common.h
new file mode 100644
index 0000000000..60a4af5b41
--- /dev/null
+++ b/sysdeps/x86/fpu/isnanl_common.h
@@ -0,0 +1,32 @@
+/* Common inline isnanl implementation for x86.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+static inline __always_inline int
+x86_isnanl (int32_t se, int32_t hx, int32_t lx)
+{
+ se = (se & 0x7fff) << 1;
+ /* Detect pseudo-normal numbers, i.e. exponent is non-zero and the top
+ bit of the significand is not set. */
+ int pn = (uint32_t)((~hx & 0x80000000) & (se | (-se))) >> 31;
+ /* Clear the significand bit when computing mantissa. */
+ lx |= hx & 0x7fffffff;
+ se |= (uint32_t)(lx | (-lx)) >> 31;
+ se = 0xfffe - se;
+
+ return (int)(((uint32_t)(se)) >> 16) | pn;
+}
--
2.29.2
More information about the Libc-alpha
mailing list