changeset 39759:4be92e43380a

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.
author Paul Eggert <eggert@cs.ucla.edu>
date Wed, 01 Aug 2018 16:08:26 -0700
parents 962b2c119f26
children 9e30fb88528f
files ChangeLog MODULES.html.sh config/srclist.txt doc/glibc-headers/ieee754.texi lib/ieee754.in.h m4/ieee754-h.m4 modules/ieee754-h modules/ieee754-h-tests tests/test-ieee754-h.c
diffstat 9 files changed, 392 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 01 13:26:38 2018 -0700
+++ b/ChangeLog	Wed Aug 01 16:08:26 2018 -0700
@@ -1,3 +1,16 @@
+2018-08-01  Paul Eggert  <eggert@cs.ucla.edu>
+
+	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  <bruno@clisp.org>
 
 	iswcntrl: Mention minor problem on macOS.
--- a/MODULES.html.sh	Wed Aug 01 13:26:38 2018 -0700
+++ b/MODULES.html.sh	Wed Aug 01 16:08:26 2018 -0700
@@ -2363,6 +2363,7 @@
 
   func_begin_table
   func_module builtin-expect
+  func_module ieee754-h
   func_module limits-h
   func_end_table
 
--- a/config/srclist.txt	Wed Aug 01 13:26:38 2018 -0700
+++ b/config/srclist.txt	Wed Aug 01 16:08:26 2018 -0700
@@ -152,6 +152,7 @@
 #$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
--- a/doc/glibc-headers/ieee754.texi	Wed Aug 01 13:26:38 2018 -0700
+++ b/doc/glibc-headers/ieee754.texi	Wed Aug 01 16:08:26 2018 -0700
@@ -8,11 +8,18 @@
 
 Portability problems 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.
 @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.
+
+@item
+The substitute for this header file returns nonsense on (now-quite-rare)
+platforms that do not use IEEE floating point.
 @end itemize
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/ieee754.in.h	Wed Aug 01 16:08:26 2018 -0700
@@ -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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m4/ieee754-h.m4	Wed Aug 01 16:08:26 2018 -0700
@@ -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"])
+])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ieee754-h	Wed Aug 01 16:08:26 2018 -0700
@@ -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 $@-t && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/ifndef _GL_GNULIB_HEADER/if 0/g' \
+	    $(srcdir)/ieee754.in.h; \
+	} > $@-t && \
+	mv -f $@-t $@
+else
+ieee754.h: $(top_builddir)/config.status
+	rm -f $@
+endif
+MOSTLYCLEANFILES += ieee754.h ieee754.h-t
+
+Include:
+<ieee754.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/ieee754-h-tests	Wed Aug 01 16:08:26 2018 -0700
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-ieee754-h.c	Wed Aug 01 16:08:26 2018 -0700
@@ -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;
+}