This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to support IEEE float variations




This patch adds two configuration macros to libm to support variations
on the 32-bit IEEE float format:

  - _LARGEST_EXPONENT_IS_NORMAL means that the float format uses the
    largest exponent for finite numbers rather than NaNs and infinities.
    FLT_MAX will be twice the IEEE value, but NaNs and infinities cannot
    be represented.

  - _NO_DENORMALS means that IEEE denormals are not supported.  Instead,
    any number with a zero exponent field is a zero representation.

The changes mostly involved replacing hard-coded comparisons with macros
whose definitions depend on the float format.  For example:

	(hx>=0x7f800000) becomes (!UWORD_IS_FINITE(hx))
	(hx<=0x42b17217) becomes (hx<=UWORD_LOG_FLT_MAX)

Some code shuffling was also needed, such as moving zero checks outside
subnormal checks.  But I tried to only change the integer operations, not the
floating-point ones, so that status & exception behaviour wouldn't be
affected.

The patch only changes the single precision stuff, so I tested it by
comparing the single and double precision functions.  I've described the
testing in more detail below, but I can send the code for the test harness
if anyone's interested.

I tested on an i386 with neither of the new macros defined, and on another
processor with both defined.  There were no regressions on the i386:
the functions returned the same values before and after the patch
using the inputs described below.  The new version behaved as expected.

One thing: hypotf() doesn't seem to work on extreme input values.  E.g:

	 hypotf(2**-126, 2**-126)
	 gives 2.828427
	 rather than sqrt(2) * 2**-126

The problem seems to happen on current sources and isn't corrected by
this patch.  I'll try to look into it sometime.

Is it OK to apply?

Richard

------- TESTING -------

The test harness tried each unary function with a set of "interesting" input
values and each binary function with every combination of those values.  The
values were:

   Group 1:

	Mask		IEEE meaning	Variant meaning
	------------------------------------------------
	0x7fffffff	NaN		2**129 - 2**105
	0x7f7fffff	2**128 - 2**104	as for IEEE
	0x00800000	2**-126		as for IEEE
	0x00000001	2**-149		0

   Group 2:

	- the modulus of the logs of Group 1 numbers
	- log(2**130 - 2**106), the largest useful input to coshf() when
	  the largest exponent is used for finite numbers.

   Group 3:

	- 8 4 2 1

   Group 4:

	- arbitrary numbers between each of those in groups 1-3, with at
          least one between any pair of group 1-3 numbers.
	- the next numbers above and below those in groups 1-3,
	  except that there's no number above 0x7fffffff.  That includes:

	Mask		IEEE meaning	Variant meaning
	------------------------------------------------
	0x00000000	0		as for IEEE
	0x7f800000	Infinity	2**128

   Group 5:

	- the negatives of numbers in groups 1-4

When a function returns a second value through a pointer argument, the
second return values were tested too.  I tried the jnf(), ynf() and scalbf()
functions with integer arguments in the range [-6,6].  I ran the tests with
the library mode set to IEEE.


2001-03-30  Richard Sandiford  <rsandifo@redhat.com>

	* libm/common/fdlib.h: Define two new configuration macros,
	_LARGEST_EXPONENT_IS_NORMAL and _NO_DENORMALS.  Use them to define
	new format-specific macros for constants and exceptional values.
	* libm/common/sf_*: Use new macros.
	* libm/math/ef_*: Likewise.
	* libm/math/sf_*: Likewise.

Index: ./libm/common/fdlibm.h
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/fdlibm.h,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 fdlibm.h
*** ./libm/common/fdlibm.h	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/fdlibm.h	2001/03/30 16:08:39
***************
*** 18,30 ****
  /* CYGNUS LOCAL: Default to XOPEN_MODE.  */
  #define _XOPEN_MODE

  #ifdef __STDC__
  #define	__P(p)	p
  #else
  #define	__P(p)	()
  #endif
-
- #define	HUGE	((float)3.40282346638528860e+38)

  /*
   * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
--- 18,132 ----
  /* CYGNUS LOCAL: Default to XOPEN_MODE.  */
  #define _XOPEN_MODE

+ /* Most routines need to check whether a float is finite, infinite, or not a
+    number, and many need to know whether the result of an operation will
+    overflow.  These conditions depend on whether the largest exponent is
+    used for NaNs & infinities, or whether it's used for finite numbers.	 The
+    macros below wrap up that kind of information:
+
+    UWORD_IS_FINITE(X)
+ 	True if a positive float with bitmask X is finite.
+
+    UWORD_IS_NAN(X)
+ 	True if a positive float with bitmask X is not a number.
+
+    UWORD_IS_INFINITE(X)
+ 	True if a positive float with bitmask X is +infinity.
+
+    UWORD_MAX
+ 	The bitmask of FLT_MAX.
+
+    UWORD_HALF_MAX
+ 	The bitmask of FLT_MAX/2.
+
+    UWORD_EXP_MAX
+ 	The bitmask of the largest finite exponent (129 if the largest
+ 	exponent is used for finite numbers, 128 otherwise).
+
+    UWORD_LOG_FLT_MAX
+ 	The bitmask of log(FLT_MAX), rounded down.  This value is the largest
+ 	input that can be passed to exp() without producing overflow.
+
+    UWORD_LOG_2FLT_MAX
+ 	The bitmask of log(2*FLT_MAX), rounded down.  This value is the
+ 	largest input than can be passed to cosh() without producing
+ 	overflow.
+
+    LARGEST_EXP
+ 	The largest biased exponent that can be used for finite numbers
+ 	(255 if the largest exponent is used for finite numbers, 254
+ 	otherwise) */
+
+ #ifdef _LARGEST_EXPONENT_IS_NORMAL
+ #define UWORD_IS_FINITE(x) 1
+ #define UWORD_IS_NAN(x) 0
+ #define UWORD_IS_INFINITE(x) 0
+ #define UWORD_MAX 0x7fffffff
+ #define UWORD_EXP_MAX 0x43010000
+ #define UWORD_LOG_FLT_MAX 0x42b2d4fc
+ #define UWORD_LOG_2FLT_MAX 0x42b437e0
+ #define HUGE ((float)0X1.FFFFFEP128)
+ #else
+ #define UWORD_IS_FINITE(x) ((x)<0x7f800000L)
+ #define UWORD_IS_NAN(x) ((x)>0x7f800000L)
+ #define UWORD_IS_INFINITE(x) ((x)==0x7f800000L)
+ #define UWORD_MAX 0x7f7fffff
+ #define UWORD_EXP_MAX 0x43000000
+ #define UWORD_LOG_FLT_MAX 0x42b17217
+ #define UWORD_LOG_2FLT_MAX 0x42b2d4fc
+ #define HUGE ((float)3.40282346638528860e+38)
+ #endif
+ #define UWORD_HALF_MAX (UWORD_MAX-(1<<23))
+ #define LARGEST_EXP (UWORD_MAX>>23)
+
+ /* Many routines check for zero and subnormal numbers.  Such things depend
+    on whether the target supports denormals or not:
+
+    UWORD_IS_ZERO(X)
+ 	True if a positive float with bitmask X is +0.	Without denormals,
+ 	any float with a zero exponent is a +0 representation.	With
+ 	denormals, the only +0 representation is a 0 bitmask.
+
+    UWORD_IS_SUBNORMAL(X)
+ 	True if a non-zero positive float with bitmask X is subnormal.
+ 	(Routines should check for zeros first.)
+
+    UWORD_MIN
+ 	The bitmask of the smallest float above +0.  Call this number
+ 	REAL_FLT_MIN...
+
+    UWORD_EXP_MIN
+ 	The bitmask of the float representation of REAL_FLT_MIN's exponent.
+
+    UWORD_LOG_FLT_MIN
+ 	The bitmask of |log(REAL_FLT_MIN)|, rounding down.
+
+    SMALLEST_EXP
+ 	REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported,
+ 	-22 if they are).
+ */
+
+ #ifdef _NO_DENORMALS
+ #define UWORD_IS_ZERO(x) ((x)<0x00800000L)
+ #define UWORD_IS_SUBNORMAL(x) 0
+ #define UWORD_MIN 0x00800000
+ #define UWORD_EXP_MIN 0x42fc0000
+ #define UWORD_LOG_FLT_MIN 0x42aeac50
+ #define SMALLEST_EXP 1
+ #else
+ #define UWORD_IS_ZERO(x) ((x)==0)
+ #define UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L)
+ #define UWORD_MIN 0x00000001
+ #define UWORD_EXP_MIN 0x43160000
+ #define UWORD_LOG_FLT_MIN 0x42cff1b5
+ #define SMALLEST_EXP -22
+ #endif
+
  #ifdef __STDC__
  #define	__P(p)	p
  #else
  #define	__P(p)	()
  #endif

  /*
   * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
Index: ./libm/common/sf_cbrt.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_cbrt.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_cbrt.c
*** ./libm/common/sf_cbrt.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_cbrt.c	2001/03/30 16:08:39
*************** G =  3.5714286566e-01; /* 5/14      = 0x
*** 53,65 ****
  	GET_FLOAT_WORD(hx,x);
  	sign=hx&0x80000000; 		/* sign= sign(x) */
  	hx  ^=sign;
! 	if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */
! 	if(hx==0)
  	    return(x);		/* cbrt(0) is itself */

  	SET_FLOAT_WORD(x,hx);	/* x <- |x| */
      /* rough cbrt to 5 bits */
! 	if(hx<0x00800000) 		/* subnormal number */
  	  {SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */
  	   t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,high/3+B2);
  	  }
--- 53,65 ----
  	GET_FLOAT_WORD(hx,x);
  	sign=hx&0x80000000; 		/* sign= sign(x) */
  	hx  ^=sign;
! 	if(!UWORD_IS_FINITE(hx)) return(x+x); /* cbrt(NaN,INF) is itself */
! 	if(UWORD_IS_ZERO(hx))
  	    return(x);		/* cbrt(0) is itself */

  	SET_FLOAT_WORD(x,hx);	/* x <- |x| */
      /* rough cbrt to 5 bits */
! 	if(UWORD_IS_SUBNORMAL(hx)) 		/* subnormal number */
  	  {SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */
  	   t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,high/3+B2);
  	  }
Index: ./libm/common/sf_expm1.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_expm1.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 sf_expm1.c
*** ./libm/common/sf_expm1.c	2000/04/17 17:10:18	1.2
--- ./libm/common/sf_expm1.c	2001/03/30 16:08:40
*************** static float
*** 27,33 ****
  one		= 1.0,
  huge		= 1.0e+30,
  tiny		= 1.0e-30,
- o_threshold	= 8.8721679688e+01,/* 0x42b17180 */
  ln2_hi		= 6.9313812256e-01,/* 0x3f317180 */
  ln2_lo		= 9.0580006145e-06,/* 0x3717f7d1 */
  invln2		= 1.4426950216e+00,/* 0x3fb8aa3b */
--- 27,32 ----
*************** Q5  =  -2.0109921195e-07; /* 0xb457edbb
*** 56,68 ****

      /* filter out huge and non-finite argument */
  	if(hx >= 0x4195b844) {			/* if |x|>=27*ln2 */
! 	    if(hx >= 0x42b17218) {		/* if |x|>=88.721... */
!                 if(hx>0x7f800000)
! 		    return x+x; 	 /* NaN */
! 		if(hx==0x7f800000)
! 		    return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
! 	        if(x > o_threshold) return huge*huge; /* overflow */
! 	    }
  	    if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
  		if(x+tiny<(float)0.0)	/* raise inexact */
  		return tiny-one;	/* return -1 */
--- 55,66 ----

      /* filter out huge and non-finite argument */
  	if(hx >= 0x4195b844) {			/* if |x|>=27*ln2 */
! 	    if(UWORD_IS_NAN(hx))
! 	        return x+x;
! 	    if(UWORD_IS_INFINITE(hx))
! 		return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
! 	    if(xsb == 0 && hx > UWORD_LOG_FLT_MAX) /* if x>=o_threshold */
! 		return huge*huge; /* overflow */
  	    if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
  		if(x+tiny<(float)0.0)	/* raise inexact */
  		return tiny-one;	/* return -1 */
Index: ./libm/common/sf_finite.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_finite.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_finite.c
*** ./libm/common/sf_finite.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_finite.c	2001/03/30 16:08:40
***************
*** 29,35 ****
  {
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
! 	return  (int)((__uint32_t)((ix&0x7fffffff)-0x7f800000)>>31);
  }

  #ifdef _DOUBLE_IS_32BITS
--- 29,36 ----
  {
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
! 	ix &= 0x7fffffff;
! 	return (UWORD_IS_FINITE(ix));
  }

  #ifdef _DOUBLE_IS_32BITS
Index: ./libm/common/sf_ilogb.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_ilogb.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_ilogb.c
*** ./libm/common/sf_ilogb.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_ilogb.c	2001/03/30 16:08:40
***************
*** 27,41 ****

  	GET_FLOAT_WORD(hx,x);
  	hx &= 0x7fffffff;
! 	if(hx<0x00800000) {
! 	    if(hx==0)
! 		return - INT_MAX;	/* ilogb(0) = 0x80000001 */
! 	    else			/* subnormal x */
! 	        for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
  	    return ix;
  	}
! 	else if (hx<0x7f800000) return (hx>>23)-127;
! 	else return INT_MAX;
  }

  #ifdef _DOUBLE_IS_32BITS
--- 27,40 ----

  	GET_FLOAT_WORD(hx,x);
  	hx &= 0x7fffffff;
! 	if(UWORD_IS_ZERO(hx))
! 	    return - INT_MAX;	/* ilogb(0) = 0x80000001 */
! 	if(UWORD_IS_SUBNORMAL(hx)) {
! 	    for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
  	    return ix;
  	}
! 	else if (!UWORD_IS_FINITE(hx)) return INT_MAX;
! 	else return (hx>>23)-127;
  }

  #ifdef _DOUBLE_IS_32BITS
Index: ./libm/common/sf_log1p.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_log1p.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 sf_log1p.c
*** ./libm/common/sf_log1p.c	2000/04/17 17:10:18	1.2
--- ./libm/common/sf_log1p.c	2001/03/30 16:08:40
*************** static float zero = 0.0;
*** 51,56 ****
--- 51,57 ----
  	ax = hx&0x7fffffff;

  	k = 1;
+ 	if (!UWORD_IS_FINITE(hx)) return x+x;
  	if (hx < 0x3ed413d7) {			/* x < 0.41422  */
  	    if(ax>=0x3f800000) {		/* x <= -1.0 */
  		if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */
*************** static float zero = 0.0;
*** 65,72 ****
  	    }
  	    if(hx>0||hx<=((__int32_t)0xbe95f61f)) {
  		k=0;f=x;hu=1;}	/* -0.2929<x<0.41422 */
! 	}
! 	if (hx >= 0x7f800000) return x+x;
  	if(k!=0) {
  	    if(hx<0x5a000000) {
  		u  = (float)1.0+x;
--- 66,72 ----
  	    }
  	    if(hx>0||hx<=((__int32_t)0xbe95f61f)) {
  		k=0;f=x;hu=1;}	/* -0.2929<x<0.41422 */
! 	}
  	if(k!=0) {
  	    if(hx<0x5a000000) {
  		u  = (float)1.0+x;
Index: ./libm/common/sf_logb.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_logb.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_logb.c
*** ./libm/common/sf_logb.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_logb.c	2001/03/30 16:08:40
***************
*** 25,32 ****
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;			/* high |x| */
! 	if(ix==0) return (float)-1.0/fabsf(x);
! 	if(ix>=0x7f800000) return x*x;
  	if((ix>>=23)==0) 			/* IEEE 754 logb */
  		return -126.0;
  	else
--- 25,32 ----
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;			/* high |x| */
! 	if(UWORD_IS_ZERO(ix)) return (float)-1.0/fabsf(x);
! 	if(!UWORD_IS_FINITE(ix)) return x*x;
  	if((ix>>=23)==0) 			/* IEEE 754 logb */
  		return -126.0;
  	else
Index: ./libm/common/sf_nan.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_nan.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_nan.c
*** ./libm/common/sf_nan.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_nan.c	2001/03/30 16:08:40
***************
*** 21,23 ****
--- 21,24 ----
  }

  #endif /* defined(_DOUBLE_IS_32BITS) */
+
Index: ./libm/common/sf_nextafter.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_nextafter.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_nextafter.c
*** ./libm/common/sf_nextafter.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_nextafter.c	2001/03/30 16:08:40
***************
*** 29,43 ****
  	ix = hx&0x7fffffff;		/* |x| */
  	iy = hy&0x7fffffff;		/* |y| */

! 	if((ix>0x7f800000) ||   /* x is nan */
! 	   (iy>0x7f800000))     /* y is nan */
! 	   return x+y;
  	if(x==y) return x;		/* x=y, return x */
! 	if(ix==0) {				/* x == 0 */
! 	    SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
  	    y = x*x;
  	    if(y==x) return y; else return x;	/* raise underflow flag */
! 	}
  	if(hx>=0) {				/* x > 0 */
  	    if(hx>hy) {				/* x > y, x -= ulp */
  		hx -= 1;
--- 29,43 ----
  	ix = hx&0x7fffffff;		/* |x| */
  	iy = hy&0x7fffffff;		/* |y| */

! 	if(UWORD_IS_NAN(ix) ||
! 	   UWORD_IS_NAN(iy))
! 	   return x+y;
  	if(x==y) return x;		/* x=y, return x */
! 	if(UWORD_IS_ZERO(ix)) {		/* x == 0 */
! 	    SET_FLOAT_WORD(x,(hy&0x80000000)|UWORD_MIN);
  	    y = x*x;
  	    if(y==x) return y; else return x;	/* raise underflow flag */
! 	}
  	if(hx>=0) {				/* x > 0 */
  	    if(hx>hy) {				/* x > y, x -= ulp */
  		hx -= 1;
***************
*** 52,58 ****
  	    }
  	}
  	hy = hx&0x7f800000;
! 	if(hy>=0x7f800000) return x+x;	/* overflow  */
  	if(hy<0x00800000) {		/* underflow */
  	    y = x*x;
  	    if(y!=x) {		/* raise underflow flag */
--- 52,58 ----
  	    }
  	}
  	hy = hx&0x7f800000;
! 	if(hy>UWORD_MAX) return x+x;	/* overflow  */
  	if(hy<0x00800000) {		/* underflow */
  	    y = x*x;
  	    if(y!=x) {		/* raise underflow flag */
Index: ./libm/common/sf_rint.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_rint.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_rint.c
*** ./libm/common/sf_rint.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/common/sf_rint.c	2001/03/30 16:08:40
*************** TWO23[2]={
*** 33,47 ****
  #endif
  {
  	__int32_t i0,j0,sx;
! 	__uint32_t i,i1;
  	float t;
  	volatile float w;
  	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;
--- 33,49 ----
  #endif
  {
  	__int32_t i0,j0,sx;
! 	__uint32_t i,i1,ix;
  	float t;
  	volatile float w;
  	GET_FLOAT_WORD(i0,x);
  	sx = (i0>>31)&1;
! 	ix = (i0&0x7fffffff);
! 	j0 = (ix>>23)-0x7f;
  	if(j0<23) {
! 	    if(UWORD_IS_ZERO(ix))
! 	        return x;
! 	    if(j0<0) {
  		i1 = (i0&0x07fffff);
  		i0 &= 0xfff00000;
  		i0 |= ((i1|-i1)>>9)&0x400000;
*************** TWO23[2]={
*** 58,65 ****
  		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);
  	w = TWO23[sx]+x;
--- 60,68 ----
  		if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
  	    }
  	} else {
! 	    if(!UWORD_IS_FINITE(ix)) return x+x; /* inf or NaN */
! 	    else
! 	      return x;		/* x is integral */
  	}
  	SET_FLOAT_WORD(x,i0);
  	w = TWO23[sx]+x;
Index: ./libm/common/sf_scalbn.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/common/sf_scalbn.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 sf_scalbn.c
*** ./libm/common/sf_scalbn.c	2000/04/17 17:10:18	1.2
--- ./libm/common/sf_scalbn.c	2001/03/30 16:08:40
***************
*** 15,20 ****
--- 15,21 ----

  #include "fdlibm.h"
  #include <limits.h>
+ #include <float.h>

  #if INT_MAX > 50000
  #define OVERFLOW_INT 50000
*************** tiny   = 1.0e-30;
*** 40,64 ****
  #endif
  {
  	__int32_t  k,ix;
  	GET_FLOAT_WORD(ix,x);
!         k = (ix&0x7f800000)>>23;		/* extract exponent */
!         if (k==0) {				/* 0 or subnormal x */
!             if ((ix&0x7fffffff)==0) return x; /* +-0 */
  	    x *= two25;
  	    GET_FLOAT_WORD(ix,x);
  	    k = ((ix&0x7f800000)>>23) - 25;
              if (n< -50000) return tiny*x; 	/*underflow*/
! 	    }
!         if (k==0xff) return x+x;		/* NaN or Inf */
          k = k+n;
!         if (k >  0xfe) return huge*copysignf(huge,x); /* overflow  */
          if (k > 0) 				/* normal result */
  	    {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
!         if (k <= -25) {
              if (n > OVERFLOW_INT) 	/* in case integer overflow in n+k */
  		return huge*copysignf(huge,x);	/*overflow*/
  	    else return tiny*copysignf(tiny,x);	/*underflow*/
!        }
          k += 25;				/* subnormal result */
  	SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
          return x*twom25;
--- 41,70 ----
  #endif
  {
  	__int32_t  k,ix;
+ 	__uint32_t hx;
+
  	GET_FLOAT_WORD(ix,x);
! 	hx = ix&0x7fffffff;
!         k = hx>>23;		/* extract exponent */
! 	if (UWORD_IS_ZERO(hx))
! 	    return x;
!         if (!UWORD_IS_FINITE(hx))
! 	    return x+x;		/* NaN or Inf */
!         if (UWORD_IS_SUBNORMAL(hx)) {
  	    x *= two25;
  	    GET_FLOAT_WORD(ix,x);
  	    k = ((ix&0x7f800000)>>23) - 25;
              if (n< -50000) return tiny*x; 	/*underflow*/
!         }
          k = k+n;
!         if (k > LARGEST_EXP) return huge*copysignf(huge,x); /* overflow  */
          if (k > 0) 				/* normal result */
  	    {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
!         if (k < SMALLEST_EXP) {
              if (n > OVERFLOW_INT) 	/* in case integer overflow in n+k */
  		return huge*copysignf(huge,x);	/*overflow*/
  	    else return tiny*copysignf(tiny,x);	/*underflow*/
!         }
          k += 25;				/* subnormal result */
  	SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
          return x*twom25;
Index: ./libm/math/ef_acosh.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_acosh.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_acosh.c
*** ./libm/math/ef_acosh.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_acosh.c	2001/03/30 16:08:40
*************** ln2	= 6.9314718246e-01;  /* 0x3f317218 *
*** 37,43 ****
  	if(hx<0x3f800000) {		/* x < 1 */
  	    return (x-x)/(x-x);
  	} else if(hx >=0x4d800000) {	/* x > 2**28 */
! 	    if(hx >=0x7f800000) {	/* x is inf of NaN */
  	        return x+x;
  	    } else
  		return __ieee754_logf(x)+ln2;	/* acosh(huge)=log(2x) */
--- 37,43 ----
  	if(hx<0x3f800000) {		/* x < 1 */
  	    return (x-x)/(x-x);
  	} else if(hx >=0x4d800000) {	/* x > 2**28 */
! 	    if(!UWORD_IS_FINITE(hx)) {	/* x is inf of NaN */
  	        return x+x;
  	    } else
  		return __ieee754_logf(x)+ln2;	/* acosh(huge)=log(2x) */
Index: ./libm/math/ef_atan2.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_atan2.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_atan2.c
*** ./libm/math/ef_atan2.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_atan2.c	2001/03/30 16:08:40
*************** pi_lo   = 1.5099578832e-07; /* 0x3422216
*** 42,55 ****
  	ix = hx&0x7fffffff;
  	GET_FLOAT_WORD(hy,y);
  	iy = hy&0x7fffffff;
! 	if((ix>0x7f800000)||
! 	   (iy>0x7f800000))	/* x or y is NaN */
  	   return x+y;
  	if(hx==0x3f800000) return atanf(y);   /* x=1.0 */
  	m = ((hy>>31)&1)|((hx>>30)&2);	/* 2*sign(x)+sign(y) */

      /* when y = 0 */
! 	if(iy==0) {
  	    switch(m) {
  		case 0:
  		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
--- 42,55 ----
  	ix = hx&0x7fffffff;
  	GET_FLOAT_WORD(hy,y);
  	iy = hy&0x7fffffff;
! 	if(UWORD_IS_NAN(ix)||
! 	   UWORD_IS_NAN(iy))	/* x or y is NaN */
  	   return x+y;
  	if(hx==0x3f800000) return atanf(y);   /* x=1.0 */
  	m = ((hy>>31)&1)|((hx>>30)&2);	/* 2*sign(x)+sign(y) */

      /* when y = 0 */
! 	if(UWORD_IS_ZERO(iy)) {
  	    switch(m) {
  		case 0:
  		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
*************** pi_lo   = 1.5099578832e-07; /* 0x3422216
*** 58,68 ****
  	    }
  	}
      /* when x = 0 */
! 	if(ix==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;

      /* when x is INF */
! 	if(ix==0x7f800000) {
! 	    if(iy==0x7f800000) {
  		switch(m) {
  		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
  		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
--- 58,68 ----
  	    }
  	}
      /* when x = 0 */
! 	if(UWORD_IS_ZERO(ix)) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;

      /* when x is INF */
! 	if(UWORD_IS_INFINITE(ix)) {
! 	    if(UWORD_IS_INFINITE(iy)) {
  		switch(m) {
  		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
  		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
*************** pi_lo   = 1.5099578832e-07; /* 0x3422216
*** 79,85 ****
  	    }
  	}
      /* when y is INF */
! 	if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;

      /* compute y/x */
  	k = (iy-ix)>>23;
--- 79,85 ----
  	    }
  	}
      /* when y is INF */
! 	if(UWORD_IS_INFINITE(iy)) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;

      /* compute y/x */
  	k = (iy-ix)>>23;
Index: ./libm/math/ef_cosh.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_cosh.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_cosh.c
*** ./libm/math/ef_cosh.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_cosh.c	2001/03/30 16:08:40
*************** static float one = 1.0, half=0.5, huge =
*** 39,45 ****
  	ix &= 0x7fffffff;

      /* x is INF or NaN */
! 	if(ix>=0x7f800000) return x*x;

      /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
  	if(ix<0x3eb17218) {
--- 39,45 ----
  	ix &= 0x7fffffff;

      /* x is INF or NaN */
! 	if(!UWORD_IS_FINITE(ix)) return x*x;

      /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
  	if(ix<0x3eb17218) {
*************** static float one = 1.0, half=0.5, huge =
*** 56,65 ****
  	}

      /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
! 	if (ix < 0x42b17180)  return half*__ieee754_expf(fabsf(x));

      /* |x| in [log(maxdouble), overflowthresold] */
! 	if (ix<=0x42b2d4fc) {
  	    w = __ieee754_expf(half*fabsf(x));
  	    t = half*w;
  	    return t*w;
--- 56,66 ----
  	}

      /* |x| in [22, log(maxdouble)] return half*exp(|x|) */
! 	if (ix <= UWORD_LOG_FLT_MAX)
! 	  return half*__ieee754_expf(fabsf(x));

      /* |x| in [log(maxdouble), overflowthresold] */
! 	if (ix <= UWORD_LOG_2FLT_MAX) {
  	    w = __ieee754_expf(half*fabsf(x));
  	    t = half*w;
  	    return t*w;
Index: ./libm/math/ef_exp.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_exp.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_exp.c
*** ./libm/math/ef_exp.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_exp.c	2001/03/30 16:08:40
*************** one	= 1.0,
*** 28,35 ****
  halF[2]	= {0.5,-0.5,},
  huge	= 1.0e+30,
  twom100 = 7.8886090522e-31,      /* 2**-100=0x0d800000 */
- o_threshold=  8.8721679688e+01,  /* 0x42b17180 */
- u_threshold= -1.0397208405e+02,  /* 0xc2cff1b5 */
  ln2HI[2]   ={ 6.9313812256e-01,		/* 0x3f317180 */
  	     -6.9313812256e-01,},	/* 0xbf317180 */
  ln2LO[2]   ={ 9.0580006145e-06,  	/* 0x3717f7d1 */
--- 28,33 ----
*************** P5   =  4.1381369442e-08; /* 0x3331bb4c
*** 49,71 ****
  #endif
  {
  	float y,hi,lo,c,t;
! 	__int32_t k,xsb;
  	__uint32_t hx;

! 	GET_FLOAT_WORD(hx,x);
! 	xsb = (hx>>31)&1;		/* sign bit of x */
! 	hx &= 0x7fffffff;		/* high word of |x| */

      /* filter out non-finite argument */
! 	if(hx >= 0x42b17218) {			/* if |x|>=88.721... */
! 	    if(hx>0x7f800000)
! 		 return x+x;	 		/* NaN */
!             if(hx==0x7f800000)
! 		return (xsb==0)? x:0.0;		/* exp(+-inf)={inf,0} */
! 	    if(x > o_threshold) return huge*huge; /* overflow */
! 	    if(x < u_threshold) return twom100*twom100; /* underflow */
! 	}
!
      /* argument reduction */
  	if(hx > 0x3eb17218) {		/* if  |x| > 0.5 ln2 */
  	    if(hx < 0x3F851592) {	/* and |x| < 1.5 ln2 */
--- 47,69 ----
  #endif
  {
  	float y,hi,lo,c,t;
! 	__int32_t k,xsb,sx;
  	__uint32_t hx;

! 	GET_FLOAT_WORD(sx,x);
! 	xsb = (sx>>31)&1;		/* sign bit of x */
! 	hx = sx & 0x7fffffff;		/* high word of |x| */

      /* filter out non-finite argument */
!         if(UWORD_IS_NAN(hx))
!             return x+x;	 	/* NaN */
!         if(UWORD_IS_INFINITE(hx))
! 	    return (xsb==0)? x:0.0;		/* exp(+-inf)={inf,0} */
! 	if(sx > UWORD_LOG_FLT_MAX)
! 	    return huge*huge; /* overflow */
! 	if(sx < 0 && hx > UWORD_LOG_FLT_MIN)
! 	    return twom100*twom100; /* underflow */
!
      /* argument reduction */
  	if(hx > 0x3eb17218) {		/* if  |x| > 0.5 ln2 */
  	    if(hx < 0x3F851592) {	/* and |x| < 1.5 ln2 */
Index: ./libm/math/ef_fmod.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_fmod.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_fmod.c
*** ./libm/math/ef_fmod.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_fmod.c	2001/03/30 16:08:40
*************** static float one = 1.0, Zero[] = {0.0, -
*** 43,62 ****
  	hy &= 0x7fffffff;	/* |y| */

      /* purge off exception values */
! 	if(hy==0||(hx>=0x7f800000)||		/* y=0,or x not finite */
! 	   (hy>0x7f800000))			/* or y is NaN */
  	    return (x*y)/(x*y);
  	if(hx<hy) return x;			/* |x|<|y| return x */
  	if(hx==hy)
  	    return Zero[(__uint32_t)sx>>31];	/* |x|=|y| return x*0*/

      /* determine ix = ilogb(x) */
! 	if(hx<0x00800000) {	/* subnormal x */
  	    for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
  	} else ix = (hx>>23)-127;

      /* determine iy = ilogb(y) */
! 	if(hy<0x00800000) {	/* subnormal y */
  	    for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
  	} else iy = (hy>>23)-127;

--- 43,65 ----
  	hy &= 0x7fffffff;	/* |y| */

      /* purge off exception values */
! 	if(UWORD_IS_ZERO(hy)||
! 	   !UWORD_IS_FINITE(hx)||
! 	   UWORD_IS_NAN(hy))
  	    return (x*y)/(x*y);
  	if(hx<hy) return x;			/* |x|<|y| return x */
  	if(hx==hy)
  	    return Zero[(__uint32_t)sx>>31];	/* |x|=|y| return x*0*/

+     /* Note: y cannot be zero if we reach here. */
+
      /* determine ix = ilogb(x) */
! 	if(UWORD_IS_SUBNORMAL(hx)) {	/* subnormal x */
  	    for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
  	} else ix = (hx>>23)-127;

      /* determine iy = ilogb(y) */
! 	if(UWORD_IS_SUBNORMAL(hy)) {	/* subnormal y */
  	    for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
  	} else iy = (hy>>23)-127;

*************** static float one = 1.0, Zero[] = {0.0, -
*** 99,104 ****
--- 102,109 ----
  	    hx = ((hx-0x00800000)|((iy+127)<<23));
  	    SET_FLOAT_WORD(x,hx|sx);
  	} else {		/* subnormal output */
+ 	    /* If denormals are not supported, this code will generate a
+ 	       zero representation.  */
  	    n = -126 - iy;
  	    hx >>= n;
  	    SET_FLOAT_WORD(x,hx|sx);
Index: ./libm/math/ef_hypot.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_hypot.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_hypot.c
*** ./libm/math/ef_hypot.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_hypot.c	2001/03/30 16:08:40
***************
*** 35,44 ****
  	if((ha-hb)>0xf000000L) {return a+b;} /* x/y > 2**30 */
  	k=0;
  	if(ha > 0x58800000L) {	/* a>2**50 */
! 	   if(ha >= 0x7f800000L) {	/* Inf or NaN */
  	       w = a+b;			/* for sNaN */
! 	       if(ha == 0x7f800000L) w = a;
! 	       if(hb == 0x7f800000L) w = b;
  	       return w;
  	   }
  	   /* scale a and b by 2**-60 */
--- 35,44 ----
  	if((ha-hb)>0xf000000L) {return a+b;} /* x/y > 2**30 */
  	k=0;
  	if(ha > 0x58800000L) {	/* a>2**50 */
! 	   if(!UWORD_IS_FINITE(ha)) {	/* Inf or NaN */
  	       w = a+b;			/* for sNaN */
! 	       if(UWORD_IS_INFINITE(ha)) w = a;
! 	       if(UWORD_IS_INFINITE(hb)) w = b;
  	       return w;
  	   }
  	   /* scale a and b by 2**-60 */
***************
*** 47,54 ****
  	   SET_FLOAT_WORD(b,hb);
  	}
  	if(hb < 0x26800000L) {	/* b < 2**-50 */
! 	    if(hb <= 0x007fffffL) {	/* subnormal b or 0 */
! 	        if(hb==0) return a;
  		SET_FLOAT_WORD(t1,0x3f000000L);	/* t1=2^126 */
  		b *= t1;
  		a *= t1;
--- 47,55 ----
  	   SET_FLOAT_WORD(b,hb);
  	}
  	if(hb < 0x26800000L) {	/* b < 2**-50 */
! 	    if(UWORD_IS_ZERO(hb)) {
! 	        return a;
! 	    } else if(UWORD_IS_SUBNORMAL(hb)) {
  		SET_FLOAT_WORD(t1,0x3f000000L);	/* t1=2^126 */
  		b *= t1;
  		a *= t1;
Index: ./libm/math/ef_j0.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_j0.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 ef_j0.c
*** ./libm/math/ef_j0.c	2000/05/26 22:42:38	1.2
--- ./libm/math/ef_j0.c	2001/03/30 16:08:41
*************** static float zero = 0.0;
*** 58,71 ****

  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(ix>=0x7f800000) return one/(x*x);
  	x = fabsf(x);
  	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
  		s = sinf(x);
  		c = cosf(x);
  		ss = s-c;
  		cc = s+c;
! 		if(ix<0x7f000000) {  /* make sure x+x not overflow */
  		    z = -cosf(x+x);
  		    if ((s*c)<zero) cc = z/ss;
  		    else 	    ss = z/cc;
--- 58,71 ----

  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(!UWORD_IS_FINITE(ix)) return one/(x*x);
  	x = fabsf(x);
  	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
  		s = sinf(x);
  		c = cosf(x);
  		ss = s-c;
  		cc = s+c;
! 		if(ix<=UWORD_HALF_MAX) {  /* make sure x+x not overflow */
  		    z = -cosf(x+x);
  		    if ((s*c)<zero) cc = z/ss;
  		    else 	    ss = z/cc;
*************** v04  =  4.4111031494e-10; /* 0x2ff280c2
*** 128,135 ****
  	GET_FLOAT_WORD(hx,x);
          ix = 0x7fffffff&hx;
      /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
! 	if(ix>=0x7f800000) return  one/(x+x*x);
!         if(ix==0) return -one/zero;
          if(hx<0) return zero/zero;
          if(ix >= 0x40000000) {  /* |x| >= 2.0 */
          /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
--- 128,135 ----
  	GET_FLOAT_WORD(hx,x);
          ix = 0x7fffffff&hx;
      /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
! 	if(!UWORD_IS_FINITE(ix)) return  one/(x+x*x);
!         if(UWORD_IS_ZERO(ix)) return -one/zero;
          if(hx<0) return zero/zero;
          if(ix >= 0x40000000) {  /* |x| >= 2.0 */
          /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
*************** v04  =  4.4111031494e-10; /* 0x2ff280c2
*** 151,157 ****
  	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
  	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
  	 */
!                 if(ix<0x7f000000) {  /* make sure x+x not overflow */
                      z = -cosf(x+x);
                      if ((s*c)<zero) cc = z/ss;
                      else            ss = z/cc;
--- 151,157 ----
  	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
  	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
  	 */
!                 if(ix<=UWORD_HALF_MAX) {  /* make sure x+x not overflow */
                      z = -cosf(x+x);
                      if ((s*c)<zero) cc = z/ss;
                      else            ss = z/cc;
Index: ./libm/math/ef_j1.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_j1.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 ef_j1.c
*** ./libm/math/ef_j1.c	2000/05/26 22:42:38	1.2
--- ./libm/math/ef_j1.c	2001/03/30 16:08:42
*************** static float zero    = 0.0;
*** 59,72 ****

  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(ix>=0x7f800000) return one/x;
  	y = fabsf(x);
  	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
  		s = sinf(y);
  		c = cosf(y);
  		ss = -s-c;
  		cc = s-c;
! 		if(ix<0x7f000000) {  /* make sure y+y not overflow */
  		    z = cosf(y+y);
  		    if ((s*c)>zero) cc = z/ss;
  		    else 	    ss = z/cc;
--- 59,72 ----

  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(!UWORD_IS_FINITE(ix)) return one/x;
  	y = fabsf(x);
  	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
  		s = sinf(y);
  		c = cosf(y);
  		ss = -s-c;
  		cc = s-c;
! 		if(ix<=UWORD_HALF_MAX) {  /* make sure y+y not overflow */
  		    z = cosf(y+y);
  		    if ((s*c)>zero) cc = z/ss;
  		    else 	    ss = z/cc;
*************** static float V0[5] = {
*** 129,143 ****
  	GET_FLOAT_WORD(hx,x);
          ix = 0x7fffffff&hx;
      /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
! 	if(ix>=0x7f800000) return  one/(x+x*x);
!         if(ix==0) return -one/zero;
          if(hx<0) return zero/zero;
          if(ix >= 0x40000000) {  /* |x| >= 2.0 */
                  s = sinf(x);
                  c = cosf(x);
                  ss = -s-c;
                  cc = s-c;
!                 if(ix<0x7f000000) {  /* make sure x+x not overflow */
                      z = cosf(x+x);
                      if ((s*c)>zero) cc = z/ss;
                      else            ss = z/cc;
--- 129,143 ----
  	GET_FLOAT_WORD(hx,x);
          ix = 0x7fffffff&hx;
      /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
! 	if(!UWORD_IS_FINITE(ix)) return one/(x+x*x);
!         if(UWORD_IS_ZERO(ix)) return -one/zero;
          if(hx<0) return zero/zero;
          if(ix >= 0x40000000) {  /* |x| >= 2.0 */
                  s = sinf(x);
                  c = cosf(x);
                  ss = -s-c;
                  cc = s-c;
!                 if(ix<=UWORD_HALF_MAX) {  /* make sure x+x not overflow */
                      z = cosf(x+x);
                      if ((s*c)>zero) cc = z/ss;
                      else            ss = z/cc;
Index: ./libm/math/ef_jn.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_jn.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_jn.c
*** ./libm/math/ef_jn.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_jn.c	2001/03/30 16:08:42
*************** static float zero  =  0.0000000000e+00;
*** 47,53 ****
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
      /* if J(n,NaN) is NaN */
! 	if(ix>0x7f800000) return x+x;
  	if(n<0){
  		n = -n;
  		x = -x;
--- 47,53 ----
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
      /* if J(n,NaN) is NaN */
! 	if(UWORD_IS_NAN(ix)) return x+x;
  	if(n<0){
  		n = -n;
  		x = -x;
*************** static float zero  =  0.0000000000e+00;
*** 57,63 ****
  	if(n==1) return(__ieee754_j1f(x));
  	sgn = (n&1)&(hx>>31);	/* even n -- 0, odd n -- sign(x) */
  	x = fabsf(x);
! 	if(ix==0||ix>=0x7f800000) 	/* if x is 0 or inf */
  	    b = zero;
  	else if((float)n<=x) {
  		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
--- 57,63 ----
  	if(n==1) return(__ieee754_j1f(x));
  	sgn = (n&1)&(hx>>31);	/* even n -- 0, odd n -- sign(x) */
  	x = fabsf(x);
! 	if(UWORD_IS_ZERO(ix)||UWORD_IS_INFINITE(ix))
  	    b = zero;
  	else if((float)n<=x) {
  		/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
*************** static float zero  =  0.0000000000e+00;
*** 181,188 ****
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
      /* if Y(n,NaN) is NaN */
! 	if(ix>0x7f800000) return x+x;
! 	if(ix==0) return -one/zero;
  	if(hx<0) return zero/zero;
  	sign = 1;
  	if(n<0){
--- 181,188 ----
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
      /* if Y(n,NaN) is NaN */
! 	if(UWORD_IS_NAN(ix)) return x+x;
! 	if(UWORD_IS_ZERO(ix)) return -one/zero;
  	if(hx<0) return zero/zero;
  	sign = 1;
  	if(n<0){
*************** static float zero  =  0.0000000000e+00;
*** 191,197 ****
  	}
  	if(n==0) return(__ieee754_y0f(x));
  	if(n==1) return(sign*__ieee754_y1f(x));
! 	if(ix==0x7f800000) return zero;

  	a = __ieee754_y0f(x);
  	b = __ieee754_y1f(x);
--- 191,197 ----
  	}
  	if(n==0) return(__ieee754_y0f(x));
  	if(n==1) return(sign*__ieee754_y1f(x));
! 	if(UWORD_IS_INFINITE(ix)) return zero;

  	a = __ieee754_y0f(x);
  	b = __ieee754_y1f(x);
Index: ./libm/math/ef_log.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_log.c,v
retrieving revision 1.2
diff -c -p -d -r1.2 ef_log.c
*** ./libm/math/ef_log.c	2000/04/17 17:10:18	1.2
--- ./libm/math/ef_log.c	2001/03/30 16:08:42
*************** static float zero   =  0.0;
*** 50,63 ****
  	GET_FLOAT_WORD(ix,x);

  	k=0;
! 	if (ix < 0x00800000) {			/* x < 2**-126  */
! 	    if ((ix&0x7fffffff)==0)
! 		return -two25/zero;		/* log(+-0)=-inf */
! 	    if (ix<0) return (x-x)/zero;	/* log(-#) = NaN */
  	    k -= 25; x *= two25; /* subnormal number, scale up x */
  	    GET_FLOAT_WORD(ix,x);
  	}
- 	if (ix >= 0x7f800000) return x+x;
  	k += (ix>>23)-127;
  	ix &= 0x007fffff;
  	i = (ix+(0x95f64<<3))&0x800000;
--- 50,63 ----
  	GET_FLOAT_WORD(ix,x);

  	k=0;
! 	if (UWORD_IS_ZERO(ix&0x7fffffff))
! 	    return -two25/zero;		/* log(+-0)=-inf */
!         if (ix<0) return (x-x)/zero;	/* log(-#) = NaN */
! 	if (!UWORD_IS_FINITE(ix)) return x+x;
! 	if (UWORD_IS_SUBNORMAL(ix)) {
  	    k -= 25; x *= two25; /* subnormal number, scale up x */
  	    GET_FLOAT_WORD(ix,x);
  	}
  	k += (ix>>23)-127;
  	ix &= 0x007fffff;
  	i = (ix+(0x95f64<<3))&0x800000;
Index: ./libm/math/ef_log10.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_log10.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_log10.c
*** ./libm/math/ef_log10.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_log10.c	2001/03/30 16:08:42
*************** static float zero   =  0.0;
*** 44,57 ****
  	GET_FLOAT_WORD(hx,x);

          k=0;
!         if (hx < 0x00800000) {                  /* x < 2**-126  */
!             if ((hx&0x7fffffff)==0)
!                 return -two25/zero;             /* log(+-0)=-inf */
!             if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
              k -= 25; x *= two25; /* subnormal number, scale up x */
  	    GET_FLOAT_WORD(hx,x);
          }
- 	if (hx >= 0x7f800000) return x+x;
  	k += (hx>>23)-127;
  	i  = ((__uint32_t)k&0x80000000)>>31;
          hx = (hx&0x007fffff)|((0x7f-i)<<23);
--- 44,57 ----
  	GET_FLOAT_WORD(hx,x);

          k=0;
!         if (UWORD_IS_ZERO(hx&0x7fffffff))
!             return -two25/zero;             /* log(+-0)=-inf */
!         if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
! 	if (!UWORD_IS_FINITE(hx)) return x+x;
!         if (UWORD_IS_SUBNORMAL(hx)) {
              k -= 25; x *= two25; /* subnormal number, scale up x */
  	    GET_FLOAT_WORD(hx,x);
          }
  	k += (hx>>23)-127;
  	i  = ((__uint32_t)k&0x80000000)>>31;
          hx = (hx&0x007fffff)|((0x7f-i)<<23);
Index: ./libm/math/ef_pow.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_pow.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_pow.c
*** ./libm/math/ef_pow.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_pow.c	2001/03/30 16:08:43
*************** ivln2_l  =  7.0526075433e-06; /* 0x36eca
*** 73,83 ****
  	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;

      /* y==zero: x**0 = 1 */
! 	if(iy==0) return one;

      /* +-NaN return x+y */
! 	if(ix > 0x7f800000 ||
! 	   iy > 0x7f800000)
  		return x+y;

      /* determine if y is an odd int when x < 0
--- 73,83 ----
  	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;

      /* y==zero: x**0 = 1 */
! 	if(UWORD_IS_ZERO(iy)) return one;

      /* +-NaN return x+y */
! 	if(UWORD_IS_NAN(ix) ||
! 	   UWORD_IS_NAN(iy))
  		return x+y;

      /* determine if y is an odd int when x < 0
*************** ivln2_l  =  7.0526075433e-06; /* 0x36eca
*** 96,102 ****
  	}

      /* special value of y */
! 	if (iy==0x7f800000) {	/* y is +-inf */
  	    if (ix==0x3f800000)
  	        return  y - y;	/* inf**+-1 is NaN */
  	    else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
--- 96,102 ----
  	}

      /* special value of y */
! 	if (UWORD_IS_INFINITE(iy)) {	/* y is +-inf */
  	    if (ix==0x3f800000)
  	        return  y - y;	/* inf**+-1 is NaN */
  	    else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */
*************** ivln2_l  =  7.0526075433e-06; /* 0x36eca
*** 115,121 ****

  	ax   = fabsf(x);
      /* special value of x */
! 	if(ix==0x7f800000||ix==0||ix==0x3f800000){
  	    z = ax;			/*x is +-0,+-inf,+-1*/
  	    if(hy<0) z = one/z;	/* z = (1/|x|) */
  	    if(hx<0) {
--- 115,121 ----

  	ax   = fabsf(x);
      /* special value of x */
! 	if(UWORD_IS_INFINITE(ix)||UWORD_IS_ZERO(ix)||ix==0x3f800000){
  	    z = ax;			/*x is +-0,+-inf,+-1*/
  	    if(hy<0) z = one/z;	/* z = (1/|x|) */
  	    if(hx<0) {
*************** ivln2_l  =  7.0526075433e-06; /* 0x36eca
*** 149,155 ****
  	    float s2,s_h,s_l,t_h,t_l;
  	    n = 0;
  	/* take care subnormal number */
! 	    if(ix<0x00800000)
  		{ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
  	    n  += ((ix)>>23)-0x7f;
  	    j  = ix&0x007fffff;
--- 149,155 ----
  	    float s2,s_h,s_l,t_h,t_l;
  	    n = 0;
  	/* take care subnormal number */
! 	    if(UWORD_IS_SUBNORMAL(ix))
  		{ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
  	    n  += ((ix)>>23)-0x7f;
  	    j  = ix&0x007fffff;
*************** ivln2_l  =  7.0526075433e-06; /* 0x36eca
*** 209,228 ****
  	p_h = y1*t1;
  	z = p_l+p_h;
  	GET_FLOAT_WORD(j,z);
! 	if (j>0x43000000)				/* if z > 128 */
! 	    return s*huge*huge;				/* overflow */
! 	else if (j==0x43000000) {			/* if z == 128 */
! 	    if(p_l+ovt>z-p_h) return s*huge*huge;	/* overflow */
! 	}
! 	else if ((j&0x7fffffff)>0x43160000)		/* z <= -150 */
! 	    return s*tiny*tiny;				/* underflow */
! 	else if (j==0xc3160000){			/* z == -150 */
! 	    if(p_l<=z-p_h) return s*tiny*tiny;		/* underflow */
  	}
      /*
       * compute 2**(p_h+p_l)
       */
- 	i = j&0x7fffffff;
  	k = (i>>23)-0x7f;
  	n = 0;
  	if(i>0x3f000000) {		/* if |z| > 0.5, set n = [z+0.5] */
--- 209,229 ----
  	p_h = y1*t1;
  	z = p_l+p_h;
  	GET_FLOAT_WORD(j,z);
! 	i = j&0x7fffffff;
! 	if (j>0) {
! 	    if (i>UWORD_EXP_MAX)
! 	        return s*huge*huge;			/* overflow */
! 	    else if (i==UWORD_EXP_MAX)
! 	        if(p_l+ovt>z-p_h) return s*huge*huge;	/* overflow */
!         } else {
! 	    if (i>UWORD_EXP_MIN)
! 	        return s*tiny*tiny;			/* underflow */
! 	    else if (i==UWORD_EXP_MIN)
! 	        if(p_l<=z-p_h) return s*tiny*tiny;	/* underflow */
  	}
      /*
       * compute 2**(p_h+p_l)
       */
  	k = (i>>23)-0x7f;
  	n = 0;
  	if(i>0x3f000000) {		/* if |z| > 0.5, set n = [z+0.5] */
Index: ./libm/math/ef_rem_pio2.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_rem_pio2.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_rem_pio2.c
*** ./libm/math/ef_rem_pio2.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_rem_pio2.c	2001/03/30 16:08:43
*************** pio2_3t =  6.1232342629e-17; /* 0x248d31
*** 174,180 ****
      /*
       * all other (large) arguments
       */
! 	if(ix>=0x7f800000) {		/* x is inf or NaN */
  	    y[0]=y[1]=x-x; return 0;
  	}
      /* set z = scalbn(|x|,ilogb(x)-7) */
--- 174,180 ----
      /*
       * all other (large) arguments
       */
! 	if(!UWORD_IS_FINITE(ix)) {
  	    y[0]=y[1]=x-x; return 0;
  	}
      /* set z = scalbn(|x|,ilogb(x)-7) */
Index: ./libm/math/ef_remainder.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_remainder.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_remainder.c
*** ./libm/math/ef_remainder.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_remainder.c	2001/03/30 16:08:43
*************** static float zero = 0.0;
*** 40,52 ****
  	hx &= 0x7fffffff;

      /* purge off exception values */
! 	if(hp==0) return (x*p)/(x*p);	 	/* p = 0 */
! 	if((hx>=0x7f800000)||			/* x not finite */
! 	  ((hp>0x7f800000)))			/* p is NaN */
  	    return (x*p)/(x*p);


! 	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
  	if ((hx-hp)==0) return zero*x;
  	x  = fabsf(x);
  	p  = fabsf(p);
--- 40,52 ----
  	hx &= 0x7fffffff;

      /* purge off exception values */
! 	if(UWORD_IS_ZERO(hp)||
! 	   !UWORD_IS_FINITE(hx)||
! 	   UWORD_IS_NAN(hp))
  	    return (x*p)/(x*p);


! 	if (hp<=UWORD_HALF_MAX) x = __ieee754_fmodf(x,p+p); /* now x < 2p */
  	if ((hx-hp)==0) return zero*x;
  	x  = fabsf(x);
  	p  = fabsf(p);
Index: ./libm/math/ef_sinh.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_sinh.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_sinh.c
*** ./libm/math/ef_sinh.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_sinh.c	2001/03/30 16:08:43
*************** static float one = 1.0, shuge = 1.0e37;
*** 35,41 ****
  	ix = jx&0x7fffffff;

      /* x is INF or NaN */
! 	if(ix>=0x7f800000) return x+x;

  	h = 0.5;
  	if (jx<0) h = -h;
--- 35,41 ----
  	ix = jx&0x7fffffff;

      /* x is INF or NaN */
! 	if(!UWORD_IS_FINITE(ix)) return x+x;

  	h = 0.5;
  	if (jx<0) h = -h;
*************** static float one = 1.0, shuge = 1.0e37;
*** 49,58 ****
  	}

      /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
! 	if (ix < 0x42b17180)  return h*__ieee754_expf(fabsf(x));

      /* |x| in [log(maxdouble), overflowthresold] */
! 	if (ix<=0x42b2d4fc) {
  	    w = __ieee754_expf((float)0.5*fabsf(x));
  	    t = h*w;
  	    return t*w;
--- 49,58 ----
  	}

      /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
! 	if (ix<=UWORD_LOG_FLT_MAX)  return h*__ieee754_expf(fabsf(x));

      /* |x| in [log(maxdouble), overflowthresold] */
! 	if (ix<=UWORD_LOG_2FLT_MAX) {
  	    w = __ieee754_expf((float)0.5*fabsf(x));
  	    t = h*w;
  	    return t*w;
Index: ./libm/math/ef_sqrt.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/ef_sqrt.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 ef_sqrt.c
*** ./libm/math/ef_sqrt.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/ef_sqrt.c	2001/03/30 16:08:43
*************** static	float	one	= 1.0, tiny=1.0e-30;
*** 30,54 ****
  {
  	float z;
  	__int32_t 	sign = (__int32_t)0x80000000;
! 	__uint32_t r;
  	__int32_t ix,s,q,m,t,i;

  	GET_FLOAT_WORD(ix,x);

      /* take care of Inf and NaN */
! 	if((ix&0x7f800000L)==0x7f800000L) {
  	    return x*x+x;		/* sqrt(NaN)=NaN, sqrt(+inf)=+inf
  					   sqrt(-inf)=sNaN */
! 	}
!     /* take care of zero */
! 	if(ix<=0) {
! 	    if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */
! 	    else if(ix<0)
! 		return (x-x)/(x-x);		/* sqrt(-ve) = sNaN */
! 	}
      /* normalize x */
  	m = (ix>>23);
! 	if(m==0) {				/* subnormal x */
  	    for(i=0;(ix&0x00800000L)==0;i++) ix<<=1;
  	    m -= i-1;
  	}
--- 30,52 ----
  {
  	float z;
  	__int32_t 	sign = (__int32_t)0x80000000;
! 	__uint32_t r,hx;
  	__int32_t ix,s,q,m,t,i;

  	GET_FLOAT_WORD(ix,x);
+ 	hx = ix&0x7fffffff;

      /* take care of Inf and NaN */
! 	if(!UWORD_IS_FINITE(hx))
  	    return x*x+x;		/* sqrt(NaN)=NaN, sqrt(+inf)=+inf
  					   sqrt(-inf)=sNaN */
!     /* take care of zero and -ves */
! 	if(UWORD_IS_ZERO(hx)) return x;/* sqrt(+-0) = +-0 */
! 	if(ix<0) return (x-x)/(x-x);		/* sqrt(-ve) = sNaN */
!
      /* normalize x */
  	m = (ix>>23);
! 	if(UWORD_IS_SUBNORMAL(hx)) {		/* subnormal x */
  	    for(i=0;(ix&0x00800000L)==0;i++) ix<<=1;
  	    m -= i-1;
  	}
Index: ./libm/math/sf_asinh.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_asinh.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_asinh.c
*** ./libm/math/sf_asinh.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_asinh.c	2001/03/30 16:08:43
*************** huge=  1.0000000000e+30;
*** 35,41 ****
  	__int32_t hx,ix;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(ix>=0x7f800000) return x+x;	/* x is inf or NaN */
  	if(ix< 0x31800000) {	/* |x|<2**-28 */
  	    if(huge+x>one) return x;	/* return x inexact except 0 */
  	}
--- 35,41 ----
  	__int32_t hx,ix;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(!UWORD_IS_FINITE(ix)) return x+x;	/* x is inf or NaN */
  	if(ix< 0x31800000) {	/* |x|<2**-28 */
  	    if(huge+x>one) return x;	/* return x inexact except 0 */
  	}
Index: ./libm/math/sf_atan.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_atan.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_atan.c
*** ./libm/math/sf_atan.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_atan.c	2001/03/30 16:08:43
*************** huge   = 1.0e30;
*** 77,83 ****
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
  	if(ix>=0x50800000) {	/* if |x| >= 2^34 */
! 	    if(ix>0x7f800000)
  		return x+x;		/* NaN */
  	    if(hx>0) return  atanhi[3]+atanlo[3];
  	    else     return -atanhi[3]-atanlo[3];
--- 77,83 ----
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
  	if(ix>=0x50800000) {	/* if |x| >= 2^34 */
! 	    if(UWORD_IS_NAN(ix))
  		return x+x;		/* NaN */
  	    if(hx>0) return  atanhi[3]+atanlo[3];
  	    else     return -atanhi[3]-atanlo[3];
Index: ./libm/math/sf_ceil.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_ceil.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_ceil.c
*** ./libm/math/sf_ceil.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_ceil.c	2001/03/30 16:08:43
*************** static float huge = 1.0e30;
*** 29,42 ****
  #endif
  {
  	__int32_t i0,j0;
! 	__uint32_t i;
  	GET_FLOAT_WORD(i0,x);
! 	j0 = ((i0>>23)&0xff)-0x7f;
  	if(j0<23) {
  	    if(j0<0) { 	/* raise inexact if x != 0 */
  		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
  		    if(i0<0) {i0=0x80000000;}
! 		    else if(i0!=0) { i0=0x3f800000;}
  		}
  	    } else {
  		i = (0x007fffff)>>j0;
--- 29,43 ----
  #endif
  {
  	__int32_t i0,j0;
! 	__uint32_t i,ix;
  	GET_FLOAT_WORD(i0,x);
! 	ix = (i0&0x7fffffff);
! 	j0 = (ix>>23)-0x7f;
  	if(j0<23) {
  	    if(j0<0) { 	/* raise inexact if x != 0 */
  		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
  		    if(i0<0) {i0=0x80000000;}
! 		    else if(!UWORD_IS_ZERO(ix)) { i0=0x3f800000;}
  		}
  	    } else {
  		i = (0x007fffff)>>j0;
*************** static float huge = 1.0e30;
*** 47,53 ****
  		}
  	    }
  	} else {
! 	    if(j0==0x80) return x+x;	/* inf or NaN */
  	    else return x;		/* x is integral */
  	}
  	SET_FLOAT_WORD(x,i0);
--- 48,54 ----
  		}
  	    }
  	} else {
! 	    if(!UWORD_IS_FINITE(ix)) return x+x; /* inf or NaN */
  	    else return x;		/* x is integral */
  	}
  	SET_FLOAT_WORD(x,i0);
Index: ./libm/math/sf_cos.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_cos.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_cos.c
*** ./libm/math/sf_cos.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_cos.c	2001/03/30 16:08:43
*************** static float one=1.0;
*** 38,44 ****
  	if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);

      /* cos(Inf or NaN) is NaN */
! 	else if (ix>=0x7f800000) return x-x;

      /* argument reduction needed */
  	else {
--- 38,44 ----
  	if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);

      /* cos(Inf or NaN) is NaN */
! 	else if (!UWORD_IS_FINITE(ix)) return x-x;

      /* argument reduction needed */
  	else {
Index: ./libm/math/sf_erf.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_erf.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_erf.c
*** ./libm/math/sf_erf.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_erf.c	2001/03/30 16:08:44
*************** sb7  = -2.2440952301e+01; /* 0xc1b38712
*** 109,115 ****
  	float R,S,P,Q,s,y,z,r;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(ix>=0x7f800000) {		/* erf(nan)=nan */
  	    i = ((__uint32_t)hx>>31)<<1;
  	    return (float)(1-i)+one/x;	/* erf(+-inf)=+-1 */
  	}
--- 109,115 ----
  	float R,S,P,Q,s,y,z,r;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(!UWORD_IS_FINITE(ix)) {		/* erf(nan)=nan */
  	    i = ((__uint32_t)hx>>31)<<1;
  	    return (float)(1-i)+one/x;	/* erf(+-inf)=+-1 */
  	}
*************** sb7  = -2.2440952301e+01; /* 0xc1b38712
*** 166,172 ****
  	float R,S,P,Q,s,y,z,r;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(ix>=0x7f800000) {			/* erfc(nan)=nan */
  						/* erfc(+-inf)=0,2 */
  	    return (float)(((__uint32_t)hx>>31)<<1)+one/x;
  	}
--- 166,172 ----
  	float R,S,P,Q,s,y,z,r;
  	GET_FLOAT_WORD(hx,x);
  	ix = hx&0x7fffffff;
! 	if(!UWORD_IS_FINITE(ix)) {			/* erfc(nan)=nan */
  						/* erfc(+-inf)=0,2 */
  	    return (float)(((__uint32_t)hx>>31)<<1)+one/x;
  	}
Index: ./libm/math/sf_floor.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_floor.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_floor.c
*** ./libm/math/sf_floor.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_floor.c	2001/03/30 16:08:44
*************** static float huge = 1.0e30;
*** 38,51 ****
  #endif
  {
  	__int32_t i0,j0;
! 	__uint32_t i;
  	GET_FLOAT_WORD(i0,x);
! 	j0 = ((i0>>23)&0xff)-0x7f;
  	if(j0<23) {
  	    if(j0<0) { 	/* raise inexact if x != 0 */
  		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
  		    if(i0>=0) {i0=0;}
! 		    else if((i0&0x7fffffff)!=0)
  			{ i0=0xbf800000;}
  		}
  	    } else {
--- 38,52 ----
  #endif
  {
  	__int32_t i0,j0;
! 	__uint32_t i,ix;
  	GET_FLOAT_WORD(i0,x);
! 	ix = (i0&0x7fffffff);
! 	j0 = (ix>>23)-0x7f;
  	if(j0<23) {
  	    if(j0<0) { 	/* raise inexact if x != 0 */
  		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
  		    if(i0>=0) {i0=0;}
! 		    else if(!UWORD_IS_ZERO(ix))
  			{ i0=0xbf800000;}
  		}
  	    } else {
*************** static float huge = 1.0e30;
*** 57,63 ****
  		}
  	    }
  	} else {
! 	    if(j0==0x80) return x+x;	/* inf or NaN */
  	    else return x;		/* x is integral */
  	}
  	SET_FLOAT_WORD(x,i0);
--- 58,64 ----
  		}
  	    }
  	} else {
! 	    if(!UWORD_IS_FINITE(ix)) return x+x;	/* inf or NaN */
  	    else return x;		/* x is integral */
  	}
  	SET_FLOAT_WORD(x,i0);
Index: ./libm/math/sf_frexp.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_frexp.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_frexp.c
*** ./libm/math/sf_frexp.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_frexp.c	2001/03/30 16:08:44
*************** two25 =  3.3554432000e+07; /* 0x4c000000
*** 33,40 ****
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
  	*eptr = 0;
! 	if(ix>=0x7f800000||(ix==0)) return x;	/* 0,inf,nan */
! 	if (ix<0x00800000) {		/* subnormal */
  	    x *= two25;
  	    GET_FLOAT_WORD(hx,x);
  	    ix = hx&0x7fffffff;
--- 33,40 ----
  	GET_FLOAT_WORD(hx,x);
  	ix = 0x7fffffff&hx;
  	*eptr = 0;
! 	if(!UWORD_IS_FINITE(ix)||UWORD_IS_ZERO(ix)) return x;	/* 0,inf,nan */
! 	if (UWORD_IS_SUBNORMAL(ix)) {		/* subnormal */
  	    x *= two25;
  	    GET_FLOAT_WORD(hx,x);
  	    ix = hx&0x7fffffff;
Index: ./libm/math/sf_isinf.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_isinf.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_isinf.c
*** ./libm/math/sf_isinf.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_isinf.c	2001/03/30 16:08:44
***************
*** 1,6 ****
  /*
!  * isinff(x) returns 1 if x is infinity, else 0;
!  * no branching!
   * Added by Cygnus Support.
   */

--- 1,5 ----
  /*
!  * isinff(x) returns 1 if x is +-infinity, else 0;
   * Added by Cygnus Support.
   */

***************
*** 16,23 ****
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;
! 	ix = 0x7f800000 - ix;
! 	return 1 - (int)((__uint32_t)(ix|(-ix))>>31);
  }

  #ifdef _DOUBLE_IS_32BITS
--- 15,21 ----
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;
! 	return UWORD_IS_INFINITE(ix);
  }

  #ifdef _DOUBLE_IS_32BITS
Index: ./libm/math/sf_isnan.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_isnan.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_isnan.c
*** ./libm/math/sf_isnan.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_isnan.c	2001/03/30 16:08:44
***************
*** 15,21 ****

  /*
   * isnanf(x) returns 1 is x is nan, else 0;
-  * no branching!
   */

  #include "fdlibm.h"
--- 15,20 ----
***************
*** 30,37 ****
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;
! 	ix = 0x7f800000 - ix;
! 	return (int)(((__uint32_t)(ix))>>31);
  }

  #ifdef _DOUBLE_IS_32BITS
--- 29,35 ----
  	__int32_t ix;
  	GET_FLOAT_WORD(ix,x);
  	ix &= 0x7fffffff;
! 	return UWORD_IS_NAN(ix);
  }

  #ifdef _DOUBLE_IS_32BITS
Index: ./libm/math/sf_sin.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_sin.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_sin.c
*** ./libm/math/sf_sin.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_sin.c	2001/03/30 16:08:44
***************
*** 32,38 ****
  	if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);

      /* sin(Inf or NaN) is NaN */
! 	else if (ix>=0x7f800000) return x-x;

      /* argument reduction needed */
  	else {
--- 32,38 ----
  	if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);

      /* sin(Inf or NaN) is NaN */
! 	else if (!UWORD_IS_FINITE(ix)) return x-x;

      /* argument reduction needed */
  	else {
Index: ./libm/math/sf_tan.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_tan.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_tan.c
*** ./libm/math/sf_tan.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_tan.c	2001/03/30 16:08:44
***************
*** 32,38 ****
  	if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);

      /* tan(Inf or NaN) is NaN */
! 	else if (ix>=0x7f800000) return x-x;		/* NaN */

      /* argument reduction needed */
  	else {
--- 32,38 ----
  	if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);

      /* tan(Inf or NaN) is NaN */
! 	else if (!UWORD_IS_FINITE(ix)) return x-x;		/* NaN */

      /* argument reduction needed */
  	else {
Index: ./libm/math/sf_tanh.c
===================================================================
RCS file: /cvs/src/src/newlib/libm/math/sf_tanh.c,v
retrieving revision 1.1.1.1
diff -c -p -d -r1.1.1.1 sf_tanh.c
*** ./libm/math/sf_tanh.c	2000/02/17 19:39:51	1.1.1.1
--- ./libm/math/sf_tanh.c	2001/03/30 16:08:44
*************** static float one=1.0, two=2.0, tiny = 1.
*** 35,41 ****
  	ix = jx&0x7fffffff;

      /* x is INF or NaN */
! 	if(ix>=0x7f800000) {
  	    if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
  	    else       return one/x-one;    /* tanh(NaN) = NaN */
  	}
--- 35,41 ----
  	ix = jx&0x7fffffff;

      /* x is INF or NaN */
! 	if(!UWORD_IS_FINITE(ix)) {
  	    if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
  	    else       return one/x-one;    /* tanh(NaN) = NaN */
  	}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]