From 8cf5ed5125ca8f57fa6f27892f3fbda25a52d354 Mon Sep 17 00:00:00 2001 From: Mike Barcroft Date: Sat, 8 Feb 2003 20:37:55 +0000 Subject: [PATCH] Implement fpclassify(): o Add a MD header private to libc called _fpmath.h; this header contains bitfield layouts of MD floating-point types. o Add a MI header private to libc called fpmath.h; this header contains bitfield layouts of MI floating-point types. o Add private libc variables to lib/libc/$arch/gen/infinity.c for storing NaN values. o Add __double_t and __float_t to , and provide double_t and float_t typedefs in . o Add some C99 manifest constants (FP_ILOGB0, FP_ILOGBNAN, HUGE_VALF, HUGE_VALL, INFINITY, NAN, and return values for fpclassify()) to and others (FLT_EVAL_METHOD, DECIMAL_DIG) to via . o Add C99 macro fpclassify() which calls __fpclassify{d,f,l}() based on the size of its argument. __fpclassifyl() is never called on alpha because (sizeof(long double) == sizeof(double)), which is good since __fpclassifyl() can't deal with such a small `long double'. This was developed by David Schultz and myself with input from bde and fenner. PR: 23103 Submitted by: David Schultz (significant portions) Reviewed by: bde, fenner (earlier versions) --- lib/libc/Makefile | 2 +- lib/libc/alpha/_fpmath.h | 39 ++++++++++++++ lib/libc/alpha/gen/infinity.c | 3 ++ lib/libc/amd64/_fpmath.h | 40 ++++++++++++++ lib/libc/amd64/gen/infinity.c | 3 ++ lib/libc/gen/Makefile.inc | 5 +- lib/libc/gen/fpclassify.3 | 81 ++++++++++++++++++++++++++++ lib/libc/gen/fpclassify.c | 93 +++++++++++++++++++++++++++++++++ lib/libc/i386/_fpmath.h | 40 ++++++++++++++ lib/libc/i386/gen/infinity.c | 3 ++ lib/libc/ia64/_fpmath.h | 40 ++++++++++++++ lib/libc/ia64/gen/infinity.c | 3 ++ lib/libc/include/fpmath.h | 63 ++++++++++++++++++++++ lib/libc/powerpc/_fpmath.h | 40 ++++++++++++++ lib/libc/powerpc/gen/infinity.c | 3 ++ lib/libc/sparc64/_fpmath.h | 40 ++++++++++++++ lib/libc/sparc64/gen/infinity.c | 3 ++ lib/msun/src/math.h | 32 ++++++++++++ sys/alpha/include/_types.h | 2 + sys/alpha/include/float.h | 2 + sys/amd64/include/float.h | 2 + sys/i386/include/_types.h | 2 + sys/i386/include/float.h | 2 + sys/ia64/include/_types.h | 2 + sys/ia64/include/float.h | 2 + sys/powerpc/include/_types.h | 2 + sys/powerpc/include/float.h | 2 + sys/sparc64/include/_types.h | 2 + sys/sparc64/include/float.h | 2 + 29 files changed, 552 insertions(+), 3 deletions(-) create mode 100644 lib/libc/alpha/_fpmath.h create mode 100644 lib/libc/amd64/_fpmath.h create mode 100644 lib/libc/gen/fpclassify.3 create mode 100644 lib/libc/gen/fpclassify.c create mode 100644 lib/libc/i386/_fpmath.h create mode 100644 lib/libc/ia64/_fpmath.h create mode 100644 lib/libc/include/fpmath.h create mode 100644 lib/libc/powerpc/_fpmath.h create mode 100644 lib/libc/sparc64/_fpmath.h diff --git a/lib/libc/Makefile b/lib/libc/Makefile index c2fe829cd72e..ae10f73c23e6 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -10,8 +10,8 @@ # system call stubs. LIB=c SHLIB_MAJOR= 5 -CFLAGS+=-I${.CURDIR}/include -I${.CURDIR}/../../include AINC= -I${.CURDIR}/${MACHINE_ARCH} +CFLAGS+=-I${.CURDIR}/include -I${.CURDIR}/../../include ${AINC} CLEANFILES+=tags INSTALL_PIC_ARCHIVE= yes PRECIOUSLIB= yes diff --git a/lib/libc/alpha/_fpmath.h b/lib/libc/alpha/_fpmath.h new file mode 100644 index 000000000000..167f942e65e5 --- /dev/null +++ b/lib/libc/alpha/_fpmath.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) diff --git a/lib/libc/alpha/gen/infinity.c b/lib/libc/alpha/gen/infinity.c index 15b129396085..b10f6d38a6e5 100644 --- a/lib/libc/alpha/gen/infinity.c +++ b/lib/libc/alpha/gen/infinity.c @@ -34,3 +34,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on an Alpha (IEEE double format) */ const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/amd64/_fpmath.h b/lib/libc/amd64/_fpmath.h new file mode 100644 index 000000000000..d78e601f5a8a --- /dev/null +++ b/lib/libc/amd64/_fpmath.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junk :16; + } bits; +}; + +#define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff) diff --git a/lib/libc/amd64/gen/infinity.c b/lib/libc/amd64/gen/infinity.c index 547927b6fd66..464b4029b35a 100644 --- a/lib/libc/amd64/gen/infinity.c +++ b/lib/libc/amd64/gen/infinity.c @@ -9,3 +9,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on a 387 */ const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 2953554839e2..93be60be6c47 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -9,7 +9,7 @@ SRCS+= __xuname.c _pthread_stubs.c _rand48.c _spinlock_stub.c _thread_init.c \ clock.c closedir.c confstr.c \ crypt.c ctermid.c daemon.c devname.c dirname.c disklabel.c \ dlfcn.c dlfunc.c drand48.c erand48.c err.c errlst.c errno.c \ - exec.c fmtcheck.c fmtmsg.c fnmatch.c fstab.c ftok.c fts.c \ + exec.c fmtcheck.c fmtmsg.c fnmatch.c fpclassify.c fstab.c ftok.c fts.c \ getbootfile.c getbsize.c \ getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \ gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \ @@ -40,7 +40,8 @@ MAN+= alarm.3 arc4random.3 \ basename.3 check_utility_compat.3 clock.3 \ confstr.3 ctermid.3 daemon.3 \ devname.3 directory.3 dirname.3 dladdr.3 dllockinit.3 dlopen.3 \ - err.3 exec.3 fmtcheck.3 fmtmsg.3 fnmatch.3 frexp.3 ftok.3 fts.3 \ + err.3 exec.3 fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 frexp.3 \ + ftok.3 fts.3 \ getbootfile.3 getbsize.3 getcap.3 getcontext.3 getcwd.3 \ getdiskbyname.3 getdomainname.3 getfsent.3 \ getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \ diff --git a/lib/libc/gen/fpclassify.3 b/lib/libc/gen/fpclassify.3 new file mode 100644 index 000000000000..3ed831fb08e4 --- /dev/null +++ b/lib/libc/gen/fpclassify.3 @@ -0,0 +1,81 @@ +.\" Copyright (c) 2003 Mike Barcroft +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd February 8, 2003 +.Dt FPCLASSIFY 3 +.Os +.Sh NAME +.Nm fpclassify +.Nd "classify a floating-point number" +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In math.h +.Ft int +.Fn fpclassify "real-floating x" +.Sh DESCRIPTION +The +.Fn fpclassify +macro takes an argument of +.Va x +and returns one of the following manifest constants. +.Bl -tag -width ".Dv FP_SUBNORMAL" +.It Dv FP_INFINITE +Indicates that +.Va x +is an infinite number. +.It Dv FP_NAN +Indicates that +.Va x +is not a number (NaN). +.It Dv FP_NORMAL +Indicates that +.Va x +is a normalized number. +.It Dv FP_SUBNORMAL +Indicates that +.Va x +is a denormalized number. +.It Dv FP_ZERO +Indicates that +.Va x +is zero (0 or -0). +.El +.Sh SEE ALSO +.Xr math 3 +.Sh STANDARDS +The +.Fn fpclassify +macro conforms to +.St -isoC-99 . +.Sh HISTORY +The +.Fn fpclassify +macro was added in +.Fx 5.1 . +.Sh BUGS +By default, the DEC Alpha architecture does not support IEEE rounding. +See compiler documentation for additional details. diff --git a/lib/libc/gen/fpclassify.c b/lib/libc/gen/fpclassify.c new file mode 100644 index 000000000000..26cb910cc141 --- /dev/null +++ b/lib/libc/gen/fpclassify.c @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#include +#include + +#include "fpmath.h" + +int +__fpclassifyf(float f) +{ + union IEEEf2bits u; + + u.f = f; + if (u.bits.exp == 0) { + if (u.bits.man == 0) + return (FP_ZERO); + return (FP_SUBNORMAL); + } + if (u.bits.exp == 255) { + if (u.bits.man == 0) + return (FP_INFINITE); + return (FP_NAN); + } + return (FP_NORMAL); +} + +int +__fpclassifyd(double d) +{ + union IEEEd2bits u; + + u.d = d; + if (u.bits.exp == 0) { + if ((u.bits.manl | u.bits.manh) == 0) + return (FP_ZERO); + return (FP_SUBNORMAL); + } + if (u.bits.exp == 2047) { + if ((u.bits.manl | u.bits.manh) == 0) + return (FP_INFINITE); + return (FP_NAN); + } + return (FP_NORMAL); +} + +int +__fpclassifyl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + if (u.bits.exp == 0) { + if ((u.bits.manl | u.bits.manh) == 0) + return (FP_ZERO); + return (FP_SUBNORMAL); + } + mask_nbit_l(u); /* Mask normalization bit if applicable. */ + if (u.bits.exp == 32767) { + if ((u.bits.manl | u.bits.manh) == 0) + return (FP_INFINITE); + return (FP_NAN); + } + return (FP_NORMAL); +} diff --git a/lib/libc/i386/_fpmath.h b/lib/libc/i386/_fpmath.h new file mode 100644 index 000000000000..d78e601f5a8a --- /dev/null +++ b/lib/libc/i386/_fpmath.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junk :16; + } bits; +}; + +#define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff) diff --git a/lib/libc/i386/gen/infinity.c b/lib/libc/i386/gen/infinity.c index 547927b6fd66..464b4029b35a 100644 --- a/lib/libc/i386/gen/infinity.c +++ b/lib/libc/i386/gen/infinity.c @@ -9,3 +9,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on a 387 */ const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/ia64/_fpmath.h b/lib/libc/ia64/_fpmath.h new file mode 100644 index 000000000000..80ea88a6bb98 --- /dev/null +++ b/lib/libc/ia64/_fpmath.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; +}; + +#define mask_nbit_l(u) ((u).bits.manl &= 0x7fffffffffffffff) diff --git a/lib/libc/ia64/gen/infinity.c b/lib/libc/ia64/gen/infinity.c index 681d811cd1ed..ac7fc38b65cb 100644 --- a/lib/libc/ia64/gen/infinity.c +++ b/lib/libc/ia64/gen/infinity.c @@ -34,3 +34,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on an ia64 (IEEE double format) */ const union __infinity_un __infinity = { { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0, 0, 0xc0, 0xff } }; diff --git a/lib/libc/include/fpmath.h b/lib/libc/include/fpmath.h new file mode 100644 index 000000000000..fcfbbcfef4fb --- /dev/null +++ b/lib/libc/include/fpmath.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include "_fpmath.h" + +union IEEEf2bits { + float f; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int man :23; + unsigned int exp :8; + unsigned int sign :1; +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :8; + unsigned int man :23; +#endif + } bits; +}; + +union IEEEd2bits { + double d; + struct { +#if _BYTE_ORDER == _LITTLE_ENDIAN + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; diff --git a/lib/libc/powerpc/_fpmath.h b/lib/libc/powerpc/_fpmath.h new file mode 100644 index 000000000000..af2e9591dbd6 --- /dev/null +++ b/lib/libc/powerpc/_fpmath.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :15; + unsigned long manh :48; + unsigned long manl :64; + } bits; +}; + +/* XXX does powerpc have a normalization bit? */ +#define mask_nbit_l(u) ((void)0) diff --git a/lib/libc/powerpc/gen/infinity.c b/lib/libc/powerpc/gen/infinity.c index 428f24dfc7b5..cf1695e68028 100644 --- a/lib/libc/powerpc/gen/infinity.c +++ b/lib/libc/powerpc/gen/infinity.c @@ -12,3 +12,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on powerpc */ const union __infinity_un __infinity = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0xff, 0xc0, 0, 0 } }; diff --git a/lib/libc/sparc64/_fpmath.h b/lib/libc/sparc64/_fpmath.h new file mode 100644 index 000000000000..e461b75a14bb --- /dev/null +++ b/lib/libc/sparc64/_fpmath.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :15; + unsigned long manh :48; + unsigned long manl :64; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) diff --git a/lib/libc/sparc64/gen/infinity.c b/lib/libc/sparc64/gen/infinity.c index 4a04c1c5471c..6d0d9344b190 100644 --- a/lib/libc/sparc64/gen/infinity.c +++ b/lib/libc/sparc64/gen/infinity.c @@ -12,3 +12,6 @@ __FBSDID("$FreeBSD$"); /* bytes for +Infinity on a sparc */ const union __infinity_un __infinity = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0xff, 0xc0, 0, 0 } }; diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h index 655b1828d90f..abeca6e8f21b 100644 --- a/lib/msun/src/math.h +++ b/lib/msun/src/math.h @@ -17,6 +17,8 @@ #ifndef _MATH_H_ #define _MATH_H_ +#include + /* * ANSI/POSIX */ @@ -24,7 +26,33 @@ extern const union __infinity_un { unsigned char __uc[8]; double __ud; } __infinity; + +extern const union __nan_un { + unsigned char __uc[sizeof(float)]; + float __uf; +} __nan; + +#define FP_ILOGB0 (-0x7fffffff - 1) /* INT_MIN */ +#define FP_ILOGBNAN 0x7fffffff /* INT_MAX */ #define HUGE_VAL (__infinity.__ud) +#define HUGE_VALF (float)HUGE_VAL +#define HUGE_VALL (long double)HUGE_VAL +#define INFINITY HUGE_VALF +#define NAN (__nan.__uf) + +/* Symbolic constants to classify floating point numbers. */ +#define FP_INFINITE 1 +#define FP_NAN 2 +#define FP_NORMAL 3 +#define FP_SUBNORMAL 4 +#define FP_ZERO 5 +#define fpclassify(x) \ + ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \ + : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \ + : __fpclassifyl(x)) + +typedef __double_t double_t; +typedef __float_t float_t; /* * XOPEN/SVID @@ -116,6 +144,10 @@ __BEGIN_DECLS /* * ANSI/POSIX */ +int __fpclassifyd(double); +int __fpclassifyf(float); +int __fpclassifyl(long double); + double acos(double); double asin(double); double atan(double); diff --git a/sys/alpha/include/_types.h b/sys/alpha/include/_types.h index 731306d29714..01ec08e31ef9 100644 --- a/sys/alpha/include/_types.h +++ b/sys/alpha/include/_types.h @@ -56,6 +56,8 @@ typedef unsigned long __uint64_t; */ typedef __int32_t __clock_t; /* clock()... */ typedef __int64_t __critical_t; +typedef double __double_t; +typedef float __float_t; typedef __int64_t __intfptr_t; typedef __int64_t __intmax_t; typedef __int64_t __intptr_t; diff --git a/sys/alpha/include/float.h b/sys/alpha/include/float.h index 4d72b0e0605d..9cb5f9ab1791 100644 --- a/sys/alpha/include/float.h +++ b/sys/alpha/include/float.h @@ -45,6 +45,8 @@ __END_DECLS #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS __flt_rounds() +#define FLT_EVAL_METHOD 0 /* no promotions */ +#define DECIMAL_DIG 17 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ diff --git a/sys/amd64/include/float.h b/sys/amd64/include/float.h index 9a075ba05b63..2cbdcafc3d98 100644 --- a/sys/amd64/include/float.h +++ b/sys/amd64/include/float.h @@ -39,6 +39,8 @@ #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS 1 /* FP addition rounds to nearest */ +#define FLT_EVAL_METHOD (-1) /* i387 semantics are...interesting */ +#define DECIMAL_DIG 21 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ diff --git a/sys/i386/include/_types.h b/sys/i386/include/_types.h index 2b61c4f28fae..847d9fd97b31 100644 --- a/sys/i386/include/_types.h +++ b/sys/i386/include/_types.h @@ -69,6 +69,8 @@ typedef unsigned long long __uint64_t; */ typedef unsigned long __clock_t; /* clock()... */ typedef __int32_t __critical_t; +typedef double __double_t; +typedef double __float_t; typedef __int32_t __intfptr_t; typedef __int64_t __intmax_t; typedef __int32_t __intptr_t; diff --git a/sys/i386/include/float.h b/sys/i386/include/float.h index 9a075ba05b63..2cbdcafc3d98 100644 --- a/sys/i386/include/float.h +++ b/sys/i386/include/float.h @@ -39,6 +39,8 @@ #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS 1 /* FP addition rounds to nearest */ +#define FLT_EVAL_METHOD (-1) /* i387 semantics are...interesting */ +#define DECIMAL_DIG 21 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ diff --git a/sys/ia64/include/_types.h b/sys/ia64/include/_types.h index db4181577727..49029abe28e0 100644 --- a/sys/ia64/include/_types.h +++ b/sys/ia64/include/_types.h @@ -56,6 +56,8 @@ typedef unsigned long __uint64_t; */ typedef __int32_t __clock_t; /* clock()... */ typedef __int64_t __critical_t; +typedef double __double_t; +typedef float __float_t; typedef __int64_t __intfptr_t; typedef __int64_t __intmax_t; typedef __int64_t __intptr_t; diff --git a/sys/ia64/include/float.h b/sys/ia64/include/float.h index 41948190544a..a1a375892ff8 100644 --- a/sys/ia64/include/float.h +++ b/sys/ia64/include/float.h @@ -41,6 +41,8 @@ #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS 1 /* FP addition rounds to nearest */ +#define FLT_EVAL_METHOD 0 /* no promotions */ +#define DECIMAL_DIG 35 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ diff --git a/sys/powerpc/include/_types.h b/sys/powerpc/include/_types.h index 7b6e9e3b3374..53740797747d 100644 --- a/sys/powerpc/include/_types.h +++ b/sys/powerpc/include/_types.h @@ -69,6 +69,8 @@ typedef unsigned long long __uint64_t; */ typedef __uint32_t __clock_t; /* clock()... */ typedef __int32_t __critical_t; +typedef double __double_t; +typedef double __float_t; typedef __int32_t __intfptr_t; typedef __int64_t __intmax_t; typedef __int32_t __intptr_t; diff --git a/sys/powerpc/include/float.h b/sys/powerpc/include/float.h index 95df5f42ced5..9096b1d48ce0 100644 --- a/sys/powerpc/include/float.h +++ b/sys/powerpc/include/float.h @@ -40,6 +40,8 @@ #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS 1 /* FP addition rounds to nearest */ +#define FLT_EVAL_METHOD 1 /* operands promoted to double */ +#define DECIMAL_DIG 35 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ diff --git a/sys/sparc64/include/_types.h b/sys/sparc64/include/_types.h index d30c9484d8d0..31185964ef74 100644 --- a/sys/sparc64/include/_types.h +++ b/sys/sparc64/include/_types.h @@ -56,6 +56,8 @@ typedef unsigned long __uint64_t; */ typedef __int32_t __clock_t; /* clock()... */ typedef __int64_t __critical_t; +typedef double __double_t; +typedef float __float_t; typedef __int64_t __intfptr_t; typedef __int64_t __intmax_t; typedef __int64_t __intptr_t; diff --git a/sys/sparc64/include/float.h b/sys/sparc64/include/float.h index 96eab375c2f5..e9fb8d003821 100644 --- a/sys/sparc64/include/float.h +++ b/sys/sparc64/include/float.h @@ -55,6 +55,8 @@ __END_DECLS #define FLT_RADIX 2 /* b */ #define FLT_ROUNDS __flt_rounds() +#define FLT_EVAL_METHOD 0 /* no promotion */ +#define DECIMAL_DIG 35 /* max precision in decimal digits */ #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-7F /* b**(1-p) */