From bb97148298fa3b2b22efc9584ba048fc0de05495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 6 Sep 2008 14:31:28 +0000 Subject: [PATCH] added more posix functions git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27348 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/posix/math.h | 11 +- .../arch/{x86 => generic}/s_nextafterf.c | 0 .../posix/glibc/arch/generic/s_remquo.c | 113 ++++++++++++++++ .../posix/glibc/arch/generic/s_remquof.c | 108 +++++++++++++++ .../posix/glibc/arch/generic/s_remquol.c | 109 +++++++++++++++ .../libroot/posix/glibc/arch/m68k/Jamfile | 4 + .../posix/glibc/arch/m68k/s_nearbyint.c | 2 + .../posix/glibc/arch/m68k/s_nearbyintf.c | 2 + .../posix/glibc/arch/m68k/s_nearbyintl.c | 2 + .../posix/glibc/arch/m68k/s_nextafterl.c | 109 +++++++++++++++ .../libroot/posix/glibc/arch/m68k/s_remquo.c | 48 +++++++ .../libroot/posix/glibc/arch/m68k/s_remquof.c | 3 + .../libroot/posix/glibc/arch/m68k/s_remquol.c | 3 + .../libroot/posix/glibc/arch/m68k/s_scalbln.c | 2 + .../posix/glibc/arch/m68k/s_scalblnf.c | 2 + .../posix/glibc/arch/m68k/s_scalblnl.c | 2 + .../libroot/posix/glibc/arch/ppc/Jamfile | 1 + .../posix/glibc/arch/ppc/s_nearbyint.c | 98 ++++++++++++++ .../posix/glibc/arch/ppc/s_nearbyintf.c | 77 +++++++++++ .../libroot/posix/glibc/arch/x86/Jamfile | 7 +- .../posix/glibc/arch/x86/s_nearbyint.S | 25 ++++ .../posix/glibc/arch/x86/s_nearbyintf.S | 25 ++++ .../posix/glibc/arch/x86/s_nearbyintl.S | 25 ++++ .../posix/glibc/arch/x86/s_nextafterl.c | 124 ++++++++++++++++++ .../libroot/posix/glibc/arch/x86/s_remquo.S | 50 +++++++ .../libroot/posix/glibc/arch/x86/s_remquof.S | 50 +++++++ .../libroot/posix/glibc/arch/x86/s_remquol.S | 50 +++++++ .../libroot/posix/glibc/arch/x86/s_scalblnl.c | 2 + .../glibc/include/arch/m68k/bits/mathdef.h | 3 + 29 files changed, 1054 insertions(+), 3 deletions(-) rename src/system/libroot/posix/glibc/arch/{x86 => generic}/s_nextafterf.c (100%) create mode 100644 src/system/libroot/posix/glibc/arch/generic/s_remquo.c create mode 100644 src/system/libroot/posix/glibc/arch/generic/s_remquof.c create mode 100644 src/system/libroot/posix/glibc/arch/generic/s_remquol.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_nearbyint.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_nearbyintf.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_nearbyintl.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_nextafterl.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_remquo.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_remquof.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_remquol.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_scalbln.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_scalblnf.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/s_scalblnl.c create mode 100644 src/system/libroot/posix/glibc/arch/ppc/s_nearbyint.c create mode 100644 src/system/libroot/posix/glibc/arch/ppc/s_nearbyintf.c create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_nearbyint.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_nearbyintf.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_nearbyintl.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_nextafterl.c create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_remquo.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_remquof.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_remquol.S create mode 100644 src/system/libroot/posix/glibc/arch/x86/s_scalblnl.c diff --git a/headers/posix/math.h b/headers/posix/math.h index 8bdabb40c6..771f26fade 100644 --- a/headers/posix/math.h +++ b/headers/posix/math.h @@ -106,7 +106,9 @@ extern float logbf(float x); extern float logf(float x); extern long lroundf(float x); extern float modff(float x, float *y); +extern float nearbyintf(float x); extern float powf(float x, float y); +extern float remquof(float x, float y, int *quo); extern float roundf(float x); extern float sinf(float x); extern float sinhf(float x); @@ -137,7 +139,9 @@ extern double log(double x); extern double log10(double x); extern long lround(double x); extern double modf(double x, double *y); +extern double nearbyint(double x); extern double pow(double x, double y); +extern double remquo(double x, double y, int *quo); extern double round(double x); extern double sin(double x); extern double sinh(double x); @@ -154,8 +158,10 @@ extern long double atanl(long double x); extern long double atanhl(long double x); extern long double atan2l(long double y, long double x); extern long double lgammal(long double x); +extern long double nearbyintl(long double x); extern long double roundl(long double x); extern long lroundl(long double x); +extern long double remquol(long double x, long double y, int *quo); /* some BSD non-ANSI or POSIX math functions */ extern double cbrt(double x); @@ -189,6 +195,7 @@ extern float copysignf(float x, float y); extern int isnanf(float value); extern double significand(double x); extern double copysign(double x, double y); +extern double scalbln(double x, long n); extern double scalbn(double x, int y); extern double drem(double x, double y); extern int isnan(double x); @@ -211,7 +218,9 @@ extern float scalbf(float x, float n); extern float scalbnf(float x, int n); extern int ilogbf(float x); -extern long double remainderl(long double x, long double y); +extern long double remainderl(long double x, long double y); +extern long double scalbnl(long double x, int n); +extern long double scalblnl(long double x, long n); /* prototypes for functions used in the macros below */ extern int __fpclassifyf(float value); diff --git a/src/system/libroot/posix/glibc/arch/x86/s_nextafterf.c b/src/system/libroot/posix/glibc/arch/generic/s_nextafterf.c similarity index 100% rename from src/system/libroot/posix/glibc/arch/x86/s_nextafterf.c rename to src/system/libroot/posix/glibc/arch/generic/s_nextafterf.c diff --git a/src/system/libroot/posix/glibc/arch/generic/s_remquo.c b/src/system/libroot/posix/glibc/arch/generic/s_remquo.c new file mode 100644 index 0000000000..820f18bd63 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_remquo.c @@ -0,0 +1,113 @@ +/* Compute remainder and a congruent to the quotient. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +static const double zero = 0.0; + + +double +__remquo (double x, double y, int *quo) +{ + int32_t hx,hy; + u_int32_t sx,lx,ly; + int cquo, qs; + + EXTRACT_WORDS (hx, lx, x); + EXTRACT_WORDS (hy, ly, y); + sx = hx & 0x80000000; + qs = sx ^ (hy & 0x80000000); + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* Purge off exception values. */ + if ((hy | ly) == 0) + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7ff00000) /* x not finite */ + || ((hy >= 0x7ff00000) /* p is NaN */ + && (((hy - 0x7ff00000) | ly) != 0))) + return (x * y) / (x * y); + + if (hy <= 0x7fbfffff) + x = __ieee754_fmod (x, 8 * y); /* now x < 8y */ + + if (((hx - hy) | (lx - ly)) == 0) + { + *quo = qs ? -1 : 1; + return zero * x; + } + + x = fabs (x); + y = fabs (y); + cquo = 0; + + if (x >= 4 * y) + { + x -= 4 * y; + cquo += 4; + } + if (x >= 2 * y) + { + x -= 2 * y; + cquo += 2; + } + + if (hy < 0x00200000) + { + if (x + x > y) + { + x -= y; + ++cquo; + if (x + x >= y) + { + x -= y; + ++cquo; + } + } + } + else + { + double y_half = 0.5 * y; + if (x > y_half) + { + x -= y; + ++cquo; + if (x >= y_half) + { + x -= y; + ++cquo; + } + } + } + + *quo = qs ? -cquo : cquo; + + if (sx) + x = -x; + return x; +} +weak_alias (__remquo, remquo) +#ifdef NO_LONG_DOUBLE +strong_alias (__remquo, __remquol) +weak_alias (__remquo, remquol) +#endif diff --git a/src/system/libroot/posix/glibc/arch/generic/s_remquof.c b/src/system/libroot/posix/glibc/arch/generic/s_remquof.c new file mode 100644 index 0000000000..0d184ad528 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_remquof.c @@ -0,0 +1,108 @@ +/* Compute remainder and a congruent to the quotient. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +static const float zero = 0.0; + + +float +__remquof (float x, float y, int *quo) +{ + int32_t hx,hy; + u_int32_t sx; + int cquo, qs; + + GET_FLOAT_WORD (hx, x); + GET_FLOAT_WORD (hy, y); + sx = hx & 0x80000000; + qs = sx ^ (hy & 0x80000000); + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* Purge off exception values. */ + if (hy == 0) + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7f800000) /* x not finite */ + || (hy > 0x7f800000)) /* y is NaN */ + return (x * y) / (x * y); + + if (hy <= 0x7dffffff) + x = __ieee754_fmodf (x, 8 * y); /* now x < 8y */ + + if ((hx - hy) == 0) + { + *quo = qs ? -1 : 1; + return zero * x; + } + + x = fabsf (x); + y = fabsf (y); + cquo = 0; + + if (x >= 4 * y) + { + x -= 4 * y; + cquo += 4; + } + if (x >= 2 * y) + { + x -= 2 * y; + cquo += 2; + } + + if (hy < 0x01000000) + { + if (x + x > y) + { + x -= y; + ++cquo; + if (x + x >= y) + { + x -= y; + ++cquo; + } + } + } + else + { + float y_half = 0.5 * y; + if (x > y_half) + { + x -= y; + ++cquo; + if (x >= y_half) + { + x -= y; + ++cquo; + } + } + } + + *quo = qs ? -cquo : cquo; + + if (sx) + x = -x; + return x; +} +weak_alias (__remquof, remquof) diff --git a/src/system/libroot/posix/glibc/arch/generic/s_remquol.c b/src/system/libroot/posix/glibc/arch/generic/s_remquol.c new file mode 100644 index 0000000000..5fd8e88475 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/s_remquol.c @@ -0,0 +1,109 @@ +/* Compute remainder and a congruent to the quotient. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#include "math_private.h" + + +static const long double zero = 0.0; + + +long double +__remquol (long double x, long double p, int *quo) +{ + int32_t ex,ep,hx,hp; + u_int32_t sx,lx,lp; + int cquo,qs; + + GET_LDOUBLE_WORDS (ex, hx, lx, x); + GET_LDOUBLE_WORDS (ep, hp, lp, p); + sx = ex & 0x8000; + qs = (sx ^ (ep & 0x8000)) >> 15; + ep &= 0x7fff; + ex &= 0x7fff; + + /* Purge off exception values. */ + if ((ep | hp | lp) == 0) + return (x * p) / (x * p); /* p = 0 */ + if ((ex == 0x7fff) /* x not finite */ + || ((ep == 0x7fff) /* p is NaN */ + && ((hp | lp) != 0))) + return (x * p) / (x * p); + + if (ep <= 0x7ffb) + x = __ieee754_fmodl (x, 8 * p); /* now x < 8p */ + + if (((ex - ep) | (hx - hp) | (lx - lp)) == 0) + { + *quo = qs ? -1 : 1; + return zero * x; + } + + x = fabsl (x); + p = fabsl (p); + cquo = 0; + + if (x >= 4 * p) + { + x -= 4 * p; + cquo += 4; + } + if (x >= 2 * p) + { + x -= 2 * p; + cquo += 2; + } + + if (ep < 0x0002) + { + if (x + x > p) + { + x -= p; + ++cquo; + if (x + x >= p) + { + x -= p; + ++cquo; + } + } + } + else + { + long double p_half = 0.5 * p; + if (x > p_half) + { + x -= p; + ++cquo; + if (x >= p_half) + { + x -= p; + ++cquo; + } + } + } + + *quo = qs ? -cquo : cquo; + + if (sx) + x = -x; + return x; +} +weak_alias (__remquol, remquol) diff --git a/src/system/libroot/posix/glibc/arch/m68k/Jamfile b/src/system/libroot/posix/glibc/arch/m68k/Jamfile index 53f1feca40..42a472a596 100644 --- a/src/system/libroot/posix/glibc/arch/m68k/Jamfile +++ b/src/system/libroot/posix/glibc/arch/m68k/Jamfile @@ -82,6 +82,7 @@ local genericSources = s_lround.c s_lroundf.c s_modf.c s_modff.c # s_modfl.c s_nan.c s_nanf.c # s_nanl.c + s_nextafter.c s_nextafterf.c # s_nextafterl.c s_round.c s_roundf.c # s_roundl.c s_scalbn.c s_scalbnf.c # s_scalbnl.c s_signbit.c s_signbitf.c # s_signbitl.c @@ -143,7 +144,10 @@ MergeObject posix_gnu_arch_$(TARGET_ARCH)_other.o : # s_fabs.S s_fabsf.S # s_fabsl.S # s_fpclassifyl.c # s_isnan.c s_isnanf.S + s_nearbyint.c s_nearbyintf.c # s_nearbyintl.c + s_remquo.c s_remquof.c # s_remquol.c s_rint.c s_rintf.c # s_rintl.c + s_scalbln.c s_scalblnf.c # s_scalblnl.c # t_sqrt.c # w_sqrt.c w_sqrtf.c # w_sqrtl.c ; diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_nearbyint.c b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyint.c new file mode 100644 index 0000000000..b87f5e2160 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyint.c @@ -0,0 +1,2 @@ +#define FUNC nearbyint +#include diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintf.c b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintf.c new file mode 100644 index 0000000000..70d08ab44c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintf.c @@ -0,0 +1,2 @@ +#define FUNC nearbyintf +#include diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintl.c b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintl.c new file mode 100644 index 0000000000..230cd7784c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_nearbyintl.c @@ -0,0 +1,2 @@ +#define FUNC nearbyintl +#include diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_nextafterl.c b/src/system/libroot/posix/glibc/arch/m68k/s_nextafterl.c new file mode 100644 index 0000000000..70ab5a4784 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_nextafterl.c @@ -0,0 +1,109 @@ +/* s_nextafterl.c -- long double version of s_nextafter.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + * Fixed for m68k by Andreas Schwab . + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + long double __nextafterl(long double x, long double y) +#else + long double __nextafterl(x,y) + long double x,y; +#endif +{ + int32_t ix,iy,esx,esy; + u_int32_t hx,hy,lx,ly; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if(((ix==0x7fff)&&((hx&0x7fffffff)|lx)!=0) || /* x is nan */ + ((iy==0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(esx>=0) { /* x > 0 */ + if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } else { /* x < 0 */ + if(esy>=0||esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0 && (hx & 0x80000000) == 0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS(y,esx,hx,lx); + return y; + } + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} +weak_alias (__nextafterl, nextafterl) +strong_alias (__nextafterl, __nexttowardl) +weak_alias (__nextafterl, nexttowardl) diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_remquo.c b/src/system/libroot/posix/glibc/arch/m68k/s_remquo.c new file mode 100644 index 0000000000..5b65f85fbc --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_remquo.c @@ -0,0 +1,48 @@ +/* Compute remainder and a congruent to the quotient. m68k fpu version + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) + +float_type +s(__remquo) (float_type x, float_type y, int *quo) +{ + float_type result; + int cquo, fpsr; + + __asm ("frem%.x %2,%0\n\tfmove%.l %/fpsr,%1" + : "=f" (result), "=dm" (fpsr) : "f" (y), "0" (x)); + cquo = (fpsr >> 16) & 0x7f; + if (fpsr & (1 << 23)) + cquo = -cquo; + *quo = cquo; + return result; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__remquo), s(remquo)) diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_remquof.c b/src/system/libroot/posix/glibc/arch/m68k/s_remquof.c new file mode 100644 index 0000000000..8a292fc26c --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_remquof.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_remquol.c b/src/system/libroot/posix/glibc/arch/m68k/s_remquol.c new file mode 100644 index 0000000000..d236cfd1f9 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_remquol.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_scalbln.c b/src/system/libroot/posix/glibc/arch/m68k/s_scalbln.c new file mode 100644 index 0000000000..1009713fbc --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_scalbln.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbn. So we define an + alias. */ diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_scalblnf.c b/src/system/libroot/posix/glibc/arch/m68k/s_scalblnf.c new file mode 100644 index 0000000000..5e558c3540 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_scalblnf.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbnf. So we define an + alias. */ diff --git a/src/system/libroot/posix/glibc/arch/m68k/s_scalblnl.c b/src/system/libroot/posix/glibc/arch/m68k/s_scalblnl.c new file mode 100644 index 0000000000..cda2ec11c8 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/s_scalblnl.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbnl. So we define an + alias. */ diff --git a/src/system/libroot/posix/glibc/arch/ppc/Jamfile b/src/system/libroot/posix/glibc/arch/ppc/Jamfile index 21fcd341d8..959deaac34 100644 --- a/src/system/libroot/posix/glibc/arch/ppc/Jamfile +++ b/src/system/libroot/posix/glibc/arch/ppc/Jamfile @@ -112,6 +112,7 @@ local genericSources = w_remainder.c w_remainderf.c # w_remainderl.c w_scalb.c w_scalbf.c # w_scalbl.c w_sinh.c w_sinhf.c # w_sinhl.c + w_tgamma.c w_tgammaf.c w_tgammal.c ; MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : diff --git a/src/system/libroot/posix/glibc/arch/ppc/s_nearbyint.c b/src/system/libroot/posix/glibc/arch/ppc/s_nearbyint.c new file mode 100644 index 0000000000..32f5bf9447 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/ppc/s_nearbyint.c @@ -0,0 +1,98 @@ +/* Adapted for use as nearbyint by Ulrich Drepper . */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; +#endif + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double __nearbyint(double x) +#else + double __nearbyint(x) + double x; +#endif +{ + fenv_t env; + int32_t i0,j0,sx; + u_int32_t i,i1; + double w,t; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + feholdexcept (&env); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + fesetenv (&env); + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if(j0==19) i1 = 0x40000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + feholdexcept (&env); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyint, nearbyint) +#ifdef NO_LONG_DOUBLE +strong_alias (__nearbyint, __nearbyintl) +weak_alias (__nearbyint, nearbyintl) +#endif diff --git a/src/system/libroot/posix/glibc/arch/ppc/s_nearbyintf.c b/src/system/libroot/posix/glibc/arch/ppc/s_nearbyintf.c new file mode 100644 index 0000000000..7d6f262f51 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/ppc/s_nearbyintf.c @@ -0,0 +1,77 @@ +/* s_rintf.c -- float version of s_rint.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +#include +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const float +#else +static float +#endif +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +#ifdef __STDC__ + float __nearbyintf(float x) +#else + float __nearbyintf(x) + float x; +#endif +{ + fenv_t env; + int32_t i0,j0,sx; + u_int32_t i,i1; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + feholdexcept (&env); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + fesetenv (&env); + return t; +} +weak_alias (__nearbyintf, nearbyintf) diff --git a/src/system/libroot/posix/glibc/arch/x86/Jamfile b/src/system/libroot/posix/glibc/arch/x86/Jamfile index 2d5fc6f0bb..e02678d629 100644 --- a/src/system/libroot/posix/glibc/arch/x86/Jamfile +++ b/src/system/libroot/posix/glibc/arch/x86/Jamfile @@ -62,7 +62,7 @@ local genericSources = s_matherr.c s_modf.c s_modff.c # s_modfl.c s_nan.c s_nanf.c - s_nextafter.c + s_nextafter.c s_nextafterf.c s_signbit.c s_signbitf.c s_signbitl.c s_round.c s_roundf.c s_roundl.c s_signgam.c @@ -156,8 +156,11 @@ MergeObject posix_gnu_arch_$(TARGET_ARCH)_s.o : s_log1p.S s_log1pf.S s_log1pl.S s_logb.S s_logbf.S s_logbl.c s_lrint.S s_lrintf.S s_lrintl.S - s_nextafterf.c + s_nearbyint.S s_nearbyintf.S s_nearbyintl.S + s_nextafterl.c + s_remquo.S s_remquof.S s_remquol.S s_rint.S s_rintf.S s_rintl.c + s_scalbln.c s_scalblnf.c s_scalblnl.c s_scalbn.S s_scalbnf.S s_scalbnl.S s_significand.S s_significandf.S s_sin.S s_sinf.S s_sinl.S diff --git a/src/system/libroot/posix/glibc/arch/x86/s_nearbyint.S b/src/system/libroot/posix/glibc/arch/x86/s_nearbyint.S new file mode 100644 index 0000000000..d8bb382d9e --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_nearbyint.S @@ -0,0 +1,25 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +#include + +ENTRY(__nearbyint) + fldl 4(%esp) + pushl %eax + pushl %ecx + fnstcw (%esp) + movl (%esp), %eax + orl $0x20, %eax + movl %eax, 4(%esp) + fldcw 4(%esp) + frndint + fclex + fldcw (%esp) + popl %ecx + popl %eax + ret +END (__nearbyint) +weak_alias (__nearbyint, nearbyint) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_nearbyintf.S b/src/system/libroot/posix/glibc/arch/x86/s_nearbyintf.S new file mode 100644 index 0000000000..21858650e2 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_nearbyintf.S @@ -0,0 +1,25 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +#include + +ENTRY(__nearbyintf) + flds 4(%esp) + pushl %eax + pushl %ecx + fnstcw (%esp) + movl (%esp), %eax + orl $0x20, %eax + movl %eax, 4(%esp) + fldcw 4(%esp) + frndint + fclex + fldcw (%esp) + popl %ecx + popl %eax + ret +END (__nearbyintf) +weak_alias (__nearbyintf, nearbyintf) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_nearbyintl.S b/src/system/libroot/posix/glibc/arch/x86/s_nearbyintl.S new file mode 100644 index 0000000000..d74dacb990 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_nearbyintl.S @@ -0,0 +1,25 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ +/* Adapted for use as nearbyint by Ulrich Drepper . */ + +#include + +ENTRY(__nearbyintl) + fldt 4(%esp) + pushl %eax + pushl %ecx + fnstcw (%esp) + movl (%esp), %eax + orl $0x20, %eax + movl %eax, 4(%esp) + fldcw 4(%esp) + frndint + fclex + fldcw (%esp) + popl %ecx + popl %eax + ret +END (__nearbyintl) +weak_alias (__nearbyintl, nearbyintl) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_nextafterl.c b/src/system/libroot/posix/glibc/arch/x86/s_nextafterl.c new file mode 100644 index 0000000000..5b617cb4e7 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_nextafterl.c @@ -0,0 +1,124 @@ +/* s_nextafterl.c -- long double version of s_nextafter.c. + * Special version for i387. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + long double __nextafterl(long double x, long double y) +#else + long double __nextafterl(x,y) + long double x,y; +#endif +{ + u_int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + int32_t esx,esy; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + /* Intel's extended format has the normally implicit 1 explicit + present. Sigh! */ + if(((ix==0x7fff)&&(((hx&0x7fffffff)|lx)!=0)) || /* x is nan */ + ((iy==0x7fff)&&(((hy&0x7fffffff)|ly)!=0))) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(esx>=0) { /* x > 0 */ + if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if (hx <= 0x80000000) { + if (esx == 0) { + --hx; + } else { + esx -= 1; + hx = hx - 1; + if (esx > 0) + hx |= 0x80000000; + } + } else + hx -= 1; + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0 || (esx == 0 && hx == 0x80000000)) { + esx += 1; + hx |= 0x80000000; + } + } + } + } else { /* x < 0 */ + if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if (hx <= 0x80000000) { + esx -= 1; + hx = hx - 1; + if ((esx&0x7fff) > 0) + hx |= 0x80000000; + } else + hx -= 1; + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) { + esx += 1; + hx |= 0x80000000; + } + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS(y,esx,hx,lx); + return y; + } + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} +weak_alias (__nextafterl, nextafterl) +strong_alias (__nextafterl, __nexttowardl) +weak_alias (__nextafterl, nexttowardl) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_remquo.S b/src/system/libroot/posix/glibc/arch/x86/s_remquo.S new file mode 100644 index 0000000000..5056593214 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_remquo.S @@ -0,0 +1,50 @@ +/* + * Written by Ulrich Drepper . + * Based on e_remainder by J.T. Conklin . + * Public domain. + */ + +#include +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE /* no space for saved regs */ +#define DVDND PARMS +#define DVSOR DVDND+8 +#define QUOP DVSOR+8 + + .text +ENTRY (BP_SYM (__remquo)) + ENTER + + fldl DVSOR(%esp) + fldl DVDND(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + /* Compute the congruent of the quotient. */ + movl %eax, %ecx + shrl $8, %eax + shrl $12, %ecx + andl $4, %ecx + andl $3, %eax + orl %eax, %ecx + leal (%ecx,%ecx,2),%ecx + movl $0xef2a60, %eax + shrl %cl, %eax + andl $7, %eax + movl QUOP(%esp), %ecx + CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4) + movl DVDND+4(%esp), %edx + xorl DVSOR+4(%esp), %edx + testl $0x80000000, %edx + jz 1f + negl %eax +1: movl %eax, (%ecx) + + LEAVE + ret +END (BP_SYM (__remquo)) +weak_alias (BP_SYM (__remquo), BP_SYM (remquo)) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_remquof.S b/src/system/libroot/posix/glibc/arch/x86/s_remquof.S new file mode 100644 index 0000000000..d3c5965be4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_remquof.S @@ -0,0 +1,50 @@ +/* + * Written by Ulrich Drepper . + * Based on e_remainder by J.T. Conklin . + * Public domain. + */ + +#include +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE /* no space for saved regs */ +#define DVDND PARMS +#define DVSOR DVDND+4 +#define QUOP DVSOR+4 + + .text +ENTRY (BP_SYM (__remquof)) + ENTER + + flds DVSOR(%esp) + flds DVDND(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + /* Compute the congruent of the quotient. */ + movl %eax, %ecx + shrl $8, %eax + shrl $12, %ecx + andl $4, %ecx + andl $3, %eax + orl %eax, %ecx + leal (%ecx,%ecx,2),%ecx + movl $0xef2a60, %eax + shrl %cl, %eax + andl $7, %eax + movl QUOP(%esp), %ecx + CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4) + movl DVDND(%esp), %edx + xorl DVSOR(%esp), %edx + testl $0x80000000, %edx + jz 1f + negl %eax +1: movl %eax, (%ecx) + + LEAVE + ret +END (BP_SYM (__remquof)) +weak_alias (BP_SYM (__remquof), BP_SYM (remquof)) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_remquol.S b/src/system/libroot/posix/glibc/arch/x86/s_remquol.S new file mode 100644 index 0000000000..65240adbe4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_remquol.S @@ -0,0 +1,50 @@ +/* + * Written by Ulrich Drepper . + * Based on e_remainder by J.T. Conklin . + * Public domain. + */ + +#include +#include "bp-sym.h" +#include "bp-asm.h" + +#define PARMS LINKAGE /* no space for saved regs */ +#define DVDND PARMS +#define DVSOR DVDND+12 +#define QUOP DVSOR+12 + + .text +ENTRY (BP_SYM (__remquol)) + ENTER + + fldt DVSOR(%esp) + fldt DVDND(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + /* Compute the congruent of the quotient. */ + movl %eax, %ecx + shrl $8, %eax + shrl $12, %ecx + andl $4, %ecx + andl $3, %eax + orl %eax, %ecx + leal (%ecx,%ecx,2),%ecx + movl $0xef2a60, %eax + shrl %cl, %eax + andl $7, %eax + movl QUOP(%esp), %ecx + CHECK_BOUNDS_BOTH_WIDE (%ecx, QUOP(%esp), $4) + movl DVDND+8(%esp), %edx + xorl DVSOR+8(%esp), %edx + testl $0x8000, %edx + jz 1f + negl %eax +1: movl %eax, (%ecx) + + LEAVE + ret +END (BP_SYM (__remquol)) +weak_alias (BP_SYM (__remquol), BP_SYM (remquol)) diff --git a/src/system/libroot/posix/glibc/arch/x86/s_scalblnl.c b/src/system/libroot/posix/glibc/arch/x86/s_scalblnl.c new file mode 100644 index 0000000000..cda2ec11c8 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/x86/s_scalblnl.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbnl. So we define an + alias. */ diff --git a/src/system/libroot/posix/glibc/include/arch/m68k/bits/mathdef.h b/src/system/libroot/posix/glibc/include/arch/m68k/bits/mathdef.h index 90146f17a9..8b02db0899 100644 --- a/src/system/libroot/posix/glibc/include/arch/m68k/bits/mathdef.h +++ b/src/system/libroot/posix/glibc/include/arch/m68k/bits/mathdef.h @@ -31,6 +31,9 @@ typedef long double float_t; /* `float' expressions are evaluated as typedef long double double_t; /* `double' expressions are evaluated as `long double'. */ +/* Signal that types are long double */ +# define FLT_EVAL_METHOD 2 + /* Define `INFINITY' as value of type `float'. */ # define INFINITY HUGE_VALF