diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/alpha/_fpmath.h | 6 | ||||
-rw-r--r-- | lib/libc/amd64/_fpmath.h | 5 | ||||
-rw-r--r-- | lib/libc/gdtoa/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/gdtoa/_ldtoa.c | 97 | ||||
-rw-r--r-- | lib/libc/i386/_fpmath.h | 5 | ||||
-rw-r--r-- | lib/libc/ia64/_fpmath.h | 5 | ||||
-rw-r--r-- | lib/libc/powerpc/_fpmath.h | 8 | ||||
-rw-r--r-- | lib/libc/sparc64/_fpmath.h | 8 |
8 files changed, 135 insertions, 1 deletions
diff --git a/lib/libc/alpha/_fpmath.h b/lib/libc/alpha/_fpmath.h index 167f942..e0df30f 100644 --- a/lib/libc/alpha/_fpmath.h +++ b/lib/libc/alpha/_fpmath.h @@ -37,3 +37,9 @@ union IEEEl2bits { }; #define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/amd64/_fpmath.h b/lib/libc/amd64/_fpmath.h index d78e601..35fe376 100644 --- a/lib/libc/amd64/_fpmath.h +++ b/lib/libc/amd64/_fpmath.h @@ -38,3 +38,8 @@ union IEEEl2bits { }; #define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff) + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc index 06281d1..2622a81 100644 --- a/lib/libc/gdtoa/Makefile.inc +++ b/lib/libc/gdtoa/Makefile.inc @@ -3,7 +3,7 @@ # netlib gdtoa sources .PATH: ${.CURDIR}/gdtoa -MISRCS+=glue.c +MISRCS+=_ldtoa.c glue.c GDTOASRCS=dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c \ hd_init.c hexnan.c misc.c smisc.c \ strtoIg.c strtod.c strtodg.c strtof.c strtord.c sum.c ulp.c diff --git a/lib/libc/gdtoa/_ldtoa.c b/lib/libc/gdtoa/_ldtoa.c new file mode 100644 index 0000000..c81c09b --- /dev/null +++ b/lib/libc/gdtoa/_ldtoa.c @@ -0,0 +1,97 @@ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <float.h> +#include <inttypes.h> +#include <limits.h> +#include <math.h> +#include <stdlib.h> +#include "fpmath.h" +#include "gdtoaimp.h" + +/* + * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(), + * except that the floating point argument is passed by reference. + * When dtoa() is passed a NaN or infinity, it sets expt to 9999. + * However, a long double could have a valid exponent of 9999, so we + * use INT_MAX in ldtoa() instead. + */ +char * +__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) +{ + static FPI fpi = { + LDBL_MANT_DIG, /* nbits */ + LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ + LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ + FPI_Round_near, /* rounding */ +#ifdef Sudden_Underflow /* unused, but correct anyway */ + 1 +#else + 0 +#endif + }; + int be, kind; + char *ret; + union IEEEl2bits u; + uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; + + u.e = *ld; + *sign = u.bits.sign; + be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); + LDBL_TO_ARRAY32(u, bits); + + switch (fpclassify(u.e)) { + case FP_NORMAL: + kind = STRTOG_Normal; +#ifdef LDBL_IMPLICIT_NBIT + bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); +#endif /* LDBL_IMPLICIT_NBIT */ + break; + case FP_ZERO: + kind = STRTOG_Zero; + break; + case FP_SUBNORMAL: + kind = STRTOG_Denormal; + break; + case FP_INFINITE: + kind = STRTOG_Infinite; + break; + case FP_NAN: + kind = STRTOG_NaN; + break; + default: + abort(); + } + + ret = gdtoa(&fpi, be, (ULong *)bits, &kind, mode, ndigits, decpt, rve); + if (*decpt == -32768) + *decpt = INT_MAX; + return ret; +} diff --git a/lib/libc/i386/_fpmath.h b/lib/libc/i386/_fpmath.h index d78e601..35fe376 100644 --- a/lib/libc/i386/_fpmath.h +++ b/lib/libc/i386/_fpmath.h @@ -38,3 +38,8 @@ union IEEEl2bits { }; #define mask_nbit_l(u) ((u).bits.manh &= 0x7fffffff) + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/ia64/_fpmath.h b/lib/libc/ia64/_fpmath.h index 33e6a32..5d7a36b 100644 --- a/lib/libc/ia64/_fpmath.h +++ b/lib/libc/ia64/_fpmath.h @@ -53,3 +53,8 @@ union IEEEl2bits { #else /* _BIG_ENDIAN */ #define mask_nbit_l(u) ((u).bits.manh &= 0xffffff7f) #endif + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/powerpc/_fpmath.h b/lib/libc/powerpc/_fpmath.h index af2e959..52129a4 100644 --- a/lib/libc/powerpc/_fpmath.h +++ b/lib/libc/powerpc/_fpmath.h @@ -38,3 +38,11 @@ union IEEEl2bits { /* XXX does powerpc have a normalization bit? */ #define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) diff --git a/lib/libc/sparc64/_fpmath.h b/lib/libc/sparc64/_fpmath.h index e461b75..69a4b03 100644 --- a/lib/libc/sparc64/_fpmath.h +++ b/lib/libc/sparc64/_fpmath.h @@ -38,3 +38,11 @@ union IEEEl2bits { }; #define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) |