added more posix functions
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27348 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+10
-1
@@ -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);
|
||||
|
||||
@@ -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 <[email protected]>, 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 <math.h>
|
||||
|
||||
#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
|
||||
@@ -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 <[email protected]>, 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 <math.h>
|
||||
|
||||
#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)
|
||||
@@ -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 <[email protected]>, 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 <math.h>
|
||||
|
||||
#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)
|
||||
@@ -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
|
||||
;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#define FUNC nearbyint
|
||||
#include <s_atan.c>
|
||||
@@ -0,0 +1,2 @@
|
||||
#define FUNC nearbyintf
|
||||
#include <s_atanf.c>
|
||||
@@ -0,0 +1,2 @@
|
||||
#define FUNC nearbyintl
|
||||
#include <s_atanl.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 <schwab@suse.de>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* 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)
|
||||
@@ -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 <schwab@issan.informatik.uni-dortmund.de>
|
||||
|
||||
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 <math.h>
|
||||
|
||||
#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))
|
||||
@@ -0,0 +1,3 @@
|
||||
#define SUFF f
|
||||
#define float_type float
|
||||
#include <s_remquo.c>
|
||||
@@ -0,0 +1,3 @@
|
||||
#define SUFF l
|
||||
#define float_type long double
|
||||
#include <s_remquo.c>
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Nothing to do. This function is the same as scalbn. So we define an
|
||||
alias. */
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Nothing to do. This function is the same as scalbnf. So we define an
|
||||
alias. */
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Nothing to do. This function is the same as scalbnl. So we define an
|
||||
alias. */
|
||||
@@ -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 :
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/* Adapted for use as nearbyint by Ulrich Drepper <[email protected]>. */
|
||||
/*
|
||||
* ====================================================
|
||||
* 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 <fenv.h>
|
||||
#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
|
||||
@@ -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 <[email protected]>. */
|
||||
|
||||
/*
|
||||
* ====================================================
|
||||
* 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 <fenv.h>
|
||||
#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)
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Written by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
/* Adapted for use as nearbyint by Ulrich Drepper <[email protected]>. */
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Written by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
/* Adapted for use as nearbyint by Ulrich Drepper <[email protected]>. */
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Written by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
/* Adapted for use as nearbyint by Ulrich Drepper <[email protected]>. */
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
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)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Written by Ulrich Drepper <drepper@cygnus.com>.
|
||||
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
#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))
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Written by Ulrich Drepper <drepper@cygnus.com>.
|
||||
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
#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))
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Written by Ulrich Drepper <drepper@cygnus.com>.
|
||||
* Based on e_remainder by J.T. Conklin <jtc@netbsd.org>.
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
#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))
|
||||
@@ -0,0 +1,2 @@
|
||||
/* Nothing to do. This function is the same as scalbnl. So we define an
|
||||
alias. */
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user