diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2009-04-19 16:42:07 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2009-04-19 16:42:07 +0000 |
commit | 96b4e1796d2cb7605b65d985063a6fb9490658cb (patch) | |
tree | d404964e5769cd93de29f14903d8e22c8588ec51 /lib/libc/arch/alpha | |
parent | 152844f11645837cb5948c638f34c527438267ab (diff) |
- ldexp implementation has issues. switch to the one from libm
- remove frexp in hppa64, cloned from hppa
- move generic ieee754 implementations of modf and ldexp to gen
ok kettenis@, "looks good" millert@
Diffstat (limited to 'lib/libc/arch/alpha')
-rw-r--r-- | lib/libc/arch/alpha/gen/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/arch/alpha/gen/ldexp.c | 138 | ||||
-rw-r--r-- | lib/libc/arch/alpha/gen/modf.c | 105 |
3 files changed, 2 insertions, 245 deletions
diff --git a/lib/libc/arch/alpha/gen/Makefile.inc b/lib/libc/arch/alpha/gen/Makefile.inc index 2f82f39d175..3e4eac62983 100644 --- a/lib/libc/arch/alpha/gen/Makefile.inc +++ b/lib/libc/arch/alpha/gen/Makefile.inc @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile.inc,v 1.8 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.9 2009/04/19 16:42:05 martynas Exp $ # $NetBSD: Makefile.inc,v 1.3 1995/04/29 05:09:14 cgd Exp $ -SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.c nan.c setjmp.S +SRCS+= _setjmp.S fabs.S infinity.c nan.c setjmp.S SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c SRCS+= sigsetjmp.S diff --git a/lib/libc/arch/alpha/gen/ldexp.c b/lib/libc/arch/alpha/gen/ldexp.c deleted file mode 100644 index 66cf9ccd311..00000000000 --- a/lib/libc/arch/alpha/gen/ldexp.c +++ /dev/null @@ -1,138 +0,0 @@ -/* $OpenBSD: ldexp.c,v 1.6 2008/12/10 01:15:01 martynas Exp $ */ -/* $NetBSD: ldexp.c,v 1.1 1995/02/10 17:50:24 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/types.h> -#include <sys/cdefs.h> -#include <machine/ieee.h> -#include <errno.h> -#include <math.h> - -/* - * double ldexp(double val, int exp) - * returns: val * (2**exp) - */ -double -ldexp(val, exp) - double val; - int exp; -{ - register int oldexp, newexp, mulexp; - union doub { - double v; - struct ieee_double s; - } u, mul; - - /* - * If input is zero, or no change, just return input. - * Likewise, if input is Inf or NaN, just return it. - */ - u.v = val; - oldexp = u.s.dbl_exp; - if (val == 0 || exp == 0 || oldexp == DBL_EXP_INFNAN) - return (val); - - /* - * Compute new exponent and check for over/under flow. - * Underflow, unfortunately, could mean switching to denormal. - * If result out of range, set ERANGE and return 0 if too small - * or Inf if too big, with the same sign as the input value. - */ - newexp = oldexp + exp; - if (newexp >= DBL_EXP_INFNAN) { - /* u.s.dbl_sign = val < 0; -- already set */ - u.s.dbl_exp = DBL_EXP_INFNAN; - u.s.dbl_frach = u.s.dbl_fracl = 0; - errno = ERANGE; - return (u.v); /* Inf */ - } - if (newexp <= 0) { - /* - * The output number is either a denormal or underflows - * (see comments in machine/ieee.h). - */ - if (newexp <= -DBL_FRACBITS) { - /* u.s.dbl_sign = val < 0; -- already set */ - u.s.dbl_exp = 0; - u.s.dbl_frach = u.s.dbl_fracl = 0; - errno = ERANGE; - return (u.v); /* zero */ - } - /* - * We are going to produce a denorm. Our `exp' argument - * might be as small as -2097, and we cannot compute - * 2^-2097, so we may have to do this as many as three - * steps (not just two, as for positive `exp's below). - */ - mul.v = 0; - while (exp <= -DBL_EXP_BIAS) { - mul.s.dbl_exp = 1; - val *= mul.v; - exp += DBL_EXP_BIAS - 1; - } - mul.s.dbl_exp = exp + DBL_EXP_BIAS; - val *= mul.v; - return (val); - } - - /* - * Newexp is positive. - * - * If oldexp is zero, we are starting with a denorm, and simply - * adjusting the exponent will produce bogus answers. We need - * to fix that first. - */ - if (oldexp == 0) { - /* - * Multiply by 2^mulexp to make the number normalizable. - * We cannot multiply by more than 2^1023, but `exp' - * argument might be as large as 2046. A single - * adjustment, however, will normalize the number even - * for huge `exp's, and then we can use exponent - * arithmetic just as for normal `double's. - */ - mulexp = exp <= DBL_EXP_BIAS ? exp : DBL_EXP_BIAS; - mul.v = 0; - mul.s.dbl_exp = mulexp + DBL_EXP_BIAS; - val *= mul.v; - if (mulexp == exp) - return (val); - u.v = val; - newexp -= mulexp; - } - - /* - * Both oldexp and newexp are positive; just replace the - * old exponent with the new one. - */ - u.s.dbl_exp = newexp; - return (u.v); -} - -__weak_alias(ldexpl, ldexp); diff --git a/lib/libc/arch/alpha/gen/modf.c b/lib/libc/arch/alpha/gen/modf.c deleted file mode 100644 index 2315ef19034..00000000000 --- a/lib/libc/arch/alpha/gen/modf.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $OpenBSD: modf.c,v 1.5 2005/08/07 16:40:13 espie Exp $ */ -/* $NetBSD: modf.c,v 1.1 1995/02/10 17:50:25 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/types.h> -#include <machine/ieee.h> -#include <errno.h> -#include <math.h> - -/* - * double modf(double val, double *iptr) - * returns: f and i such that |f| < 1.0, (f + i) = val, and - * sign(f) == sign(i) == sign(val). - * - * Beware signedness when doing subtraction, and also operand size! - */ -double -modf(val, iptr) - double val, *iptr; -{ - union doub { - double v; - struct ieee_double s; - } u, v; - u_int64_t frac; - - /* - * If input is Inf or NaN, return it and leave i alone. - */ - u.v = val; - if (u.s.dbl_exp == DBL_EXP_INFNAN) - return (u.v); - - /* - * If input can't have a fractional part, return - * (appropriately signed) zero, and make i be the input. - */ - if ((int)u.s.dbl_exp - DBL_EXP_BIAS > DBL_FRACBITS - 1) { - *iptr = u.v; - v.v = 0.0; - v.s.dbl_sign = u.s.dbl_sign; - return (v.v); - } - - /* - * If |input| < 1.0, return it, and set i to the appropriately - * signed zero. - */ - if (u.s.dbl_exp < DBL_EXP_BIAS) { - v.v = 0.0; - v.s.dbl_sign = u.s.dbl_sign; - *iptr = v.v; - return (u.v); - } - - /* - * There can be a fractional part of the input. - * If you look at the math involved for a few seconds, it's - * plain to see that the integral part is the input, with the - * low (DBL_FRACBITS - (exponent - DBL_EXP_BIAS)) bits zeroed, - * the fractional part is the part with the rest of the - * bits zeroed. Just zeroing the high bits to get the - * fractional part would yield a fraction in need of - * normalization. Therefore, we take the easy way out, and - * just use subtraction to get the fractional part. - */ - v.v = u.v; - /* Zero the low bits of the fraction, the sleazy way. */ - frac = ((u_int64_t)v.s.dbl_frach << 32) + v.s.dbl_fracl; - frac >>= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS); - frac <<= DBL_FRACBITS - (u.s.dbl_exp - DBL_EXP_BIAS); - v.s.dbl_fracl = frac & 0xffffffff; - v.s.dbl_frach = frac >> 32; - *iptr = v.v; - - u.v -= v.v; - u.s.dbl_sign = v.s.dbl_sign; - return (u.v); -} |