Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2001-04-04 17:33:01 +0400
committerRichard Sandiford <rdsandiford@googlemail.com>2001-04-04 17:33:01 +0400
commit16740220a22d09a1c63714d93f1efc5fbe3927f3 (patch)
tree7b24242b9b20a0ee328c94acd2c95e1a8778c944
parent51fc3813e9a9ef8079b2fbde1b12647dd3f4ac93 (diff)
* libc/include/machine/ieeefp.h: Comment about new configuration
macros _FLT_LARGEST_EXPONENT_IS_NORMAL and _FLT_NO_DENORMALS. * libm/common/fdlib.h: Define new macros for testing floats. * libm/common/sf_*: Use them. * libm/math/ef_*: Likewise. * libm/math/sf_*: Likewise.
-rw-r--r--newlib/ChangeLog9
-rw-r--r--newlib/libc/include/machine/ieeefp.h18
-rw-r--r--newlib/libm/common/fdlibm.h106
-rw-r--r--newlib/libm/common/sf_cbrt.c9
-rw-r--r--newlib/libm/common/sf_expm1.c14
-rw-r--r--newlib/libm/common/sf_finite.c3
-rw-r--r--newlib/libm/common/sf_ilogb.c13
-rw-r--r--newlib/libm/common/sf_log1p.c4
-rw-r--r--newlib/libm/common/sf_logb.c4
-rw-r--r--newlib/libm/common/sf_nan.c1
-rw-r--r--newlib/libm/common/sf_nextafter.c14
-rw-r--r--newlib/libm/common/sf_rint.c15
-rw-r--r--newlib/libm/common/sf_scalbn.c22
-rw-r--r--newlib/libm/math/ef_acosh.c2
-rw-r--r--newlib/libm/math/ef_atan2.c14
-rw-r--r--newlib/libm/math/ef_cosh.c7
-rw-r--r--newlib/libm/math/ef_exp.c28
-rw-r--r--newlib/libm/math/ef_fmod.c13
-rw-r--r--newlib/libm/math/ef_hypot.c11
-rw-r--r--newlib/libm/math/ef_j0.c10
-rw-r--r--newlib/libm/math/ef_j1.c10
-rw-r--r--newlib/libm/math/ef_jn.c10
-rw-r--r--newlib/libm/math/ef_log.c10
-rw-r--r--newlib/libm/math/ef_log10.c10
-rw-r--r--newlib/libm/math/ef_pow.c33
-rw-r--r--newlib/libm/math/ef_rem_pio2.c2
-rw-r--r--newlib/libm/math/ef_remainder.c8
-rw-r--r--newlib/libm/math/ef_sinh.c6
-rw-r--r--newlib/libm/math/ef_sqrt.c18
-rw-r--r--newlib/libm/math/sf_asinh.c2
-rw-r--r--newlib/libm/math/sf_atan.c2
-rw-r--r--newlib/libm/math/sf_ceil.c9
-rw-r--r--newlib/libm/math/sf_cos.c2
-rw-r--r--newlib/libm/math/sf_erf.c4
-rw-r--r--newlib/libm/math/sf_floor.c9
-rw-r--r--newlib/libm/math/sf_frexp.c4
-rw-r--r--newlib/libm/math/sf_isinf.c6
-rw-r--r--newlib/libm/math/sf_isnan.c4
-rw-r--r--newlib/libm/math/sf_sin.c2
-rw-r--r--newlib/libm/math/sf_tan.c2
-rw-r--r--newlib/libm/math/sf_tanh.c2
41 files changed, 306 insertions, 166 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 77426d3cb..46746a42f 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,12 @@
+2001-04-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * libc/include/machine/ieeefp.h: Comment about new configuration
+ macros _FLT_LARGEST_EXPONENT_IS_NORMAL and _FLT_NO_DENORMALS.
+ * libm/common/fdlib.h: Define new macros for testing floats.
+ * libm/common/sf_*: Use them.
+ * libm/math/ef_*: Likewise.
+ * libm/math/sf_*: Likewise.
+
2001-03-29 Jeff Johnston <jjohnstn@redhat.com>
* libc/sys/arm/setjmp.S: Added .code 16 specifier for thumb-mode
diff --git a/newlib/libc/include/machine/ieeefp.h b/newlib/libc/include/machine/ieeefp.h
index 570db14ef..b96f91274 100644
--- a/newlib/libc/include/machine/ieeefp.h
+++ b/newlib/libc/include/machine/ieeefp.h
@@ -1,6 +1,24 @@
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
+/* This file can define macros to choose variations of the IEEE float
+ format:
+
+ _FLT_LARGEST_EXPONENT_IS_NORMAL
+
+ Defined if the float format uses the largest exponent for finite
+ numbers rather than NaN and infinity representations. Such a
+ format cannot represent NaNs or infinities at all, but it's FLT_MAX
+ is twice the IEEE value.
+
+ _FLT_NO_DENORMALS
+
+ Defined if the float format does not support IEEE denormals. Every
+ float with a zero exponent is taken to be a zero representation.
+
+ ??? At the moment, there are no equivalent macros for doubles and
+ the macros are not fully supported by --enable-newlib-hw-fp. */
+
#if defined(__arm__) || defined(__thumb__)
/* ARM always has big-endian words. Within those words the byte ordering
appears to be big or little endian. Newlib doesn't seem to care about
diff --git a/newlib/libm/common/fdlibm.h b/newlib/libm/common/fdlibm.h
index 752d24246..5ca1a917b 100644
--- a/newlib/libm/common/fdlibm.h
+++ b/newlib/libm/common/fdlibm.h
@@ -18,14 +18,116 @@
/* 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:
+
+ FLT_UWORD_IS_FINITE(X)
+ True if a positive float with bitmask X is finite.
+
+ FLT_UWORD_IS_NAN(X)
+ True if a positive float with bitmask X is not a number.
+
+ FLT_UWORD_IS_INFINITE(X)
+ True if a positive float with bitmask X is +infinity.
+
+ FLT_UWORD_MAX
+ The bitmask of FLT_MAX.
+
+ FLT_UWORD_HALF_MAX
+ The bitmask of FLT_MAX/2.
+
+ FLT_UWORD_EXP_MAX
+ The bitmask of the largest finite exponent (129 if the largest
+ exponent is used for finite numbers, 128 otherwise).
+
+ FLT_UWORD_LOG_MAX
+ The bitmask of log(FLT_MAX), rounded down. This value is the largest
+ input that can be passed to exp() without producing overflow.
+
+ FLT_UWORD_LOG_2MAX
+ The bitmask of log(2*FLT_MAX), rounded down. This value is the
+ largest input than can be passed to cosh() without producing
+ overflow.
+
+ FLT_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 _FLT_LARGEST_EXPONENT_IS_NORMAL
+#define FLT_UWORD_IS_FINITE(x) 1
+#define FLT_UWORD_IS_NAN(x) 0
+#define FLT_UWORD_IS_INFINITE(x) 0
+#define FLT_UWORD_MAX 0x7fffffff
+#define FLT_UWORD_EXP_MAX 0x43010000
+#define FLT_UWORD_LOG_MAX 0x42b2d4fc
+#define FLT_UWORD_LOG_2MAX 0x42b437e0
+#define HUGE ((float)0X1.FFFFFEP128)
+#else
+#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L)
+#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L)
+#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L)
+#define FLT_UWORD_MAX 0x7f7fffff
+#define FLT_UWORD_EXP_MAX 0x43000000
+#define FLT_UWORD_LOG_MAX 0x42b17217
+#define FLT_UWORD_LOG_2MAX 0x42b2d4fc
+#define HUGE ((float)3.40282346638528860e+38)
+#endif
+#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1<<23))
+#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23)
+
+/* Many routines check for zero and subnormal numbers. Such things depend
+ on whether the target supports denormals or not:
+
+ FLT_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.
+
+ FLT_UWORD_IS_SUBNORMAL(X)
+ True if a non-zero positive float with bitmask X is subnormal.
+ (Routines should check for zeros first.)
+
+ FLT_UWORD_MIN
+ The bitmask of the smallest float above +0. Call this number
+ REAL_FLT_MIN...
+
+ FLT_UWORD_EXP_MIN
+ The bitmask of the float representation of REAL_FLT_MIN's exponent.
+
+ FLT_UWORD_LOG_MIN
+ The bitmask of |log(REAL_FLT_MIN)|, rounding down.
+
+ FLT_SMALLEST_EXP
+ REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported,
+ -22 if they are).
+*/
+
+#ifdef _FLT_NO_DENORMALS
+#define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L)
+#define FLT_UWORD_IS_SUBNORMAL(x) 0
+#define FLT_UWORD_MIN 0x00800000
+#define FLT_UWORD_EXP_MIN 0x42fc0000
+#define FLT_UWORD_LOG_MIN 0x42aeac50
+#define FLT_SMALLEST_EXP 1
+#else
+#define FLT_UWORD_IS_ZERO(x) ((x)==0)
+#define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L)
+#define FLT_UWORD_MIN 0x00000001
+#define FLT_UWORD_EXP_MIN 0x43160000
+#define FLT_UWORD_LOG_MIN 0x42cff1b5
+#define FLT_SMALLEST_EXP -22
+#endif
+
#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>
* (one may replace the following line by "#include <values.h>")
diff --git a/newlib/libm/common/sf_cbrt.c b/newlib/libm/common/sf_cbrt.c
index c053d9548..fe632f0a8 100644
--- a/newlib/libm/common/sf_cbrt.c
+++ b/newlib/libm/common/sf_cbrt.c
@@ -53,13 +53,14 @@ G = 3.5714286566e-01; /* 5/14 = 0x3eb6db6e */
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 */
+ if(!FLT_UWORD_IS_FINITE(hx))
+ return(x+x); /* cbrt(NaN,INF) is itself */
+ if(FLT_UWORD_IS_ZERO(hx))
+ return(x); /* cbrt(0) is itself */
SET_FLOAT_WORD(x,hx); /* x <- |x| */
/* rough cbrt to 5 bits */
- if(hx<0x00800000) /* subnormal number */
+ if(FLT_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);
}
diff --git a/newlib/libm/common/sf_expm1.c b/newlib/libm/common/sf_expm1.c
index e9108b7b8..4ba3b815a 100644
--- a/newlib/libm/common/sf_expm1.c
+++ b/newlib/libm/common/sf_expm1.c
@@ -27,7 +27,6 @@ static float
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 */
@@ -56,13 +55,12 @@ Q5 = -2.0109921195e-07; /* 0xb457edbb */
/* 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(FLT_UWORD_IS_NAN(hx))
+ return x+x;
+ if(FLT_UWORD_IS_INFINITE(hx))
+ return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
+ if(xsb == 0 && hx > FLT_UWORD_LOG_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 */
diff --git a/newlib/libm/common/sf_finite.c b/newlib/libm/common/sf_finite.c
index 4c48f400f..cb7026fbd 100644
--- a/newlib/libm/common/sf_finite.c
+++ b/newlib/libm/common/sf_finite.c
@@ -29,7 +29,8 @@
{
__int32_t ix;
GET_FLOAT_WORD(ix,x);
- return (int)((__uint32_t)((ix&0x7fffffff)-0x7f800000)>>31);
+ ix &= 0x7fffffff;
+ return (FLT_UWORD_IS_FINITE(ix));
}
#ifdef _DOUBLE_IS_32BITS
diff --git a/newlib/libm/common/sf_ilogb.c b/newlib/libm/common/sf_ilogb.c
index ee65594b1..ec59406e1 100644
--- a/newlib/libm/common/sf_ilogb.c
+++ b/newlib/libm/common/sf_ilogb.c
@@ -27,15 +27,14 @@
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;
+ if(FLT_UWORD_IS_ZERO(hx))
+ return - INT_MAX; /* ilogb(0) = 0x80000001 */
+ if(FLT_UWORD_IS_SUBNORMAL(hx)) {
+ 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;
+ else if (!FLT_UWORD_IS_FINITE(hx)) return INT_MAX;
+ else return (hx>>23)-127;
}
#ifdef _DOUBLE_IS_32BITS
diff --git a/newlib/libm/common/sf_log1p.c b/newlib/libm/common/sf_log1p.c
index 5ae7fb936..e09170f3e 100644
--- a/newlib/libm/common/sf_log1p.c
+++ b/newlib/libm/common/sf_log1p.c
@@ -51,6 +51,7 @@ static float zero = 0.0;
ax = hx&0x7fffffff;
k = 1;
+ if (!FLT_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 */
@@ -65,8 +66,7 @@ static float zero = 0.0;
}
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;
diff --git a/newlib/libm/common/sf_logb.c b/newlib/libm/common/sf_logb.c
index 6e67637fe..f193f91f6 100644
--- a/newlib/libm/common/sf_logb.c
+++ b/newlib/libm/common/sf_logb.c
@@ -25,8 +25,8 @@
__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(FLT_UWORD_IS_ZERO(ix)) return (float)-1.0/fabsf(x);
+ if(!FLT_UWORD_IS_FINITE(ix)) return x*x;
if((ix>>=23)==0) /* IEEE 754 logb */
return -126.0;
else
diff --git a/newlib/libm/common/sf_nan.c b/newlib/libm/common/sf_nan.c
index cb3e1cd03..c8d7027f8 100644
--- a/newlib/libm/common/sf_nan.c
+++ b/newlib/libm/common/sf_nan.c
@@ -21,3 +21,4 @@
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+
diff --git a/newlib/libm/common/sf_nextafter.c b/newlib/libm/common/sf_nextafter.c
index cd938d339..cea4da58d 100644
--- a/newlib/libm/common/sf_nextafter.c
+++ b/newlib/libm/common/sf_nextafter.c
@@ -29,15 +29,15 @@
ix = hx&0x7fffffff; /* |x| */
iy = hy&0x7fffffff; /* |y| */
- if((ix>0x7f800000) || /* x is nan */
- (iy>0x7f800000)) /* y is nan */
- return x+y;
+ if(FLT_UWORD_IS_NAN(ix) ||
+ FLT_UWORD_IS_NAN(iy))
+ 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 */
+ if(FLT_UWORD_IS_ZERO(ix)) { /* x == 0 */
+ SET_FLOAT_WORD(x,(hy&0x80000000)|FLT_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,7 +52,7 @@
}
}
hy = hx&0x7f800000;
- if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy>FLT_UWORD_MAX) return x+x; /* overflow */
if(hy<0x00800000) { /* underflow */
y = x*x;
if(y!=x) { /* raise underflow flag */
diff --git a/newlib/libm/common/sf_rint.c b/newlib/libm/common/sf_rint.c
index d38080a5d..6459b7a4c 100644
--- a/newlib/libm/common/sf_rint.c
+++ b/newlib/libm/common/sf_rint.c
@@ -33,15 +33,17 @@ TWO23[2]={
#endif
{
__int32_t i0,j0,sx;
- __uint32_t i,i1;
+ __uint32_t i,i1,ix;
float t;
volatile float w;
GET_FLOAT_WORD(i0,x);
sx = (i0>>31)&1;
- j0 = ((i0>>23)&0xff)-0x7f;
+ ix = (i0&0x7fffffff);
+ j0 = (ix>>23)-0x7f;
if(j0<23) {
- if(j0<0) {
- if((i0&0x7fffffff)==0) return x;
+ if(FLT_UWORD_IS_ZERO(ix))
+ return x;
+ if(j0<0) {
i1 = (i0&0x07fffff);
i0 &= 0xfff00000;
i0 |= ((i1|-i1)>>9)&0x400000;
@@ -58,8 +60,9 @@ TWO23[2]={
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 */
+ if(!FLT_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;
diff --git a/newlib/libm/common/sf_scalbn.c b/newlib/libm/common/sf_scalbn.c
index fb67c7816..700060010 100644
--- a/newlib/libm/common/sf_scalbn.c
+++ b/newlib/libm/common/sf_scalbn.c
@@ -15,6 +15,7 @@
#include "fdlibm.h"
#include <limits.h>
+#include <float.h>
#if INT_MAX > 50000
#define OVERFLOW_INT 50000
@@ -40,25 +41,30 @@ tiny = 1.0e-30;
#endif
{
__int32_t k,ix;
+ __uint32_t hx;
+
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 */
+ hx = ix&0x7fffffff;
+ k = hx>>23; /* extract exponent */
+ if (FLT_UWORD_IS_ZERO(hx))
+ return x;
+ if (!FLT_UWORD_IS_FINITE(hx))
+ return x+x; /* NaN or Inf */
+ if (FLT_UWORD_IS_SUBNORMAL(hx)) {
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 > FLT_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 <= -25) {
+ if (k < FLT_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;
diff --git a/newlib/libm/math/ef_acosh.c b/newlib/libm/math/ef_acosh.c
index 37c788576..1119c2c86 100644
--- a/newlib/libm/math/ef_acosh.c
+++ b/newlib/libm/math/ef_acosh.c
@@ -37,7 +37,7 @@ ln2 = 6.9314718246e-01; /* 0x3f317218 */
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 */
+ if(!FLT_UWORD_IS_FINITE(hx)) { /* x is inf of NaN */
return x+x;
} else
return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */
diff --git a/newlib/libm/math/ef_atan2.c b/newlib/libm/math/ef_atan2.c
index 25e86b374..45b5acb0c 100644
--- a/newlib/libm/math/ef_atan2.c
+++ b/newlib/libm/math/ef_atan2.c
@@ -42,14 +42,14 @@ pi_lo = 1.5099578832e-07; /* 0x34222168 */
ix = hx&0x7fffffff;
GET_FLOAT_WORD(hy,y);
iy = hy&0x7fffffff;
- if((ix>0x7f800000)||
- (iy>0x7f800000)) /* x or y is NaN */
+ if(FLT_UWORD_IS_NAN(ix)||
+ FLT_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(iy==0) {
+ if(FLT_UWORD_IS_ZERO(iy)) {
switch(m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
@@ -58,11 +58,11 @@ pi_lo = 1.5099578832e-07; /* 0x34222168 */
}
}
/* when x = 0 */
- if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+ if(FLT_UWORD_IS_ZERO(ix)) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* when x is INF */
- if(ix==0x7f800000) {
- if(iy==0x7f800000) {
+ if(FLT_UWORD_IS_INFINITE(ix)) {
+ if(FLT_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) */
@@ -79,7 +79,7 @@ pi_lo = 1.5099578832e-07; /* 0x34222168 */
}
}
/* when y is INF */
- if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
+ if(FLT_UWORD_IS_INFINITE(iy)) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* compute y/x */
k = (iy-ix)>>23;
diff --git a/newlib/libm/math/ef_cosh.c b/newlib/libm/math/ef_cosh.c
index 68e59f886..bdce61a00 100644
--- a/newlib/libm/math/ef_cosh.c
+++ b/newlib/libm/math/ef_cosh.c
@@ -39,7 +39,7 @@ static float one = 1.0, half=0.5, huge = 1.0e30;
ix &= 0x7fffffff;
/* x is INF or NaN */
- if(ix>=0x7f800000) return x*x;
+ if(!FLT_UWORD_IS_FINITE(ix)) return x*x;
/* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
if(ix<0x3eb17218) {
@@ -56,10 +56,11 @@ static float one = 1.0, half=0.5, huge = 1.0e30;
}
/* |x| in [22, log(maxdouble)] return half*exp(|x|) */
- if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x));
+ if (ix <= FLT_UWORD_LOG_MAX)
+ return half*__ieee754_expf(fabsf(x));
/* |x| in [log(maxdouble), overflowthresold] */
- if (ix<=0x42b2d4fc) {
+ if (ix <= FLT_UWORD_LOG_2MAX) {
w = __ieee754_expf(half*fabsf(x));
t = half*w;
return t*w;
diff --git a/newlib/libm/math/ef_exp.c b/newlib/libm/math/ef_exp.c
index 04331a52a..19c570cfd 100644
--- a/newlib/libm/math/ef_exp.c
+++ b/newlib/libm/math/ef_exp.c
@@ -28,8 +28,6 @@ one = 1.0,
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 */
@@ -49,23 +47,23 @@ P5 = 4.1381369442e-08; /* 0x3331bb4c */
#endif
{
float y,hi,lo,c,t;
- __int32_t k,xsb;
+ __int32_t k,xsb,sx;
__uint32_t hx;
- GET_FLOAT_WORD(hx,x);
- xsb = (hx>>31)&1; /* sign bit of x */
- hx &= 0x7fffffff; /* high word of |x| */
+ 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(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 */
- }
-
+ if(FLT_UWORD_IS_NAN(hx))
+ return x+x; /* NaN */
+ if(FLT_UWORD_IS_INFINITE(hx))
+ return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
+ if(sx > FLT_UWORD_LOG_MAX)
+ return huge*huge; /* overflow */
+ if(sx < 0 && hx > FLT_UWORD_LOG_MIN)
+ return twom100*twom100; /* underflow */
+
/* argument reduction */
if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
diff --git a/newlib/libm/math/ef_fmod.c b/newlib/libm/math/ef_fmod.c
index d5d28e08e..53c1ba280 100644
--- a/newlib/libm/math/ef_fmod.c
+++ b/newlib/libm/math/ef_fmod.c
@@ -43,20 +43,23 @@ static float one = 1.0, Zero[] = {0.0, -0.0,};
hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
- if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */
- (hy>0x7f800000)) /* or y is NaN */
+ if(FLT_UWORD_IS_ZERO(hy)||
+ !FLT_UWORD_IS_FINITE(hx)||
+ FLT_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(hx<0x00800000) { /* subnormal x */
+ if(FLT_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(hy<0x00800000) { /* subnormal y */
+ if(FLT_UWORD_IS_SUBNORMAL(hy)) { /* subnormal y */
for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
} else iy = (hy>>23)-127;
@@ -99,6 +102,8 @@ static float one = 1.0, Zero[] = {0.0, -0.0,};
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);
diff --git a/newlib/libm/math/ef_hypot.c b/newlib/libm/math/ef_hypot.c
index a87fa489e..9f6d40c9c 100644
--- a/newlib/libm/math/ef_hypot.c
+++ b/newlib/libm/math/ef_hypot.c
@@ -35,10 +35,10 @@
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 */
+ if(!FLT_UWORD_IS_FINITE(ha)) { /* Inf or NaN */
w = a+b; /* for sNaN */
- if(ha == 0x7f800000L) w = a;
- if(hb == 0x7f800000L) w = b;
+ if(FLT_UWORD_IS_INFINITE(ha)) w = a;
+ if(FLT_UWORD_IS_INFINITE(hb)) w = b;
return w;
}
/* scale a and b by 2**-60 */
@@ -47,8 +47,9 @@
SET_FLOAT_WORD(b,hb);
}
if(hb < 0x26800000L) { /* b < 2**-50 */
- if(hb <= 0x007fffffL) { /* subnormal b or 0 */
- if(hb==0) return a;
+ if(FLT_UWORD_IS_ZERO(hb)) {
+ return a;
+ } else if(FLT_UWORD_IS_SUBNORMAL(hb)) {
SET_FLOAT_WORD(t1,0x3f000000L); /* t1=2^126 */
b *= t1;
a *= t1;
diff --git a/newlib/libm/math/ef_j0.c b/newlib/libm/math/ef_j0.c
index e7ee6e748..866cfcf96 100644
--- a/newlib/libm/math/ef_j0.c
+++ b/newlib/libm/math/ef_j0.c
@@ -58,14 +58,14 @@ static float zero = 0.0;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) return one/(x*x);
+ if(!FLT_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<0x7f000000) { /* make sure x+x not overflow */
+ if(ix<=FLT_UWORD_HALF_MAX) { /* make sure x+x not overflow */
z = -cosf(x+x);
if ((s*c)<zero) cc = z/ss;
else ss = z/cc;
@@ -128,8 +128,8 @@ v04 = 4.4111031494e-10; /* 0x2ff280c2 */
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(!FLT_UWORD_IS_FINITE(ix)) return one/(x+x*x);
+ if(FLT_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))
@@ -151,7 +151,7 @@ v04 = 4.4111031494e-10; /* 0x2ff280c2 */
* 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 */
+ if(ix<=FLT_UWORD_HALF_MAX) { /* make sure x+x not overflow */
z = -cosf(x+x);
if ((s*c)<zero) cc = z/ss;
else ss = z/cc;
diff --git a/newlib/libm/math/ef_j1.c b/newlib/libm/math/ef_j1.c
index e11cf1fba..01bd24cf1 100644
--- a/newlib/libm/math/ef_j1.c
+++ b/newlib/libm/math/ef_j1.c
@@ -59,14 +59,14 @@ static float zero = 0.0;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) return one/x;
+ if(!FLT_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<0x7f000000) { /* make sure y+y not overflow */
+ if(ix<=FLT_UWORD_HALF_MAX) { /* make sure y+y not overflow */
z = cosf(y+y);
if ((s*c)>zero) cc = z/ss;
else ss = z/cc;
@@ -129,15 +129,15 @@ static float V0[5] = {
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(!FLT_UWORD_IS_FINITE(ix)) return one/(x+x*x);
+ if(FLT_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<0x7f000000) { /* make sure x+x not overflow */
+ if(ix<=FLT_UWORD_HALF_MAX) { /* make sure x+x not overflow */
z = cosf(x+x);
if ((s*c)>zero) cc = z/ss;
else ss = z/cc;
diff --git a/newlib/libm/math/ef_jn.c b/newlib/libm/math/ef_jn.c
index 04a93b685..bedfb3ed5 100644
--- a/newlib/libm/math/ef_jn.c
+++ b/newlib/libm/math/ef_jn.c
@@ -47,7 +47,7 @@ static float zero = 0.0000000000e+00;
GET_FLOAT_WORD(hx,x);
ix = 0x7fffffff&hx;
/* if J(n,NaN) is NaN */
- if(ix>0x7f800000) return x+x;
+ if(FLT_UWORD_IS_NAN(ix)) return x+x;
if(n<0){
n = -n;
x = -x;
@@ -57,7 +57,7 @@ static float zero = 0.0000000000e+00;
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 */
+ if(FLT_UWORD_IS_ZERO(ix)||FLT_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) */
@@ -181,8 +181,8 @@ static float zero = 0.0000000000e+00;
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(FLT_UWORD_IS_NAN(ix)) return x+x;
+ if(FLT_UWORD_IS_ZERO(ix)) return -one/zero;
if(hx<0) return zero/zero;
sign = 1;
if(n<0){
@@ -191,7 +191,7 @@ static float zero = 0.0000000000e+00;
}
if(n==0) return(__ieee754_y0f(x));
if(n==1) return(sign*__ieee754_y1f(x));
- if(ix==0x7f800000) return zero;
+ if(FLT_UWORD_IS_INFINITE(ix)) return zero;
a = __ieee754_y0f(x);
b = __ieee754_y1f(x);
diff --git a/newlib/libm/math/ef_log.c b/newlib/libm/math/ef_log.c
index 87d6af2c5..619fe9090 100644
--- a/newlib/libm/math/ef_log.c
+++ b/newlib/libm/math/ef_log.c
@@ -50,14 +50,14 @@ static float zero = 0.0;
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 */
+ if (FLT_UWORD_IS_ZERO(ix&0x7fffffff))
+ return -two25/zero; /* log(+-0)=-inf */
+ if (ix<0) return (x-x)/zero; /* log(-#) = NaN */
+ if (!FLT_UWORD_IS_FINITE(ix)) return x+x;
+ if (FLT_UWORD_IS_SUBNORMAL(ix)) {
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;
diff --git a/newlib/libm/math/ef_log10.c b/newlib/libm/math/ef_log10.c
index 63fee9b9d..5ab23c43f 100644
--- a/newlib/libm/math/ef_log10.c
+++ b/newlib/libm/math/ef_log10.c
@@ -44,14 +44,14 @@ static float zero = 0.0;
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 */
+ if (FLT_UWORD_IS_ZERO(hx&0x7fffffff))
+ return -two25/zero; /* log(+-0)=-inf */
+ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
+ if (!FLT_UWORD_IS_FINITE(hx)) return x+x;
+ if (FLT_UWORD_IS_SUBNORMAL(hx)) {
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);
diff --git a/newlib/libm/math/ef_pow.c b/newlib/libm/math/ef_pow.c
index 40b679d6e..e50cc58b3 100644
--- a/newlib/libm/math/ef_pow.c
+++ b/newlib/libm/math/ef_pow.c
@@ -73,11 +73,11 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
ix = hx&0x7fffffff; iy = hy&0x7fffffff;
/* y==zero: x**0 = 1 */
- if(iy==0) return one;
+ if(FLT_UWORD_IS_ZERO(iy)) return one;
/* +-NaN return x+y */
- if(ix > 0x7f800000 ||
- iy > 0x7f800000)
+ if(FLT_UWORD_IS_NAN(ix) ||
+ FLT_UWORD_IS_NAN(iy))
return x+y;
/* determine if y is an odd int when x < 0
@@ -96,7 +96,7 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
}
/* special value of y */
- if (iy==0x7f800000) { /* y is +-inf */
+ if (FLT_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 */
@@ -115,7 +115,7 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
ax = fabsf(x);
/* special value of x */
- if(ix==0x7f800000||ix==0||ix==0x3f800000){
+ if(FLT_UWORD_IS_INFINITE(ix)||FLT_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) {
@@ -149,7 +149,7 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
float s2,s_h,s_l,t_h,t_l;
n = 0;
/* take care subnormal number */
- if(ix<0x00800000)
+ if(FLT_UWORD_IS_SUBNORMAL(ix))
{ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); }
n += ((ix)>>23)-0x7f;
j = ix&0x007fffff;
@@ -209,20 +209,21 @@ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
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 */
+ i = j&0x7fffffff;
+ if (j>0) {
+ if (i>FLT_UWORD_EXP_MAX)
+ return s*huge*huge; /* overflow */
+ else if (i==FLT_UWORD_EXP_MAX)
+ if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
+ } else {
+ if (i>FLT_UWORD_EXP_MIN)
+ return s*tiny*tiny; /* underflow */
+ else if (i==FLT_UWORD_EXP_MIN)
+ 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] */
diff --git a/newlib/libm/math/ef_rem_pio2.c b/newlib/libm/math/ef_rem_pio2.c
index e91aa47f3..f1191d09f 100644
--- a/newlib/libm/math/ef_rem_pio2.c
+++ b/newlib/libm/math/ef_rem_pio2.c
@@ -174,7 +174,7 @@ pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
/*
* all other (large) arguments
*/
- if(ix>=0x7f800000) { /* x is inf or NaN */
+ if(!FLT_UWORD_IS_FINITE(ix)) {
y[0]=y[1]=x-x; return 0;
}
/* set z = scalbn(|x|,ilogb(x)-7) */
diff --git a/newlib/libm/math/ef_remainder.c b/newlib/libm/math/ef_remainder.c
index 8ce7fac99..23d29d05a 100644
--- a/newlib/libm/math/ef_remainder.c
+++ b/newlib/libm/math/ef_remainder.c
@@ -40,13 +40,13 @@ static float zero = 0.0;
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 */
+ if(FLT_UWORD_IS_ZERO(hp)||
+ !FLT_UWORD_IS_FINITE(hx)||
+ FLT_UWORD_IS_NAN(hp))
return (x*p)/(x*p);
- if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */
+ if (hp<=FLT_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);
diff --git a/newlib/libm/math/ef_sinh.c b/newlib/libm/math/ef_sinh.c
index 375198344..a61b17294 100644
--- a/newlib/libm/math/ef_sinh.c
+++ b/newlib/libm/math/ef_sinh.c
@@ -35,7 +35,7 @@ static float one = 1.0, shuge = 1.0e37;
ix = jx&0x7fffffff;
/* x is INF or NaN */
- if(ix>=0x7f800000) return x+x;
+ if(!FLT_UWORD_IS_FINITE(ix)) return x+x;
h = 0.5;
if (jx<0) h = -h;
@@ -49,10 +49,10 @@ static float one = 1.0, shuge = 1.0e37;
}
/* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
- if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x));
+ if (ix<=FLT_UWORD_LOG_MAX) return h*__ieee754_expf(fabsf(x));
/* |x| in [log(maxdouble), overflowthresold] */
- if (ix<=0x42b2d4fc) {
+ if (ix<=FLT_UWORD_LOG_2MAX) {
w = __ieee754_expf((float)0.5*fabsf(x));
t = h*w;
return t*w;
diff --git a/newlib/libm/math/ef_sqrt.c b/newlib/libm/math/ef_sqrt.c
index aabbc51ce..17dab9311 100644
--- a/newlib/libm/math/ef_sqrt.c
+++ b/newlib/libm/math/ef_sqrt.c
@@ -30,25 +30,23 @@ static float one = 1.0, tiny=1.0e-30;
{
float z;
__int32_t sign = (__int32_t)0x80000000;
- __uint32_t r;
+ __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((ix&0x7f800000L)==0x7f800000L) {
+ if(!FLT_UWORD_IS_FINITE(hx))
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 */
- }
+ /* take care of zero and -ves */
+ if(FLT_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(m==0) { /* subnormal x */
+ if(FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal x */
for(i=0;(ix&0x00800000L)==0;i++) ix<<=1;
m -= i-1;
}
diff --git a/newlib/libm/math/sf_asinh.c b/newlib/libm/math/sf_asinh.c
index d5dfef811..4688ea8c1 100644
--- a/newlib/libm/math/sf_asinh.c
+++ b/newlib/libm/math/sf_asinh.c
@@ -35,7 +35,7 @@ huge= 1.0000000000e+30;
__int32_t hx,ix;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) return x+x; /* x is inf or NaN */
+ if(!FLT_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 */
}
diff --git a/newlib/libm/math/sf_atan.c b/newlib/libm/math/sf_atan.c
index 7ea664f23..6edf05fe5 100644
--- a/newlib/libm/math/sf_atan.c
+++ b/newlib/libm/math/sf_atan.c
@@ -77,7 +77,7 @@ huge = 1.0e30;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>=0x50800000) { /* if |x| >= 2^34 */
- if(ix>0x7f800000)
+ if(FLT_UWORD_IS_NAN(ix))
return x+x; /* NaN */
if(hx>0) return atanhi[3]+atanlo[3];
else return -atanhi[3]-atanlo[3];
diff --git a/newlib/libm/math/sf_ceil.c b/newlib/libm/math/sf_ceil.c
index 85f0e9714..8a8edac14 100644
--- a/newlib/libm/math/sf_ceil.c
+++ b/newlib/libm/math/sf_ceil.c
@@ -29,14 +29,15 @@ static float huge = 1.0e30;
#endif
{
__int32_t i0,j0;
- __uint32_t i;
+ __uint32_t i,ix;
GET_FLOAT_WORD(i0,x);
- j0 = ((i0>>23)&0xff)-0x7f;
+ 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(i0!=0) { i0=0x3f800000;}
+ else if(!FLT_UWORD_IS_ZERO(ix)) { i0=0x3f800000;}
}
} else {
i = (0x007fffff)>>j0;
@@ -47,7 +48,7 @@ static float huge = 1.0e30;
}
}
} else {
- if(j0==0x80) return x+x; /* inf or NaN */
+ if(!FLT_UWORD_IS_FINITE(ix)) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
diff --git a/newlib/libm/math/sf_cos.c b/newlib/libm/math/sf_cos.c
index 8f3a8af01..4c0a9a535 100644
--- a/newlib/libm/math/sf_cos.c
+++ b/newlib/libm/math/sf_cos.c
@@ -38,7 +38,7 @@ static float one=1.0;
if(ix <= 0x3f490fd8) return __kernel_cosf(x,z);
/* cos(Inf or NaN) is NaN */
- else if (ix>=0x7f800000) return x-x;
+ else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
/* argument reduction needed */
else {
diff --git a/newlib/libm/math/sf_erf.c b/newlib/libm/math/sf_erf.c
index 1a9fa8d01..0329c60fa 100644
--- a/newlib/libm/math/sf_erf.c
+++ b/newlib/libm/math/sf_erf.c
@@ -109,7 +109,7 @@ sb7 = -2.2440952301e+01; /* 0xc1b38712 */
float R,S,P,Q,s,y,z,r;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) { /* erf(nan)=nan */
+ if(!FLT_UWORD_IS_FINITE(ix)) { /* erf(nan)=nan */
i = ((__uint32_t)hx>>31)<<1;
return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */
}
@@ -166,7 +166,7 @@ sb7 = -2.2440952301e+01; /* 0xc1b38712 */
float R,S,P,Q,s,y,z,r;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
- if(ix>=0x7f800000) { /* erfc(nan)=nan */
+ if(!FLT_UWORD_IS_FINITE(ix)) { /* erfc(nan)=nan */
/* erfc(+-inf)=0,2 */
return (float)(((__uint32_t)hx>>31)<<1)+one/x;
}
diff --git a/newlib/libm/math/sf_floor.c b/newlib/libm/math/sf_floor.c
index 787f2fdf0..9264d81e9 100644
--- a/newlib/libm/math/sf_floor.c
+++ b/newlib/libm/math/sf_floor.c
@@ -38,14 +38,15 @@ static float huge = 1.0e30;
#endif
{
__int32_t i0,j0;
- __uint32_t i;
+ __uint32_t i,ix;
GET_FLOAT_WORD(i0,x);
- j0 = ((i0>>23)&0xff)-0x7f;
+ 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((i0&0x7fffffff)!=0)
+ else if(!FLT_UWORD_IS_ZERO(ix))
{ i0=0xbf800000;}
}
} else {
@@ -57,7 +58,7 @@ static float huge = 1.0e30;
}
}
} else {
- if(j0==0x80) return x+x; /* inf or NaN */
+ if(!FLT_UWORD_IS_FINITE(ix)) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
diff --git a/newlib/libm/math/sf_frexp.c b/newlib/libm/math/sf_frexp.c
index 271fb9dca..8dd8a9767 100644
--- a/newlib/libm/math/sf_frexp.c
+++ b/newlib/libm/math/sf_frexp.c
@@ -33,8 +33,8 @@ two25 = 3.3554432000e+07; /* 0x4c000000 */
GET_FLOAT_WORD(hx,x);
ix = 0x7fffffff&hx;
*eptr = 0;
- if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */
- if (ix<0x00800000) { /* subnormal */
+ if(!FLT_UWORD_IS_FINITE(ix)||FLT_UWORD_IS_ZERO(ix)) return x; /* 0,inf,nan */
+ if (FLT_UWORD_IS_SUBNORMAL(ix)) { /* subnormal */
x *= two25;
GET_FLOAT_WORD(hx,x);
ix = hx&0x7fffffff;
diff --git a/newlib/libm/math/sf_isinf.c b/newlib/libm/math/sf_isinf.c
index 1af4aab2a..43a8abdf2 100644
--- a/newlib/libm/math/sf_isinf.c
+++ b/newlib/libm/math/sf_isinf.c
@@ -1,6 +1,5 @@
/*
- * isinff(x) returns 1 if x is infinity, else 0;
- * no branching!
+ * isinff(x) returns 1 if x is +-infinity, else 0;
* Added by Cygnus Support.
*/
@@ -16,8 +15,7 @@
__int32_t ix;
GET_FLOAT_WORD(ix,x);
ix &= 0x7fffffff;
- ix = 0x7f800000 - ix;
- return 1 - (int)((__uint32_t)(ix|(-ix))>>31);
+ return FLT_UWORD_IS_INFINITE(ix);
}
#ifdef _DOUBLE_IS_32BITS
diff --git a/newlib/libm/math/sf_isnan.c b/newlib/libm/math/sf_isnan.c
index 8fdb6adf2..0b4be3e9c 100644
--- a/newlib/libm/math/sf_isnan.c
+++ b/newlib/libm/math/sf_isnan.c
@@ -15,7 +15,6 @@
/*
* isnanf(x) returns 1 is x is nan, else 0;
- * no branching!
*/
#include "fdlibm.h"
@@ -30,8 +29,7 @@
__int32_t ix;
GET_FLOAT_WORD(ix,x);
ix &= 0x7fffffff;
- ix = 0x7f800000 - ix;
- return (int)(((__uint32_t)(ix))>>31);
+ return FLT_UWORD_IS_NAN(ix);
}
#ifdef _DOUBLE_IS_32BITS
diff --git a/newlib/libm/math/sf_sin.c b/newlib/libm/math/sf_sin.c
index 315d4b4ba..da81845d9 100644
--- a/newlib/libm/math/sf_sin.c
+++ b/newlib/libm/math/sf_sin.c
@@ -32,7 +32,7 @@
if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0);
/* sin(Inf or NaN) is NaN */
- else if (ix>=0x7f800000) return x-x;
+ else if (!FLT_UWORD_IS_FINITE(ix)) return x-x;
/* argument reduction needed */
else {
diff --git a/newlib/libm/math/sf_tan.c b/newlib/libm/math/sf_tan.c
index ade1cb216..18c47a454 100644
--- a/newlib/libm/math/sf_tan.c
+++ b/newlib/libm/math/sf_tan.c
@@ -32,7 +32,7 @@
if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1);
/* tan(Inf or NaN) is NaN */
- else if (ix>=0x7f800000) return x-x; /* NaN */
+ else if (!FLT_UWORD_IS_FINITE(ix)) return x-x; /* NaN */
/* argument reduction needed */
else {
diff --git a/newlib/libm/math/sf_tanh.c b/newlib/libm/math/sf_tanh.c
index ba9edf5c0..1eb44a2ff 100644
--- a/newlib/libm/math/sf_tanh.c
+++ b/newlib/libm/math/sf_tanh.c
@@ -35,7 +35,7 @@ static float one=1.0, two=2.0, tiny = 1.0e-30;
ix = jx&0x7fffffff;
/* x is INF or NaN */
- if(ix>=0x7f800000) {
+ if(!FLT_UWORD_IS_FINITE(ix)) {
if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
else return one/x-one; /* tanh(NaN) = NaN */
}