[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] ieee754-h: new module
From: |
Paul Eggert |
Subject: |
[PATCH] ieee754-h: new module |
Date: |
Wed, 1 Aug 2018 19:07:58 -0700 |
It looks like Emacs can use this for some NaN processing.
Emacs uses it only on double NaNs so it should be safe.
* MODULES.html.sh (func_all_modules): Add ieee754-h.
* config/srclist.txt: Mention ieee754.h in a comment.
* doc/glibc-headers/ieee754.texi (ieee754.h):
Gnulib now has a substitute that should work
except for long double and for non-IEEE platforms.
* lib/ieee754.in.h, m4/ieee754-h.m4, modules/ieee754-h:
* modules/ieee754-h-tests, tests/test-ieee754-h.c: New files.
---
ChangeLog | 13 ++
MODULES.html.sh | 1 +
config/srclist.txt | 1 +
doc/glibc-headers/ieee754.texi | 11 +-
lib/ieee754.in.h | 222 +++++++++++++++++++++++++++++++++
m4/ieee754-h.m4 | 21 ++++
modules/ieee754-h | 39 ++++++
modules/ieee754-h-tests | 10 ++
tests/test-ieee754-h.c | 76 +++++++++++
9 files changed, 392 insertions(+), 2 deletions(-)
create mode 100644 lib/ieee754.in.h
create mode 100644 m4/ieee754-h.m4
create mode 100644 modules/ieee754-h
create mode 100644 modules/ieee754-h-tests
create mode 100644 tests/test-ieee754-h.c
diff --git a/ChangeLog b/ChangeLog
index 07e970c10..6af377024 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-08-01 Paul Eggert <address@hidden>
+
+ ieee754-h: new module
+ It looks like Emacs can use this for some NaN processing.
+ Emacs uses it only on double NaNs so it should be safe.
+ * MODULES.html.sh (func_all_modules): Add ieee754-h.
+ * config/srclist.txt: Mention ieee754.h in a comment.
+ * doc/glibc-headers/ieee754.texi (ieee754.h):
+ Gnulib now has a substitute that should work
+ except for long double and for non-IEEE platforms.
+ * lib/ieee754.in.h, m4/ieee754-h.m4, modules/ieee754-h:
+ * modules/ieee754-h-tests, tests/test-ieee754-h.c: New files.
+
2018-07-27 Bruno Haible <address@hidden>
iswcntrl: Mention minor problem on macOS.
diff --git a/MODULES.html.sh b/MODULES.html.sh
index a61a84e4d..6fff5b3c5 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -2363,6 +2363,7 @@ func_all_modules ()
func_begin_table
func_module builtin-expect
+ func_module ieee754-h
func_module limits-h
func_end_table
diff --git a/config/srclist.txt b/config/srclist.txt
index 84b2f3345..387d1d3cc 100644
--- a/config/srclist.txt
+++ b/config/srclist.txt
@@ -152,6 +152,7 @@ $LIBCSRC posix/regexec.c lib
#$LIBCSRC string/strpbrk.c lib gpl
#$LIBCSRC string/strstr.c lib gpl
#$LIBCSRC sysdeps/generic/pty-private.h lib gpl
+#$LIBCSRC sysdeps/ieee754/ieee754.h lib gpl (ieee754.in.h in gnulib)
#$LIBCSRC sysdeps/posix/dup2.c lib gpl
#$LIBCSRC sysdeps/posix/euidaccess.c lib gpl
#$LIBCSRC sysdeps/posix/tempname.c lib gpl
diff --git a/doc/glibc-headers/ieee754.texi b/doc/glibc-headers/ieee754.texi
index d67b6e70d..5ad0500a9 100644
--- a/doc/glibc-headers/ieee754.texi
+++ b/doc/glibc-headers/ieee754.texi
@@ -8,11 +8,18 @@ Gnulib module: ---
Portability problems fixed by Gnulib:
@itemize
address@hidden
+This header file is missing on all non-glibc platforms:
+Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1,
HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix
3.5, BeOS, Android 9.0.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
-This header file is missing on all non-glibc platforms:
-Mac OS X 10.5, FreeBSD 6.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 5.1,
HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix
3.5, BeOS, Android 9.0.
+The substitute for this header file has not been tested for @code{long
+double} and does not work on some platforms.
+
address@hidden
+The substitute for this header file returns nonsense on (now-quite-rare)
+platforms that do not use IEEE floating point.
@end itemize
diff --git a/lib/ieee754.in.h b/lib/ieee754.in.h
new file mode 100644
index 000000000..ea5763858
--- /dev/null
+++ b/lib/ieee754.in.h
@@ -0,0 +1,222 @@
+/* Copyright (C) 1992-2018 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
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _IEEE754_H
+
+#define _IEEE754_H 1
+
+#ifndef _GL_GNULIB_HEADER
+/* Ordinary glibc usage. */
+# include <features.h>
+# include <endian.h>
+#else
+/* Gnulib usage. */
+# ifndef __BEGIN_DECLS
+# ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+# else
+# define __BEGIN_DECLS
+# define __END_DECLS
+# endif
+# endif
+# ifndef __FLOAT_WORD_ORDER
+# define __LITTLE_ENDIAN 1234
+# define __BIG_ENDIAN 4321
+# ifdef WORDS_BIGENDIAN
+# define __BYTE_ORDER __BIG_ENDIAN
+# else
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# endif
+# define __FLOAT_WORD_ORDER __BYTE_ORDER
+# endif
+#endif
+
+__BEGIN_DECLS
+
+union ieee754_float
+ {
+ float f;
+
+ /* This is the IEEE 754 single-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int mantissa:23;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:23;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:8;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa:22;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int mantissa:22;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:8;
+ unsigned int negative:1;
+#endif /* Little endian. */
+ } ieee_nan;
+ };
+
+#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
+
+
+union ieee754_double
+ {
+ double d;
+
+ /* This is the IEEE 754 double-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:20;
+ unsigned int mantissa1:32;
+#endif /* Big endian. */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == __BIG_ENDIAN
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:20;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif /* Little endian. */
+ } ieee;
+
+ /* This format makes it easier to see if a NaN is a signalling NaN. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:11;
+ unsigned int quiet_nan:1;
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa0:19;
+ unsigned int mantissa1:32;
+#else
+# if __FLOAT_WORD_ORDER == __BIG_ENDIAN
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+ unsigned int mantissa1:32;
+# else
+ /* Together these comprise the mantissa. */
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:19;
+ unsigned int quiet_nan:1;
+ unsigned int exponent:11;
+ unsigned int negative:1;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
+
+
+union ieee854_long_double
+ {
+ long double d;
+
+ /* This is the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == __BIG_ENDIAN
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:32;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:32;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
+ } ieee;
+
+ /* This is for NaNs in the IEEE 854 double-extended-precision format. */
+ struct
+ {
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int negative:1;
+ unsigned int exponent:15;
+ unsigned int empty:16;
+ unsigned int one:1;
+ unsigned int quiet_nan:1;
+ unsigned int mantissa0:30;
+ unsigned int mantissa1:32;
+#endif
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# if __FLOAT_WORD_ORDER == __BIG_ENDIAN
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int mantissa1:32;
+# else
+ unsigned int mantissa1:32;
+ unsigned int mantissa0:30;
+ unsigned int quiet_nan:1;
+ unsigned int one:1;
+ unsigned int exponent:15;
+ unsigned int negative:1;
+ unsigned int empty:16;
+# endif
+#endif
+ } ieee_nan;
+ };
+
+#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
+
+__END_DECLS
+
+#endif /* ieee754.h */
diff --git a/m4/ieee754-h.m4 b/m4/ieee754-h.m4
new file mode 100644
index 000000000..bf7c332e4
--- /dev/null
+++ b/m4/ieee754-h.m4
@@ -0,0 +1,21 @@
+# Configure ieee754-h module
+
+dnl Copyright 2018 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_IEEE754_H],
+[
+ AC_REQUIRE([AC_C_BIGENDIAN])
+ AC_CHECK_HEADERS_ONCE([ieee754.h])
+ if test $ac_cv_header_ieee754_h = yes; then
+ IEEE754_H=
+ else
+ IEEE754_H=ieee754.h
+ AC_DEFINE([_GL_REPLACE_IEEE754_H], 1,
+ [Define to 1 if <ieee754.h> is missing.])
+ fi
+ AC_SUBST([IEEE754_H])
+ AM_CONDITIONAL([GL_GENERATE_IEEE754_H], [test -n "$IEEE754_H"])
+])
diff --git a/modules/ieee754-h b/modules/ieee754-h
new file mode 100644
index 000000000..e830023aa
--- /dev/null
+++ b/modules/ieee754-h
@@ -0,0 +1,39 @@
+Description:
+An <ieee754.h> that is like GNU.
+
+Files:
+lib/ieee754.in.h
+m4/ieee754-h.m4
+
+Depends-on:
+
+configure.ac:
+gl_IEEE754_H
+
+Makefile.am:
+BUILT_SOURCES += $(IEEE754_H)
+
+# We need the following in order to create <ieee754.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_IEEE754_H
+ieee754.h: ieee754.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f address@hidden && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's/ifndef _GL_GNULIB_HEADER/if 0/g' \
+ $(srcdir)/ieee754.in.h; \
+ } > address@hidden && \
+ mv -f address@hidden $@
+else
+ieee754.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += ieee754.h ieee754.h-t
+
+Include:
+<ieee754.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
diff --git a/modules/ieee754-h-tests b/modules/ieee754-h-tests
new file mode 100644
index 000000000..986301e06
--- /dev/null
+++ b/modules/ieee754-h-tests
@@ -0,0 +1,10 @@
+Files:
+tests/test-ieee754-h.c
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-ieee754-h
+check_PROGRAMS += test-ieee754-h
diff --git a/tests/test-ieee754-h.c b/tests/test-ieee754-h.c
new file mode 100644
index 000000000..ce19eea18
--- /dev/null
+++ b/tests/test-ieee754-h.c
@@ -0,0 +1,76 @@
+/* Test <ieee754.h>.
+ Copyright 2018 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+#include <config.h>
+
+#include <ieee754.h>
+#include <stdio.h>
+
+static struct {
+ float x;
+ unsigned sign; unsigned exponent; unsigned frac;
+} const float_tests[] =
+ {
+ {0, 0, 0, 0},
+ {-0.0, 1, 0, 0},
+ {0.1, 0, 0x7b, 0x4ccccd}
+ };
+
+static struct {
+ double x;
+ unsigned sign; unsigned exponent; unsigned frac_hi; unsigned frac_lo;
+} const double_tests[] =
+ {
+ {0, 0, 0, 0},
+ {-0.0, 1, 0, 0 },
+ {0.1, 0, 0x3fb, 0x99999, 0x9999999a}
+ };
+
+int
+main (void)
+{
+ int i;
+
+ for (i = 0; i < sizeof float_tests / sizeof *float_tests; i++)
+ {
+ union ieee754_float u;
+ u.f = float_tests[i].x;
+ if (float_tests[i].sign != u.ieee.negative)
+ return 1;
+ if (float_tests[i].exponent != u.ieee.exponent)
+ return 2;
+ if (float_tests[i].frac != u.ieee.mantissa)
+ return 3;
+ }
+
+ for (i = 0; i < sizeof double_tests / sizeof *double_tests; i++)
+ {
+ union ieee754_double u;
+ u.d = double_tests[i].x;
+ if (double_tests[i].sign != u.ieee.negative)
+ return 4;
+ if (double_tests[i].exponent != u.ieee.exponent)
+ return 5;
+ if (double_tests[i].frac_hi != u.ieee.mantissa0)
+ return 6;
+ if (double_tests[i].frac_lo != u.ieee.mantissa1)
+ return 7;
+ }
+
+ return 0;
+}
--
2.17.1
- [PATCH] ieee754-h: new module,
Paul Eggert <=