bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

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