* Slim fdlibm version from GNU classpath, we need these functions (finite,
authortwisti <none@none>
Thu, 29 Sep 2005 12:16:48 +0000 (12:16 +0000)
committertwisti <none@none>
Thu, 29 Sep 2005 12:16:48 +0000 (12:16 +0000)
  fmod, copysign) since on some OSs the fmod does not work like java would
  like to have it (e.g. IRIX).  So we do not link against the system libm,
  but this one.

src/fdlibm/.cvsignore [new file with mode: 0644]
src/fdlibm/Makefile.am [new file with mode: 0644]
src/fdlibm/e_fmod.c [new file with mode: 0644]
src/fdlibm/fdlibm.h [new file with mode: 0644]
src/fdlibm/ieeefp.h [new file with mode: 0644]
src/fdlibm/java-assert.h [new file with mode: 0644]
src/fdlibm/mprec.h [new file with mode: 0644]
src/fdlibm/s_copysign.c [new file with mode: 0644]
src/fdlibm/s_finite.c [new file with mode: 0644]
src/fdlibm/w_fmod.c [new file with mode: 0644]

diff --git a/src/fdlibm/.cvsignore b/src/fdlibm/.cvsignore
new file mode 100644 (file)
index 0000000..e9f2658
--- /dev/null
@@ -0,0 +1,8 @@
+*.o
+*.a
+*.lo
+*.la
+.libs
+.deps
+Makefile
+Makefile.in
diff --git a/src/fdlibm/Makefile.am b/src/fdlibm/Makefile.am
new file mode 100644 (file)
index 0000000..07b2518
--- /dev/null
@@ -0,0 +1,17 @@
+INCLUDES = -I$(top_builddir)
+
+noinst_LTLIBRARIES = libfdlibm.la 
+
+libfdlibm_la_SOURCES =  \
+                       e_fmod.c \
+                       fdlibm.h \
+                       ieeefp.h \
+                       java-assert.h \
+                       mprec.h \
+                       s_copysign.c \
+                       s_finite.c \
+                       w_fmod.c
+
+# We just want the standard flags for fdlibm since it is an upstream lib
+# and our normal -pedantic -Wall -Werror breaks this lib. So no AM_CFLAGS.
+# We also don't need extra includes, so no AM_CPPFLAGS either.
diff --git a/src/fdlibm/e_fmod.c b/src/fdlibm/e_fmod.c
new file mode 100644 (file)
index 0000000..1cf0990
--- /dev/null
@@ -0,0 +1,140 @@
+
+/* @(#)e_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * __ieee754_fmod(x,y)
+ * Return x mod y in exact arithmetic
+ * Method: shift and subtract
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+static const double one = 1.0, Zero[] = {0.0, -0.0,};
+#else
+static double one = 1.0, Zero[] = {0.0, -0.0,};
+#endif
+
+#ifdef __STDC__
+       double __ieee754_fmod(double x, double y)
+#else
+       double __ieee754_fmod(x,y)
+       double x,y ;
+#endif
+{
+       int32_t n,hx,hy,hz,ix,iy,sx,i;
+       uint32_t lx,ly,lz;
+
+       EXTRACT_WORDS(hx,lx,x);
+       EXTRACT_WORDS(hy,ly,y);
+       sx = hx&0x80000000;             /* sign of x */
+       hx ^=sx;                /* |x| */
+       hy &= 0x7fffffff;       /* |y| */
+
+    /* purge off exception values */
+       if((hy|ly)==0||(hx>=0x7ff00000)||       /* y=0,or x not finite */
+         ((hy|((ly|-ly)>>31))>0x7ff00000))     /* or y is NaN */
+           return (x*y)/(x*y);
+       if(hx<=hy) {
+           if((hx<hy)||(lx<ly)) return x;      /* |x|<|y| return x */
+           if(lx==ly)
+               return Zero[(uint32_t)sx>>31];  /* |x|=|y| return x*0*/
+       }
+
+    /* determine ix = ilogb(x) */
+       if(hx<0x00100000) {     /* subnormal x */
+           if(hx==0) {
+               for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
+           } else {
+               for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
+           }
+       } else ix = (hx>>20)-1023;
+
+    /* determine iy = ilogb(y) */
+       if(hy<0x00100000) {     /* subnormal y */
+           if(hy==0) {
+               for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
+           } else {
+               for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
+           }
+       } else iy = (hy>>20)-1023;
+
+    /* set up {hx,lx}, {hy,ly} and align y to x */
+       if(ix >= -1022)
+           hx = 0x00100000|(0x000fffff&hx);
+       else {          /* subnormal x, shift x to normal */
+           n = -1022-ix;
+           if(n<=31) {
+               hx = (hx<<n)|(lx>>(32-n));
+               lx <<= n;
+           } else {
+               hx = lx<<(n-32);
+               lx = 0;
+           }
+       }
+       if(iy >= -1022)
+           hy = 0x00100000|(0x000fffff&hy);
+       else {          /* subnormal y, shift y to normal */
+           n = -1022-iy;
+           if(n<=31) {
+               hy = (hy<<n)|(ly>>(32-n));
+               ly <<= n;
+           } else {
+               hy = ly<<(n-32);
+               ly = 0;
+           }
+       }
+
+    /* fix point fmod */
+       n = ix - iy;
+       while(n--) {
+           hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+           if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
+           else {
+               if((hz|lz)==0)          /* return sign(x)*0 */
+                   return Zero[(uint32_t)sx>>31];
+               hx = hz+hz+(lz>>31); lx = lz+lz;
+           }
+       }
+       hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
+       if(hz>=0) {hx=hz;lx=lz;}
+
+    /* convert back to floating value and restore the sign */
+       if((hx|lx)==0)                  /* return sign(x)*0 */
+           return Zero[(uint32_t)sx>>31];
+       while(hx<0x00100000) {          /* normalize x */
+           hx = hx+hx+(lx>>31); lx = lx+lx;
+           iy -= 1;
+       }
+       if(iy>= -1022) {        /* normalize output */
+           hx = ((hx-0x00100000)|((iy+1023)<<20));
+           INSERT_WORDS(x,hx|sx,lx);
+       } else {                /* subnormal output */
+           n = -1022 - iy;
+           if(n<=20) {
+               lx = (lx>>n)|((uint32_t)hx<<(32-n));
+               hx >>= n;
+           } else if (n<=31) {
+               lx = (hx<<(32-n))|(lx>>n); hx = sx;
+           } else {
+               lx = hx>>(n-32); hx = sx;
+           }
+           INSERT_WORDS(x,hx|sx,lx);
+           x *= one;           /* create necessary signal */
+       }
+       return x;               /* exact output */
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */
diff --git a/src/fdlibm/fdlibm.h b/src/fdlibm/fdlibm.h
new file mode 100644 (file)
index 0000000..156a03c
--- /dev/null
@@ -0,0 +1,354 @@
+
+/* @(#)fdlibm.h 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993, 2000 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef __CLASSPATH_FDLIBM_H__
+#define __CLASSPATH_FDLIBM_H__
+
+/* AIX needs _XOPEN_SOURCE */
+#ifdef _AIX
+#define _XOPEN_SOURCE
+#endif
+
+#include <config.h>
+#include <stdlib.h>
+
+/* GCJ LOCAL: Include files.  */
+#include "ieeefp.h"
+
+#include "mprec.h"
+
+/* CYGNUS LOCAL: Default to XOPEN_MODE.  */
+#define _XOPEN_MODE
+
+#ifdef __P
+#undef __P
+#endif
+
+#ifdef __STDC__
+#define        __P(p)  p
+#else
+#define        __P(p)  ()
+#endif
+
+#ifndef HUGE
+#define        HUGE    ((float)3.40282346638528860e+38)
+#endif
+
+/* 
+ * set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
+ * (one may replace the following line by "#include <values.h>")
+ */
+
+#define X_TLOSS                1.41484755040568800000e+16 
+
+/* These typedefs are true for the targets running Java. */
+
+#define _IEEE_LIBM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ANSI/POSIX
+ */
+extern double acos __P((double));
+extern double asin __P((double));
+extern double atan __P((double));
+extern double atan2 __P((double, double));
+extern double cos __P((double));
+extern double sin __P((double));
+extern double tan __P((double));
+
+extern double cosh __P((double));
+extern double sinh __P((double));
+extern double tanh __P((double));
+
+extern double exp __P((double));
+extern double frexp __P((double, int *));
+extern double ldexp __P((double, int));
+extern double log __P((double));
+extern double log10 __P((double));
+extern double modf __P((double, double *));
+
+extern double pow __P((double, double));
+extern double sqrt __P((double));
+
+extern double ceil __P((double));
+extern double fabs __P((double));
+extern double floor __P((double));
+extern double fmod __P((double, double));
+
+extern double erf __P((double));
+extern double erfc __P((double));
+extern double gamma __P((double));
+extern double hypot __P((double, double));
+extern int isnan __P((double));
+extern int finite __P((double));
+extern double j0 __P((double));
+extern double j1 __P((double));
+extern double jn __P((int, double));
+extern double lgamma __P((double));
+extern double y0 __P((double));
+extern double y1 __P((double));
+extern double yn __P((int, double));
+
+extern double acosh __P((double));
+extern double asinh __P((double));
+extern double atanh __P((double));
+extern double cbrt __P((double));
+extern double logb __P((double));
+extern double nextafter __P((double, double));
+extern double remainder __P((double, double));
+
+/* Functions that are not documented, and are not in <math.h>.  */
+
+extern double logb __P((double));
+#ifdef _SCALB_INT
+extern double scalb __P((double, int));
+#else
+extern double scalb __P((double, double));
+#endif
+extern double significand __P((double));
+
+/* ieee style elementary functions */
+extern double __ieee754_sqrt __P((double));                    
+extern double __ieee754_acos __P((double));                    
+extern double __ieee754_acosh __P((double));                   
+extern double __ieee754_log __P((double));                     
+extern double __ieee754_atanh __P((double));                   
+extern double __ieee754_asin __P((double));                    
+extern double __ieee754_atan2 __P((double,double));                    
+extern double __ieee754_exp __P((double));
+extern double __ieee754_cosh __P((double));
+extern double __ieee754_fmod __P((double,double));
+extern double __ieee754_pow __P((double,double));
+extern double __ieee754_lgamma_r __P((double,int *));
+extern double __ieee754_gamma_r __P((double,int *));
+extern double __ieee754_log10 __P((double));
+extern double __ieee754_sinh __P((double));
+extern double __ieee754_hypot __P((double,double));
+extern double __ieee754_j0 __P((double));
+extern double __ieee754_j1 __P((double));
+extern double __ieee754_y0 __P((double));
+extern double __ieee754_y1 __P((double));
+extern double __ieee754_jn __P((int,double));
+extern double __ieee754_yn __P((int,double));
+extern double __ieee754_remainder __P((double,double));
+extern int32_t __ieee754_rem_pio2 __P((double,double*));
+#ifdef _SCALB_INT
+extern double __ieee754_scalb __P((double,int));
+#else
+extern double __ieee754_scalb __P((double,double));
+#endif
+
+/* fdlibm kernel function */
+extern double __kernel_standard __P((double,double,int));
+extern double __kernel_sin __P((double,double,int));
+extern double __kernel_cos __P((double,double));
+extern double __kernel_tan __P((double,double,int));
+extern int    __kernel_rem_pio2 __P((double*,double*,int,int,int,const int32_t*));
+
+/* Undocumented float functions.  */
+extern float logbf __P((float));
+#ifdef _SCALB_INT
+extern float scalbf __P((float, int));
+#else
+extern float scalbf __P((float, float));
+#endif
+extern float significandf __P((float));
+
+/*
+ * Functions callable from C, intended to support IEEE arithmetic.
+ */
+extern double copysign __P((double, double));
+extern int ilogb __P((double));
+extern double rint __P((double));
+extern float rintf __P((float));
+extern double scalbn __P((double, int));
+
+/* ieee style elementary float functions */
+extern float __ieee754_sqrtf __P((float));                     
+extern float __ieee754_acosf __P((float));                     
+extern float __ieee754_acoshf __P((float));                    
+extern float __ieee754_logf __P((float));                      
+extern float __ieee754_atanhf __P((float));                    
+extern float __ieee754_asinf __P((float));                     
+extern float __ieee754_atan2f __P((float,float));                      
+extern float __ieee754_expf __P((float));
+extern float __ieee754_coshf __P((float));
+extern float __ieee754_fmodf __P((float,float));
+extern float __ieee754_powf __P((float,float));
+extern float __ieee754_lgammaf_r __P((float,int *));
+extern float __ieee754_gammaf_r __P((float,int *));
+extern float __ieee754_log10f __P((float));
+extern float __ieee754_sinhf __P((float));
+extern float __ieee754_hypotf __P((float,float));
+extern float __ieee754_j0f __P((float));
+extern float __ieee754_j1f __P((float));
+extern float __ieee754_y0f __P((float));
+extern float __ieee754_y1f __P((float));
+extern float __ieee754_jnf __P((int,float));
+extern float __ieee754_ynf __P((int,float));
+extern float __ieee754_remainderf __P((float,float));
+extern int32_t __ieee754_rem_pio2f __P((float,float*));
+#ifdef _SCALB_INT
+extern float __ieee754_scalbf __P((float,int));
+#else
+extern float __ieee754_scalbf __P((float,float));
+#endif
+
+/* float versions of fdlibm kernel functions */
+extern float __kernel_sinf __P((float,float,int));
+extern float __kernel_cosf __P((float,float));
+extern float __kernel_tanf __P((float,float,int));
+extern int   __kernel_rem_pio2f __P((float*,float*,int,int,int,const int32_t*));
+
+/* The original code used statements like
+       n0 = ((*(int*)&one)>>29)^1;             * index of high word *
+       ix0 = *(n0+(int*)&x);                   * high word of x *
+       ix1 = *((1-n0)+(int*)&x);               * low word of x *
+   to dig two 32 bit words out of the 64 bit IEEE floating point
+   value.  That is non-ANSI, and, moreover, the gcc instruction
+   scheduler gets it wrong.  We instead use the following macros.
+   Unlike the original code, we determine the endianness at compile
+   time, not at run time; I don't see much benefit to selecting
+   endianness at run time.  */
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+ #error Must define endianness
+#endif
+#endif
+
+/* A union which permits us to convert between a double and two 32 bit
+   ints.  */
+
+#ifdef __IEEE_BIG_ENDIAN
+
+typedef union 
+{
+  double value;
+  struct 
+  {
+    uint32_t msw;
+    uint32_t lsw;
+  } parts;
+} ieee_double_shape_type;
+
+#endif
+
+#ifdef __IEEE_LITTLE_ENDIAN
+
+typedef union 
+{
+  double value;
+  struct 
+  {
+    uint32_t lsw;
+    uint32_t msw;
+  } parts;
+} ieee_double_shape_type;
+
+#endif
+
+/* Get two 32 bit ints from a double.  */
+
+#define EXTRACT_WORDS(ix0,ix1,d)                               \
+do {                                                           \
+  ieee_double_shape_type ew_u;                                 \
+  ew_u.value = (d);                                            \
+  (ix0) = ew_u.parts.msw;                                      \
+  (ix1) = ew_u.parts.lsw;                                      \
+} while (0)
+
+/* Get the more significant 32 bit int from a double.  */
+
+#define GET_HIGH_WORD(i,d)                                     \
+do {                                                           \
+  ieee_double_shape_type gh_u;                                 \
+  gh_u.value = (d);                                            \
+  (i) = gh_u.parts.msw;                                                \
+} while (0)
+
+/* Get the less significant 32 bit int from a double.  */
+
+#define GET_LOW_WORD(i,d)                                      \
+do {                                                           \
+  ieee_double_shape_type gl_u;                                 \
+  gl_u.value = (d);                                            \
+  (i) = gl_u.parts.lsw;                                                \
+} while (0)
+
+/* Set a double from two 32 bit ints.  */
+
+#define INSERT_WORDS(d,ix0,ix1)                                        \
+do {                                                           \
+  ieee_double_shape_type iw_u;                                 \
+  iw_u.parts.msw = (ix0);                                      \
+  iw_u.parts.lsw = (ix1);                                      \
+  (d) = iw_u.value;                                            \
+} while (0)
+
+/* Set the more significant 32 bits of a double from an int.  */
+
+#define SET_HIGH_WORD(d,v)                                     \
+do {                                                           \
+  ieee_double_shape_type sh_u;                                 \
+  sh_u.value = (d);                                            \
+  sh_u.parts.msw = (v);                                                \
+  (d) = sh_u.value;                                            \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int.  */
+
+#define SET_LOW_WORD(d,v)                                      \
+do {                                                           \
+  ieee_double_shape_type sl_u;                                 \
+  sl_u.value = (d);                                            \
+  sl_u.parts.lsw = (v);                                                \
+  (d) = sl_u.value;                                            \
+} while (0)
+
+/* A union which permits us to convert between a float and a 32 bit
+   int.  */
+
+typedef union
+{
+  float value;
+  uint32_t word;
+} ieee_float_shape_type;
+
+/* Get a 32 bit int from a float.  */
+
+#define GET_FLOAT_WORD(i,d)                                    \
+do {                                                           \
+  ieee_float_shape_type gf_u;                                  \
+  gf_u.value = (d);                                            \
+  (i) = gf_u.word;                                             \
+} while (0)
+
+/* Set a float from a 32 bit int.  */
+
+#define SET_FLOAT_WORD(d,i)                                    \
+do {                                                           \
+  ieee_float_shape_type sf_u;                                  \
+  sf_u.word = (i);                                             \
+  (d) = sf_u.value;                                            \
+} while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLASSPATH_FDLIBM_H__ */
diff --git a/src/fdlibm/ieeefp.h b/src/fdlibm/ieeefp.h
new file mode 100644 (file)
index 0000000..405baab
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef __CLASSPATH_IEEEFP_H__
+#define __CLASSPATH_IEEEFP_H__
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+
+#ifdef __alpha__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#if defined(__arm__) || defined(__thumb__)
+/* ARM traditionally used big-endian words; and within those words the
+   byte ordering was big or little endian depending upon the target.  
+   Modern floating-point formats are naturally ordered; in this case
+   __VFP_FP__ will be defined, even if soft-float.  */
+#ifdef __VFP_FP__
+#ifdef __ARMEL__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#else
+#define __IEEE_BIG_ENDIAN
+#ifdef __ARMEL__
+#define __IEEE_BYTES_LITTLE_ENDIAN
+#endif
+#endif
+#endif
+
+#ifdef __hppa__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__sparc) || defined (__sparc__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __m32r__
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#endif
+
+#if defined(__m68k__) || defined(__mc68000__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#if defined (__H8300__) || defined (__H8300H__)
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __H8500__
+#define __IEEE_BIG_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#ifdef __sh__
+#ifdef __LITTLE_ENDIAN__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __SH3E__
+#define _DOUBLE_IS_32BITS
+#endif
+#endif
+
+#ifdef _AM29K
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __i386__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __x86_64__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __i960__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __MIPSEL__
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#ifdef __MIPSEB__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __pj__
+#ifdef __pjl__
+#define __IEEE_LITTLE_ENDIAN
+#else
+#define __IEEE_BIG_ENDIAN
+#endif
+#endif
+
+/* necv70 was __IEEE_LITTLE_ENDIAN. */
+
+#ifdef __W65__
+#define __IEEE_LITTLE_ENDIAN
+#define __SMALL_BITFIELDS
+#define _DOUBLE_IS_32BITS
+#endif
+
+#if defined(__Z8001__) || defined(__Z8002__)
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __m88k__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __v800
+#define __IEEE_LITTLE_ENDIAN
+#endif
+
+#if defined (__PPC__) || defined (__ppc__) || defined (__ppc64__)
+#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) \
+    || defined (__APPLE__)
+#define __IEEE_BIG_ENDIAN
+#else
+#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(__WIN32__) && __WIN32__)
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#endif
+#endif
+
+#ifdef __fr30__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifdef __mcore__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+
+#ifdef __ia64__
+#ifdef __BIG_ENDIAN__
+#define __IEEE_BIG_ENDIAN
+#else
+#define __IEEE_LITTLE_ENDIAN
+#endif
+#endif
+
+#ifdef __s390__
+#define __IEEE_BIG_ENDIAN
+#endif
+
+#ifndef __IEEE_BIG_ENDIAN
+#ifndef __IEEE_LITTLE_ENDIAN
+#error Endianess not declared!!
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
+#endif /* not __IEEE_LITTLE_ENDIAN */
+#endif /* not __IEEE_BIG_ENDIAN */
+
+#endif /* __CLASSPATH_IEEEFP_H__ */
diff --git a/src/fdlibm/java-assert.h b/src/fdlibm/java-assert.h
new file mode 100644 (file)
index 0000000..4b2d836
--- /dev/null
@@ -0,0 +1,40 @@
+/* java-assert.h - Header file holding assertion definitions.  -*- c++ -*- */
+
+/* Copyright (C) 1998, 1999  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+#ifndef __JAVA_ASSERT_H__
+#define __JAVA_ASSERT_H__
+
+#include "config.h"
+
+/* This is a libgcj implementation header. */
+
+void _Jv_Abort (const char *, const char *, int, const char *)
+  __attribute__ ((__noreturn__));
+
+#ifdef DEBUG
+#define _Jv_AssertDoCall(Message) _Jv_Abort (__FUNCTION__, __FILE__, __LINE__, Message)
+
+#define JvAssertMessage(Expr, Message) \
+   do { if (! (Expr)) _Jv_AssertDoCall (Message); } while (0)
+#define JvAssert(Expr) \
+   do { if (! (Expr)) _Jv_AssertDoCall (# Expr); } while (0)
+
+#define JvFail(Message) _Jv_AssertDoCall (Message)
+
+#else /* DEBUG */
+
+#define _Jv_AssertDoCall(Message)
+#define JvAssertMessage(Expr, Message)
+#define JvAssert(Expr)
+#define JvFail(Message) _Jv_Abort (0, 0, 0, Message)
+
+#endif /* not DEBUG */
+
+#endif /* __JAVA_ASSERT_H__ */
diff --git a/src/fdlibm/mprec.h b/src/fdlibm/mprec.h
new file mode 100644 (file)
index 0000000..9e1a106
--- /dev/null
@@ -0,0 +1,407 @@
+/****************************************************************
+ *
+ * The author of this software is David M. Gay.
+ *
+ * Copyright (c) 1991, 2000 by AT&T.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ ***************************************************************/
+
+/* Please send bug reports to
+       David M. Gay
+       AT&T Bell Laboratories, Room 2C-463
+       600 Mountain Avenue
+       Murray Hill, NJ 07974-2070
+       U.S.A.
+       dmg@research.att.com or research!dmg
+ */
+
+#ifndef __CLASSPATH_MPREC_H__
+#define __CLASSPATH_MPREC_H__
+
+#include <config.h>
+#include "ieeefp.h"
+
+#if defined HAVE_STDINT_H
+#include <stdint.h>
+#elif defined HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if defined HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#if defined HAVE_SYS_CONFIG_H
+#include <sys/config.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ISO C99 int type declarations */
+
+#if !defined HAVE_INT32_DEFINED && defined HAVE_BSD_INT32_DEFINED
+typedef u_int32_t uint32_t;
+#endif
+
+#if !defined HAVE_BSD_INT32_DEFINED && !defined HAVE_INT32_DEFINED
+/* FIXME this could have problems with systems that don't define SI to be 4 */
+typedef int int32_t __attribute__((mode(SI)));
+
+/* This is a blatant hack: on Solaris 2.5, pthread.h defines uint32_t
+   in pthread.h, which we sometimes include.  We protect our
+   definition the same way Solaris 2.5 does, to avoid redefining it.  */
+#  ifndef _UINT32_T
+typedef unsigned int uint32_t __attribute__((mode(SI)));
+#  endif
+#endif
+
+  /* These typedefs are true for the targets running Java. */
+
+#ifdef __IEEE_LITTLE_ENDIAN
+#define IEEE_8087
+#endif
+
+#ifdef __IEEE_BIG_ENDIAN
+#define IEEE_MC68k
+#endif
+
+#ifdef __Z8000__
+#define Just_16
+#endif
+
+#ifdef DEBUG
+#include "stdio.h"
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= (uint32_t)0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
+Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
+#endif
+
+/* If we are going to examine or modify specific bits in a double using
+   the word0 and/or word1 macros, then we must wrap the double inside
+   a union.  This is necessary to avoid undefined behavior according to
+   the ANSI C spec.  */
+union double_union
+{
+  double d;
+  uint32_t i[2];
+};
+
+#ifdef IEEE_8087
+#define word0(x) (x.i[1])
+#define word1(x) (x.i[0])
+#else
+#define word0(x) (x.i[0])
+#define word1(x) (x.i[1])
+#endif
+
+/* The following definition of Storeinc is appropriate for MIPS processors.
+ * An alternative that might be better on some machines is
+ * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
+ */
+#if defined(IEEE_8087) + defined(VAX)
+#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
+((unsigned short *)a)[0] = (unsigned short)c, a++)
+#else
+#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
+((unsigned short *)a)[1] = (unsigned short)c, a++)
+#endif
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_8087) + defined(IEEE_MC68k)
+#if defined (_DOUBLE_IS_32BITS)
+#define Exp_shift   23
+#define Exp_shift1  23
+#define Exp_msk1    ((uint32_t)0x00800000L)
+#define Exp_msk11   ((uint32_t)0x00800000L)
+#define Exp_mask    ((uint32_t)0x7f800000L)
+#define P          24
+#define Bias       127
+#if 0
+#define IEEE_Arith  /* it is, but the code doesn't handle IEEE singles yet */
+#endif
+#define Emin        (-126)
+#define Exp_1       ((uint32_t)0x3f800000L)
+#define Exp_11      ((uint32_t)0x3f800000L)
+#define Ebits      8
+#define Frac_mask   ((uint32_t)0x007fffffL)
+#define Frac_mask1  ((uint32_t)0x007fffffL)
+#define Ten_pmax    10
+#define Sign_bit    ((uint32_t)0x80000000L)
+#define Ten_pmax    10
+#define Bletch     2
+#define Bndry_mask  ((uint32_t)0x007fffffL)
+#define Bndry_mask1 ((uint32_t)0x007fffffL)
+#define LSB 1
+#define Sign_bit    ((uint32_t)0x80000000L)
+#define Log2P      1
+#define Tiny0      0
+#define Tiny1      1
+#define Quick_max   5
+#define Int_max     6
+#define Infinite(x) (word0(x) == ((uint32_t)0x7f800000L))
+#undef word0
+#undef word1
+
+#define word0(x) (x.i[0])
+#define word1(x) 0
+#else
+
+#define Exp_shift  20
+#define Exp_shift1 20
+#define Exp_msk1    ((uint32_t)0x100000L)
+#define Exp_msk11   ((uint32_t)0x100000L)
+#define Exp_mask  ((uint32_t)0x7ff00000L)
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1  ((uint32_t)0x3ff00000L)
+#define Exp_11 ((uint32_t)0x3ff00000L)
+#define Ebits 11
+#define Frac_mask  ((uint32_t)0xfffffL)
+#define Frac_mask1 ((uint32_t)0xfffffL)
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask  ((uint32_t)0xfffffL)
+#define Bndry_mask1 ((uint32_t)0xfffffL)
+#define LSB 1
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (word0(x) == ((uint32_t)0x7ff00000L)) /* sufficient test for here */
+#endif
+
+#else
+#undef  Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift  24
+#define Exp_shift1 24
+#define Exp_msk1   ((uint32_t)0x1000000L)
+#define Exp_msk11  ((uint32_t)0x1000000L)
+#define Exp_mask  ((uint32_t)0x7f000000L)
+#define P 14
+#define Bias 65
+#define Exp_1  ((uint32_t)0x41000000L)
+#define Exp_11 ((uint32_t)0x41000000L)
+#define Ebits 8        /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask  ((uint32_t)0xffffffL)
+#define Frac_mask1 ((uint32_t)0xffffffL)
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask  ((uint32_t)0xefffffL)
+#define Bndry_mask1 ((uint32_t)0xffffffL)
+#define LSB 1
+#define Sign_bit ((uint32_t)0x80000000L)
+#define Log2P 4
+#define Tiny0 ((uint32_t)0x100000L)
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift  23
+#define Exp_shift1 7
+#define Exp_msk1    0x80
+#define Exp_msk11   ((uint32_t)0x800000L)
+#define Exp_mask  ((uint32_t)0x7f80L)
+#define P 56
+#define Bias 129
+#define Exp_1  ((uint32_t)0x40800000L)
+#define Exp_11 ((uint32_t)0x4080L)
+#define Ebits 8
+#define Frac_mask  ((uint32_t)0x7fffffL)
+#define Frac_mask1 ((uint32_t)0xffff007fL)
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask  ((uint32_t)0xffff007fL)
+#define Bndry_mask1 ((uint32_t)0xffff007fL)
+#define LSB ((uint32_t)0x10000L)
+#define Sign_bit ((uint32_t)0x8000L)
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+#ifdef KR_headers
+extern double rnd_prod(), rnd_quot();
+#else
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#endif
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 ((uint32_t)0xffffffffL)
+
+/* TWISTI to avoid bugs, we should use Just_16 on every platform */
+#define Just_16
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower.  Hence the default is now to store 32 bits per long.
+ */
+
+#ifndef Pack_32
+#if SIZEOF_VOID_P != 8
+#define Pack_32
+#endif
+#endif
+#endif
+
+
+#define MAX_BIGNUMS 16
+/* TWISTI this does not work at least on alpha */
+/* #define MAX_BIGNUM_WDS 32 */
+#define MAX_BIGNUM_WDS 64
+
+struct _Jv_Bigint
+{
+  struct _Jv_Bigint *_next;
+  int _k, _maxwds, _sign, _wds;
+  unsigned long _x[MAX_BIGNUM_WDS];
+};
+
+
+#define        _PTR            void *
+#define        _AND            ,
+#define        _NOARGS         void
+#define        _CONST          const
+#define        _VOLATILE       volatile
+#define        _SIGNED         signed
+#define        _DOTS           , ...
+#define _VOID void
+#define        _EXFUN(name, proto)             name proto
+#define        _DEFUN(name, arglist, args)     name(args)
+#define        _DEFUN_VOID(name)               name(_NOARGS)
+#define _CAST_VOID (void)
+
+
+struct _Jv_reent
+{
+  /* local copy of errno */
+  int _errno;
+
+  /* used by mprec routines */
+  struct _Jv_Bigint *_result;
+  int _result_k;
+  struct _Jv_Bigint *_p5s;
+
+  struct _Jv_Bigint _freelist[MAX_BIGNUMS];
+  int _allocation_map;
+
+  int num;
+};
+
+
+typedef struct _Jv_Bigint _Jv_Bigint;
+
+#define Balloc  _Jv_Balloc
+#define Bfree   _Jv_Bfree
+#define multadd _Jv_multadd
+#define s2b     _Jv_s2b
+#define lo0bits _Jv_lo0bits
+#define hi0bits _Jv_hi0bits
+#define i2b     _Jv_i2b
+#define mult    _Jv_mult
+#define pow5mult        _Jv_pow5mult
+#define lshift  _Jv_lshift
+#define cmp     _Jv__mcmp
+#define diff    _Jv__mdiff
+#define ulp     _Jv_ulp
+#define b2d     _Jv_b2d
+#define d2b     _Jv_d2b
+#define ratio   _Jv_ratio
+
+#define tens _Jv__mprec_tens
+#define bigtens _Jv__mprec_bigtens
+#define tinytens _Jv__mprec_tinytens
+
+#define _dtoa _Jv_dtoa
+#define _dtoa_r _Jv_dtoa_r
+#define _strtod_r _Jv_strtod_r
+
+extern double _EXFUN(_strtod_r, (struct _Jv_reent *ptr, const char *s00, char **se));
+extern char* _EXFUN(_dtoa_r, (struct _Jv_reent *ptr, double d,
+                             int mode, int ndigits, int *decpt, int *sign,
+                             char **rve, int float_type));
+void _EXFUN(_dtoa, (double d, int mode, int ndigits, int *decpt, int *sign,
+                   char **rve, char *buf, int float_type));
+
+double                 _EXFUN(ulp,(double x));
+double         _EXFUN(b2d,(_Jv_Bigint *a , int *e));
+_Jv_Bigint *   _EXFUN(Balloc,(struct _Jv_reent *p, int k));
+void           _EXFUN(Bfree,(struct _Jv_reent *p, _Jv_Bigint *v));
+_Jv_Bigint *   _EXFUN(multadd,(struct _Jv_reent *p, _Jv_Bigint *, int, int));
+_Jv_Bigint *   _EXFUN(s2b,(struct _Jv_reent *, const char*, int, int, unsigned long));
+_Jv_Bigint *   _EXFUN(i2b,(struct _Jv_reent *,int));
+_Jv_Bigint *   _EXFUN(mult, (struct _Jv_reent *, _Jv_Bigint *, _Jv_Bigint *));
+_Jv_Bigint *   _EXFUN(pow5mult, (struct _Jv_reent *, _Jv_Bigint *, int k));
+int            _EXFUN(hi0bits,(unsigned long));
+int            _EXFUN(lo0bits,(unsigned long *));
+_Jv_Bigint *    _EXFUN(d2b,(struct _Jv_reent *p, double d, int *e, int *bits));
+_Jv_Bigint *    _EXFUN(lshift,(struct _Jv_reent *p, _Jv_Bigint *b, int k));
+_Jv_Bigint *    _EXFUN(diff,(struct _Jv_reent *p, _Jv_Bigint *a, _Jv_Bigint *b));
+int             _EXFUN(cmp,(_Jv_Bigint *a, _Jv_Bigint *b));
+
+double         _EXFUN(ratio,(_Jv_Bigint *a, _Jv_Bigint *b));
+#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(long) + 2*sizeof(int))
+
+#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
+#define n_bigtens 2
+#else
+#define n_bigtens 5
+#endif
+
+extern _CONST double tinytens[];
+extern _CONST double bigtens[];
+extern _CONST double tens[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLASSPATH_MPREC_H__ */
diff --git a/src/fdlibm/s_copysign.c b/src/fdlibm/s_copysign.c
new file mode 100644 (file)
index 0000000..4804df1
--- /dev/null
@@ -0,0 +1,82 @@
+
+/* @(#)s_copysign.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+FUNCTION
+<<copysign>>, <<copysignf>>---sign of <[y]>, magnitude of <[x]>
+
+INDEX
+       copysign
+INDEX
+       copysignf
+
+ANSI_SYNOPSIS
+       #include <math.h>
+       double copysign (double <[x]>, double <[y]>);
+       float copysignf (float <[x]>, float <[y]>);
+
+TRAD_SYNOPSIS
+       #include <math.h>
+       double copysign (<[x]>, <[y]>)
+       double <[x]>;
+       double <[y]>;
+
+       float copysignf (<[x]>, <[y]>)
+       float <[x]>;
+       float <[y]>;
+
+DESCRIPTION
+<<copysign>> constructs a number with the magnitude (absolute value)
+of its first argument, <[x]>, and the sign of its second argument,
+<[y]>.
+
+<<copysignf>> does the same thing; the two functions differ only in
+the type of their arguments and result.
+
+RETURNS
+<<copysign>> returns a <<double>> with the magnitude of
+<[x]> and the sign of <[y]>.
+<<copysignf>> returns a <<float>> with the magnitude of
+<[x]> and the sign of <[y]>.
+
+PORTABILITY
+<<copysign>> is not required by either ANSI C or the System V Interface
+Definition (Issue 2).
+
+*/
+
+/*
+ * copysign(double x, double y)
+ * copysign(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include "fdlibm.h"
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+       double copysign(double x, double y)
+#else
+       double copysign(x,y)
+       double x,y;
+#endif
+{
+       uint32_t hx,hy;
+       GET_HIGH_WORD(hx,x);
+       GET_HIGH_WORD(hy,y);
+       SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
+        return x;
+}
+
+#endif /* _DOUBLE_IS_32BITS */
diff --git a/src/fdlibm/s_finite.c b/src/fdlibm/s_finite.c
new file mode 100644 (file)
index 0000000..3e6c812
--- /dev/null
@@ -0,0 +1,31 @@
+
+/* @(#)s_finite.c 1.3 95/01/18 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunSoft, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * finite(x) returns 1 is x is finite, else 0;
+ * no branching!
+ */
+
+#include "fdlibm.h"
+
+#ifdef __STDC__
+       int finite(double x)
+#else
+       int finite(x)
+       double x;
+#endif
+{
+       uint32_t high; 
+       GET_HIGH_WORD(high,x);
+       return  (unsigned)((high&0x7fffffff)-0x7ff00000)>>31;
+}
diff --git a/src/fdlibm/w_fmod.c b/src/fdlibm/w_fmod.c
new file mode 100644 (file)
index 0000000..b6b36cb
--- /dev/null
@@ -0,0 +1,107 @@
+
+/* @(#)w_fmod.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice 
+ * is preserved.
+ * ====================================================
+ */
+
+/* 
+FUNCTION 
+<<fmod>>, <<fmodf>>---floating-point remainder (modulo)
+
+INDEX
+fmod
+INDEX
+fmodf
+
+ANSI_SYNOPSIS
+#include <math.h>
+double fmod(double <[x]>, double <[y]>)
+float fmodf(float <[x]>, float <[y]>)
+
+TRAD_SYNOPSIS
+#include <math.h>
+double fmod(<[x]>, <[y]>)
+double (<[x]>, <[y]>);
+
+float fmodf(<[x]>, <[y]>)
+float (<[x]>, <[y]>);
+
+DESCRIPTION
+The <<fmod>> and <<fmodf>> functions compute the floating-point
+remainder of <[x]>/<[y]> (<[x]> modulo <[y]>).
+
+RETURNS
+The <<fmod>> function returns the value 
+@ifinfo
+<[x]>-<[i]>*<[y]>, 
+@end ifinfo
+@tex
+$x-i\times y$,
+@end tex
+for the largest integer <[i]> such that, if <[y]> is nonzero, the
+result has the same sign as <[x]> and magnitude less than the
+magnitude of <[y]>. 
+
+<<fmod(<[x]>,0)>> returns NaN, and sets <<errno>> to <<EDOM>>.
+
+You can modify error treatment for these functions using <<matherr>>.
+
+PORTABILITY
+<<fmod>> is ANSI C. <<fmodf>> is an extension.
+*/
+
+/* 
+ * wrapper fmod(x,y)
+ */
+
+#include "fdlibm.h"
+#include <errno.h>
+
+#ifndef _DOUBLE_IS_32BITS
+
+#ifdef __STDC__
+       double fmod(double x, double y) /* wrapper fmod */
+#else
+       double fmod(x,y)                /* wrapper fmod */
+       double x,y;
+#endif
+{
+#ifdef _IEEE_LIBM
+       return __ieee754_fmod(x,y);
+#else
+       double z;
+       struct exception exc;
+       z = __ieee754_fmod(x,y);
+       if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
+       if(y==0.0) {
+            /* fmod(x,0) */
+            exc.type = DOMAIN;
+            exc.name = "fmod";
+           exc.arg1 = x;
+           exc.arg2 = y;
+           exc.err = 0;
+            if (_LIB_VERSION == _SVID_)
+               exc.retval = x;
+           else
+              exc.retval = 0.0/0.0;
+            if (_LIB_VERSION == _POSIX_)
+               errno = EDOM;
+            else if (!matherr(&exc)) {
+                  errno = EDOM;
+            }
+           if (exc.err != 0)
+              errno = exc.err;
+            return exc.retval; 
+       } else
+           return z;
+#endif
+}
+
+#endif /* defined(_DOUBLE_IS_32BITS) */