From: Paul Eggert Date: Wed, 1 Aug 2018 23:08:26 +0000 (-0700) Subject: ieee754-h: new module X-Git-Tag: v1.0~5504 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=80d1e8623ac79431a51f617871b7fdc5d28ef917;p=gnulib.git 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. --- diff --git a/ChangeLog b/ChangeLog index 07e970c105..6af3770246 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2018-08-01 Paul Eggert + + 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 iswcntrl: Mention minor problem on macOS. diff --git a/MODULES.html.sh b/MODULES.html.sh index a61a84e4d8..6fff5b3c5d 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 84b2f33455..387d1d3ccc 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 d67b6e70de..5ad0500a9f 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 +@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 diff --git a/lib/ieee754.in.h b/lib/ieee754.in.h new file mode 100644 index 0000000000..ea57638582 --- /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 + . */ + +#ifndef _IEEE754_H + +#define _IEEE754_H 1 + +#ifndef _GL_GNULIB_HEADER +/* Ordinary glibc usage. */ +# include +# include +#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 0000000000..bf7c332e48 --- /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 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 0000000000..e830023aa6 --- /dev/null +++ b/modules/ieee754-h @@ -0,0 +1,39 @@ +Description: +An 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 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: + + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/ieee754-h-tests b/modules/ieee754-h-tests new file mode 100644 index 0000000000..986301e06e --- /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 0000000000..ce19eea186 --- /dev/null +++ b/tests/test-ieee754-h.c @@ -0,0 +1,76 @@ +/* Test . + 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 . */ + +/* Written by Paul Eggert. */ + +#include + +#include +#include + +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; +}