Add incomplet long double math support to libmingwex.a

This commit is contained in:
Danny Smith 2002-07-29 03:00:10 +00:00
parent 840e611264
commit b8cdc234c6
143 changed files with 5213 additions and 639 deletions

View File

@ -1,3 +1,154 @@
2002-07-29 Danny Smith <dannysmith@users.sourceforge.net>
* moldname.def.in (chgsign,scalb,finite,fpclass,logb,
nextafter): Add non-underscored stubs.
* moldname-msvcrt.def: Regenerate.
* moldname-crtdll.def: Regenerate.
* mingwex/math: New directory.
* mingwex/rint.c: Move to mingwex/math.
* mingwex/rintf.c: Ditto.
* mingwex/rintl.c: Ditto.
* mingwex/round.c: Ditto.
* mingwex/roundf.c: Ditto.
* mingwex/roundl.c: Ditto.
* mingwex/rint.c: Ditto.
* mingwex/rintf.c: Ditto.
* mingwex/rintl.c: Ditto.
* mingwex/trunc.c: Ditto.
* mingwex/truncf.c: Ditto.
* mingwex/truncl.c: Ditto.
* mingwex/signbit.c: Ditto.
* mingwex/signbitf.c: Ditto.
* mingwex/signbitl.c: Ditto.
* mingwex/copysignl.S: Ditto.
* mingwex/fdim.c: Ditto.
* mingwex/fdimf.c: Ditto.
* mingwex/fdiml.c: Ditto.
* mingwex/fmin.c: Ditto.
* mingwex/fminf.c: Ditto.
* mingwex/fminl.c: Ditto.
* mingwex/fmax.c: Ditto.
* mingwex/fmaxf.c: Ditto.
* mingwex/fmaxl.c: Ditto.
* mingwex/fma.c: Ditto.
* mingwex/fmaf.c: Ditto.
* mingwex/fmal.c: Ditto.
* mingwex/fpclassify.c: Ditto.
* mingwex/fpclassifyl.c: Ditto.
* mingwex/fpclassifyl.c: Ditto.
* mingwex/isnan.c: Ditto.
* mingwex/isnanf.c: Ditto.
* mingwex/isnanl.c: Ditto.
* mingwex/fucom.c: Ditto.
* mingwex/fp_consts.c: Ditto. Split out float and long double
definitions.
* mingwex/math_stubs.c: Remove.
* mingwex/log2.c: Remove. Replaced by math/log2.S
* mingwex/log2f.c: Remove. Replaced by math/log2f.S
* mingwex/log2l.c: Remove. Replaced by math/log2l.S
* mingwex/math/acosf.c : New file.
* mingwex/math/acosl.c: New file.
* mingwex/math/asinf.c: New file.
* mingwex/math/asinl.c: New file.
* mingwex/math/atan2f.c: New file.
* mingwex/math/atan2l.c: New file.
* mingwex/math/atanf.c: New file.
* mingwex/math/atanl.c: New file.
* mingwex/math/cbrt.c: New file.
* mingwex/math/cbrtf.c: New file.
* mingwex/math/cbrtl.c: New file.
* mingwex/math/ceilf.S: New file.
* mingwex/math/ceill.S: New file.
* mingwex/math/cephes_ld.h: New file.
* mingwex/math/copysign.S: New file.
* mingwex/math/copysignf.S: New file.
* mingwex/math/cosf.S: New file.
* mingwex/math/coshf.c: New file.
* mingwex/math/coshl.c: New file.
* mingwex/math/cosl.S: New file.
* mingwex/math/exp2.S: New file.
* mingwex/math/exp2f.S: New file.
* mingwex/math/exp2l.S: New file.
* mingwex/math/expf.c: New file.
* mingwex/math/expl.c: New file.
* mingwex/math/fabs.c: New file.
* mingwex/math/fabsf.c: New file.
* mingwex/math/fabsl.c: New file.
* mingwex/math/floorf.S: New file.
* mingwex/math/floorl.S: New file.
* mingwex/math/fmodf.c: New file.
* mingwex/math/fmodl.c: New file.
* mingwex/math/fp_consts.h: Ditto.
* mingwex/math/fp_constsf.c: Ditto.
* mingwex/math/fp_constsl.c: Ditto.
* mingwex/math/frexpf.c: New file.
* mingwex/math/frexpl.S: New file.
* mingwex/math/hypotf.c: New file.
* mingwex/math/hypotl.c: New file.
* mingwex/math/ilogb.S: New file.
* mingwex/math/ilogbf.S: New file.
* mingwex/math/ilogbl.S: New file.
* mingwex/math/ldexpf.c: New file.
* mingwex/math/ldexpl.c: New file.
* mingwex/math/llrint.c: New file.
* mingwex/math/llrintf.c: New file.
* mingwex/math/llrintl.c: New file.
* mingwex/math/llround.c: New file.
* mingwex/math/llroundf.c: New file.
* mingwex/math/llroundl.c: New file.
* mingwex/math/log10f.S: New file.
* mingwex/math/log10l.S: New file.
* mingwex/math/log1p.S: New file.
* mingwex/math/log1pf.S: New file.
* mingwex/math/log1pl.S: New file.
* mingwex/math/log2.S: New file.
* mingwex/math/log2f.S: New file.
* mingwex/math/log2l.S: New file.
* mingwex/math/logb.c: New file.
* mingwex/math/logbf.c: New file.
* mingwex/math/logbl.c: New file.
* mingwex/math/logf.S: New file.
* mingwex/math/logl.S: New file.
* mingwex/math/lrint.c: New file.
* mingwex/math/lrintf.c: New file.
* mingwex/math/lrintl.c: New file.
* mingwex/math/lround.c: New file.
* mingwex/math/lroundf.c: New file.
* mingwex/math/lroundl.c: New file.
* mingwex/math/modff.c: New file.
* mingwex/math/modfl.c: New file.
* mingwex/math/nearbyint.S: New file.
* mingwex/math/nearbyintf.S: New file.
* mingwex/math/nearbyintl.S: New file.
* mingwex/math/nextafterf.c: New file.
* mingwex/math/powf.c: New file.
* mingwex/math/powl.c: New file.
* mingwex/math/powil.c: New file.
* mingwex/math/remainder.S: New file.
* mingwex/math/remainderf.S: New file.
* mingwex/math/remainderl.S: New file.
* mingwex/math/remquo.S: New file.
* mingwex/math/remquof.S: New file.
* mingwex/math/remquol.S: New file.
* mingwex/math/scalbn.S: New file.
* mingwex/math/scalbnf.S: New file.
* mingwex/math/scalbnl.S: New file.
* mingwex/math/sinf.S: New file.
* mingwex/math/sinhf.c: New file.
* mingwex/math/sinhl.c: New file.
* mingwex/math/sinl.S: New file.
* mingwex/math/sqrt.c: New file.
* mingwex/math/sqrtf.c: New file.
* mingwex/math/sqrtl.c: New file.
* mingwex/math/tanf.S: New file.
* mingwex/math/tanhf.c: New file.
* mingwex/math/tanhl.c: New file.
* mingwex/math/tanl.S: New file.
* mingwex/Makefile.in: Adjust VPATH for source files in
mingwex/math.
* include/ math.h: Add protypes for new functions and
reorganise to reflect ANSI,C99 status.
2002-06-19 Danny Smith <dannysmith@users.sourceforge.net> 2002-06-19 Danny Smith <dannysmith@users.sourceforge.net>
* include/tchar.h (_getts): Define as _getws for _UNICODE. * include/tchar.h (_getts): Define as _getws for _UNICODE.

View File

@ -144,17 +144,30 @@ double log (double);
double log10 (double); double log10 (double);
double pow (double, double); double pow (double, double);
double sqrt (double); double sqrt (double);
extern __inline__ double sqrt (double x)
{
double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
double ceil (double); double ceil (double);
double floor (double); double floor (double);
double fabs (double); double fabs (double);
extern __inline__ double fabs (double x)
{
double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
double ldexp (double, int); double ldexp (double, int);
double frexp (double, int*); double frexp (double, int*);
double modf (double, double*); double modf (double, double*);
double fmod (double, double); double fmod (double, double);
#ifndef __STRICT_ANSI__ #ifndef __STRICT_ANSI__
/* Complex number (for cabs) */ /* Complex number (for cabs). This really belongs in complex.h */
struct _complex struct _complex
{ {
double x; /* Real part */ double x; /* Real part */
@ -162,6 +175,7 @@ struct _complex
}; };
double _cabs (struct _complex); double _cabs (struct _complex);
double _hypot (double, double); double _hypot (double, double);
double _j0 (double); double _j0 (double);
double _j1 (double); double _j1 (double);
@ -190,17 +204,15 @@ int _isnan (double);
/* END FLOAT.H COPY */ /* END FLOAT.H COPY */
#if !defined (_NO_OLDNAMES) \
|| (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
/* /*
* Non-underscored versions of non-ANSI functions. These reside in * Non-underscored versions of non-ANSI functions.
* liboldnames.a. They are now also ISO C99 standand names. * These reside in liboldnames.a.
* Provided for extra portability.
*/ */
#if !defined (_NO_OLDNAMES)
double cabs (struct _complex); double cabs (struct _complex);
double hypot (double, double);
double j0 (double); double j0 (double);
double j1 (double); double j1 (double);
double jn (int, double); double jn (int, double);
@ -208,28 +220,27 @@ double y0 (double);
double y1 (double); double y1 (double);
double yn (int, double); double yn (int, double);
double chgsign (double);
double scalb (double, long);
int finite (double);
int fpclass (double);
#endif /* Not _NO_OLDNAMES */ #endif /* Not _NO_OLDNAMES */
#endif /* Not __STRICT_ANSI__ */ #endif /* __STRICT_ANSI__ */
#ifdef __cplusplus
}
#endif
#endif /* Not RC_INVOKED */
#ifndef __NO_ISOCEXT #ifndef __NO_ISOCEXT
#ifndef RC_INVOKED
#ifdef __cplusplus
extern "C" {
#endif
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \ #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|| !defined __STRICT_ANSI__ || !defined __STRICT_ANSI__
#define INFINITY HUGE_VAL
#define NAN (0.0F/0.0F) #define NAN (0.0F/0.0F)
#define HUGE_VALF (1.0F/0.0F)
#define HUGE_VALL (1.0L/0.0L)
#define INFINITY (1.0F/0.0F)
/* 7.12.3.1 */
/* /*
Return values for fpclassify. Return values for fpclassify.
These are based on Intel x87 fpu condition codes These are based on Intel x87 fpu condition codes
@ -244,17 +255,6 @@ extern "C" {
/* 0x0200 is signbit mask */ /* 0x0200 is signbit mask */
/* Return a NaN */
double nan(const char *tagp);
float nanf(const char *tagp);
long double nanl(const char *tagp);
#ifndef __STRICT_ANSI__
#define nan() nan("")
#define nanf() nanf("")
#define nanl() nanl("")
#endif
/* /*
We can't inline float or double, because we want to ensure truncation We can't inline float or double, because we want to ensure truncation
to semantic type before classification. to semantic type before classification.
@ -275,8 +275,16 @@ extern __inline__ int __fpclassifyl (long double x){
: sizeof (x) == sizeof (double) ? __fpclassify (x) \ : sizeof (x) == sizeof (double) ? __fpclassify (x) \
: __fpclassifyl (x)) : __fpclassifyl (x))
/* 7.12.3.2 */
#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
/* 7.12.3.3 */
#define isinf(x) (fpclassify(x) == FP_INFINITE)
/* 7.12.3.4 */
/* We don't need to worry about trucation here: /* We don't need to worry about trucation here:
A NaN stays a NaN. */ A NaN stays a NaN. */
extern __inline__ int __isnan (double _x) extern __inline__ int __isnan (double _x)
{ {
unsigned short sw; unsigned short sw;
@ -304,15 +312,15 @@ extern __inline__ int __isnanl (long double _x)
== FP_NAN; == FP_NAN;
} }
#define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \ #define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \
: sizeof (x) == sizeof (double) ? __isnan (x) \ : sizeof (x) == sizeof (double) ? __isnan (x) \
: __isnanl (x)) : __isnanl (x))
#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0) /* 7.12.3.5 */
#define isinf(x) (fpclassify(x) == FP_INFINITE)
#define isnormal(x) (fpclassify(x) == FP_NORMAL) #define isnormal(x) (fpclassify(x) == FP_NORMAL)
/* 7.12.3.6 The signbit macro */
extern __inline__ int __signbit (double x) { extern __inline__ int __signbit (double x) {
unsigned short stw; unsigned short stw;
__asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x)); __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
@ -335,11 +343,361 @@ extern __inline__ int __signbitl (long double x) {
: sizeof (x) == sizeof (double) ? __signbit (x) \ : sizeof (x) == sizeof (double) ? __signbit (x) \
: __signbitl (x)) : __signbitl (x))
/* 7.12.4 Trigonometric functions: Double in C89 */
extern float sinf (float);
extern long double sinl (long double);
extern float cosf (float);
extern long double cosl (long double);
extern float tanf (float);
extern long double tanl (long double);
extern float asinf (float);
extern long double asinl (long double);
extern float acosf (float);
extern long double acosl (long double);
extern float atanf (float);
extern long double atanl (long double);
extern float atan2f (float, float);
extern long double atan2l (long double, long double);
/* 7.12.5 Hyperbolic functions: Double in C89 */
extern __inline__ float sinhf (float x)
{return (float) sinh (x);}
extern long double sinhl (long double);
extern __inline__ float coshf (float x)
{return (float) cosh (x);}
extern long double coshl (long double);
extern __inline__ float tanhf (float x)
{return (float) tanh (x);}
extern long double tanhl (long double);
/*
* TODO: asinh, acosh, atanh
*/
/* 7.12.6.1 Double in C89 */
extern __inline__ float expf (float x)
{return (float) exp (x);}
extern long double expl (long double);
/* 7.12.6.2 */
extern double exp2(double);
extern float exp2f(float);
extern long double exp2l(long double);
/* 7.12.6.3 The expm1 functions: TODO */
/* 7.12.6.4 Double in C89 */
extern __inline__ float frexpf (float x, int* expn)
{return (float) frexp (x, expn);}
extern long double frexpl (long double, int*);
/* 7.12.6.5 */
#define FP_ILOGB0 ((int)0x80000000)
#define FP_ILOGBNAN ((int)0x80000000)
extern int ilogb (double);
extern int ilogbf (float);
extern int ilogbl (long double);
/* 7.12.6.6 Double in C89 */
extern __inline__ float ldexpf (float x, int expn)
{return (float) ldexp (x, expn);}
extern long double ldexpl (long double, int);
/* 7.12.6.7 Double in C89 */
extern float logf (float);
extern long double logl (long double);
/* 7.12.6.8 Double in C89 */
extern float log10f (float);
extern long double log10l (long double);
/* 7.12.6.9 */
extern double log1p(double);
extern float log1pf(float);
extern long double log1pl(long double);
/* 7.12.6.10 */
extern double log2 (double);
extern float log2f (float);
extern long double log2l (long double);
/* 7.12.6.11 */
extern double logb (double);
extern float logbf (float);
extern long double logbl (long double);
extern __inline__ double logb (double x)
{
double res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
extern __inline__ float logbf (float x)
{
float res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
extern __inline__ long double logbl (long double x)
{
long double res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}
/* 7.12.6.12 Double in C89 */
extern float modff (float, float*);
extern long double modfl (long double, long double*);
/* 7.12.6.13 */
extern double scalbn (double, int);
extern float scalbnf (float, int);
extern long double scalbnl (long double, int);
extern double scalbln (double, long);
extern float scalblnf (float, long);
extern long double scalblnl (long double, long);
/* 7.12.7.1 */
/* Implementations adapted from Cephes versions */
extern double cbrt (double);
extern float cbrtf (float);
extern long double cbrtl (long double);
/* 7.12.7.2 The fabs functions: Double in C89 */
extern __inline__ float fabsf (float x)
{
float res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
extern __inline__ long double fabsl (long double x)
{
long double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}
/* 7.12.7.3 */
extern double hypot (double, double); /* in libmoldname.a */
extern __inline__ float hypotf (float x, float y)
{ return (float) _hypot (x, y);}
extern long double hypotl (long double, long double);
/* 7.12.7.4 The pow functions. Double in C89 */
extern __inline__ float powf (float x, float y)
{return (float) pow (x, y);}
extern long double powl (long double, long double);
/* 7.12.7.5 The sqrt functions. Double in C89. */
extern __inline__ float sqrtf (float x)
{
float res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
extern __inline__ long double sqrtl (long double x)
{
long double res;
asm ("fsqrt" : "=t" (res) : "0" (x));
return res;
}
/* 7.12.8 Error and gamma functions: TODO */
/* 7.12.9.1 Double in C89 */
extern float ceilf (float);
extern long double ceill (long double);
/* 7.12.9.2 Double in C89 */
extern float floorf (float);
extern long double floorl (long double);
/* 7.12.9.3 */
extern double nearbyint ( double);
extern float nearbyintf (float);
extern long double nearbyintl (long double);
/* 7.12.9.4 */
/* round, using fpu control word settings */
extern __inline__ double rint (double x)
{
double retval;
__asm__ ("frndint;": "=t" (retval) : "0" (x));
return retval;
}
extern __inline__ float rintf (float x)
{
float retval;
__asm__ ("frndint;" : "=t" (retval) : "0" (x) );
return retval;
}
extern __inline__ long double rintl (long double x)
{
long double retval;
__asm__ ("frndint;" : "=t" (retval) : "0" (x) );
return retval;
}
/* 7.12.9.5 */
extern __inline__ long lrint (double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
extern __inline__ long lrintf (float x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
extern __inline__ long lrintl (long double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
extern __inline__ long long llrint (double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
extern __inline__ long long llrintf (float x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
extern __inline__ long long llrintl (long double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}
/* 7.12.9.6 */
/* round away from zero, regardless of fpu control word settings */
extern double round (double);
extern float roundf (float);
extern long double roundl (long double);
/* 7.12.9.7 */
extern long lround (double);
extern long lroundf (float);
extern long lroundl (long double);
extern long long llround (double);
extern long long llroundf (float);
extern long long llroundl (long double);
/* 7.12.9.8 */
/* round towards zero, regardless of fpu control word settings */
extern double trunc (double);
extern float truncf (float);
extern long double truncl (long double);
/* 7.12.10.1 Double in C89 */
extern float fmodf (float, float);
extern long double fmodl (long double, long double);
/* 7.12.10.2 */
extern double remainder (double, double);
extern float remainderf (float, float);
extern long double remainderl (long double, long double);
/* 7.12.10.3 */
extern double remquo(double, double, int *);
extern float remquof(float, float, int *);
extern long double remquol(long double, long double, int *);
/* 7.12.11.1 */
extern double copysign (double, double); /* in libmoldname.a */
extern float copysignf (float, float);
extern long double copysignl (long double, long double);
/* 7.12.11.2 Return a NaN */
extern double nan(const char *tagp);
extern float nanf(const char *tagp);
extern long double nanl(const char *tagp);
#ifndef __STRICT_ANSI__
#define _nan() nan("")
#define _nanf() nanf("")
#define _nanl() nanl("")
#endif
/* 7.12.11.3 */
extern double nextafter (double, double); /* in libmoldname.a */
extern float nextafterf (float, float);
/* TODO: Not yet implemented */
/* extern long double nextafterl (long double, long double); */
/* 7.12.11.4 The nexttoward functions: TODO */
/* 7.12.12.1 */
/* x > y ? (x - y) : 0.0 */
extern double fdim (double x, double y);
extern float fdimf (float x, float y);
extern long double fdiml (long double x, long double y);
/* fmax and fmin.
NaN arguments are treated as missing data: if one argument is a NaN
and the other numeric, then these functions choose the numeric
value. */
/* 7.12.12.2 */
extern double fmax (double, double);
extern float fmaxf (float, float);
extern long double fmaxl (long double, long double);
/* 7.12.12.3 */
extern double fmin (double, double);
extern float fminf (float, float);
extern long double fminl (long double, long double);
/* 7.12.13.1 */
/* return x * y + z as a ternary op */
extern double fma (double, double, double);
extern float fmaf (float, float, float);
extern long double fmal (long double, long double, long double);
/* 7.12.14 */
/* /*
* With these functions, comparisons involving quiet NaNs set the FP * With these functions, comparisons involving quiet NaNs set the FP
* condition code to "unordered". The IEEE floating-point spec * condition code to "unordered". The IEEE floating-point spec
* dictates that the result of floating-point comparisons should be * dictates that the result of floating-point comparisons should be
* false whenever a NaN is involved, with the exception of the !=, * false whenever a NaN is involved, with the exception of the != op,
* which always returns true: yes, (NaN != NaN) is true). * which always returns true: yes, (NaN != NaN) is true).
*/ */
@ -377,109 +735,15 @@ __fp_unordered_compare (long double x, long double y){
#endif #endif
/* round, using fpu control word settings */
extern __inline__ double rint (double x)
{
double retval;
__asm__ ("frndint;": "=t" (retval) : "0" (x));
return retval;
}
extern __inline__ float rintf (float x)
{
float retval;
__asm__ ("frndint;" : "=t" (retval) : "0" (x) );
return retval;
}
extern __inline__ long double rintl (long double x)
{
long double retval;
__asm__ ("frndint;" : "=t" (retval) : "0" (x) );
return retval;
}
/* round away from zero, regardless of fpu control word settings */
extern double round (double);
extern float roundf (float);
extern long double roundl (long double);
/* round towards zero, regardless of fpu control word settings */
extern double trunc (double);
extern float truncf (float);
extern long double truncl (long double);
/* fmax and fmin.
NaN arguments are treated as missing data: if one argument is a NaN
and the other numeric, then these functions choose the numeric
value. */
extern double fmax (double, double);
extern float fmaxf (float, float);
extern long double fmaxl (long double, long double);
extern double fmin (double, double);
extern float fminf (float, float);
extern long double fminl (long double, long double);
/* return x * y + z as a ternary op */
extern double fma (double, double, double);
extern float fmaf (float, float, float);
extern long double fmal (long double, long double, long double);
/* x > y ? (x - y) : 0.0 */
extern double fdim (double, double);
extern float fdimf (float, float);
extern long double fdiml (long double, long double);
/* one lonely transcendental */
extern double log2 (double _x);
extern float log2f (float _x);
extern long double log2l (long double _x);
#endif /* __STDC_VERSION__ >= 199901L */ #endif /* __STDC_VERSION__ >= 199901L */
#endif /* __NO_ISOCEXT */
/* The underscored versions for double are in MSVCRT.dll.
The stubs for float and double versions are in libmingwex.a */
double copysign (double, double);
float copysignf (float, float);
long double copysignl (long double, long double);
double logb (double);
float logbf (float);
double nextafter (double, double);
float nextafterf (float, float);
double scalb (double, long);
float scalbf (float, long);
#if !defined (__STRICT_ANSI__) /* inline using non-ANSI functions */
extern __inline__ double copysign (double x, double y)
{ return _copysign(x, y); }
extern __inline__ float copysignf (float x, float y)
{ return _copysign(x, y); }
extern __inline__ double logb (double x)
{ return _logb(x); }
extern __inline__ float logbf (float x)
{ return _logb(x); }
extern __inline__ double nextafter(double x, double y)
{ return _nextafter(x, y); }
extern __inline__ float nextafterf(float x, float y)
{ return _nextafter(x, y); }
extern __inline__ double scalb (double x, long i)
{ return _scalb (x, i); }
extern __inline__ float scalbf (float x, long i)
{ return _scalb(x, i); }
#endif /* (__STRICT_ANSI__) */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* Not RC_INVOKED */ #endif /* Not RC_INVOKED */
#endif /* __NO_ISOCEXT */
#endif /* Not _MATH_H_ */ #endif /* Not _MATH_H_ */

View File

@ -3,8 +3,8 @@
# #
# This makefile requires GNU make. # This makefile requires GNU make.
VPATH = @srcdir@
srcdir = @srcdir@ srcdir = @srcdir@
VPATH = $(srcdir):$(srcdir)/math
objdir = . objdir = .
target_alias = @target_alias@ target_alias = @target_alias@
@ -26,85 +26,36 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
mkinstalldirs = $(SHELL) $(srcdir)/../mkinstalldirs mkinstalldirs = $(SHELL) $(srcdir)/../mkinstalldirs
DISTFILES = Makefile.in configure configure.in \ DISTFILES = Makefile.in configure configure.in \
mingw-fseek.c \ _Exit.c atoll.c dirent.c feclearexcept.c fegetenv.c \
_Exit.c \ fegetexceptflag.c fegetround.c feholdexcept.c feraiseexcept.c \
atoll.c \ fesetenv.c fesetexceptflag.c fesetround.c fetestexcept.c \
copysignl.S \ feupdateenv.c fwide.c imaxabs.c imaxdiv.c lltoa.c lltow.c \
dirent.c \ mbsinit.c mingw-fseek.c sitest.c snprintf.c snwprintf.c \
fdim.c \ strtof.c strtoimax.c strtoumax.c testwmem.c ulltoa.c ulltow.c \
fdimf.c \ vsnprintf.c vsnwprintf.c wcstof.c wcstoimax.c wcstoumax.c \
fdiml.c \ wdirent.c wmemchr.c wmemcmp.c wmemcpy.c wmemmove.c wmemset.c \
feclearexcept.c \
fegetenv.c \
fegetexceptflag.c \
fegetround.c \
feholdexcept.c \
feraiseexcept.c \
fesetenv.c \
fesetround.c \
fetestexcept.c \
fesetexceptflag.c \
feupdateenv.c \
fma.S \
fmaf.S \
fmal.c \
fmax.c \
fmaxf.c \
fmaxl.c \
fmin.c \
fminf.c \
fminl.c \
fp_consts.c \
fpclassify.c \
fpclassifyf.c \
fpclassifyl.c \
fucom.c \
fwide.c \
imaxabs.c \
imaxdiv.c \
isnan.c \
isnanf.c \
isnanl.c \
lltoa.c \
lltow.c \
log2.c \
log2f.c \
log2l.c \
math_stubs.c \
mbsinit.c \
rint.c \
rintf.c \
rintl.c \
round.c \
roundf.c \
roundl.c \
signbit.c \
signbitf.c \
signbitl.c \
sitest.c \
snprintf.c \
snwprintf.c \
strtof.c \
strtoimax.c \
strtoumax.c \
testwmem.c \
trunc.c \
truncf.c \
truncl.c \
ulltoa.c \
ulltow.c \
vsnprintf.c \
vsnwprintf.c \
wcstof.c \
wcstoimax.c \
wcstoumax.c \
wdirent.c \
wmemchr.c \
wmemcmp.c \
wmemcpy.c \
wmemmove.c \
wmemset.c \
wtoll.c wtoll.c
MATH_DISTFILES = \
acosf.c acosl.c asinf.c asinl.c atan2f.c atan2l.c \
atanf.c atanl.c cbrt.c cbrtf.c cbrtl.c ceilf.S ceill.S cephes_mconf.h \
copysign.S copysignf.S copysignl.S cosf.S coshf.c coshl.c cosl.S \
exp2.S exp2f.S exp2l.S expf.c expl.c fabs.c fabsf.c fabsl.c \
fdim.c fdimf.c fdiml.c floorf.S floorl.S fma.S fmaf.S fmal.c \
fmax.c fmaxf.c fmaxl.c fmin.c fminf.c fminl.c fmodf.c \
fmodl.c fp_consts.c fp_consts.h fp_constsf.c fp_constsl.c \
fpclassify.c fpclassifyf.c fpclassifyl.c \
frexpf.c frexpl.S fucom.c hypotf.c hypotl.c ilogb.S ilogbf.S \
ilogbl.S isnan.c isnanf.c isnanl.c ldexpf.c ldexpl.c llrint.c \
llrintf.c llrintl.c llround.c llroundf.c llroundl.c \
log10f.S log10l.S log1p.S log1pf.S log1pl.S log2.S log2f.S \
log2l.S logb.c logbf.c logbl.c logf.S logl.S lrint.c lrintf.c \
lrintl.c lround.c lroundf.c lroundl.c modff.c modfl.c \
nearbyint.S nearbyintf.S nearbyintl.S nextafterf.c powf.c powil.c \
powl.c remainder.S remainderf.S remainderl.S remquo.S \
remquof.S remquol.S rint.c rintf.c rintl.c round.c roundf.c \
roundl.c scalbn.S scalbnf.S scalbnl.S signbit.c signbitf.c \
signbitl.c sinf.S sinhf.c sinhl.c sinl.S sqrtf.c sqrtl.c \
tanf.S tanhf.c tanhl.c tanl.S trunc.c truncf.c truncl.c
CC = @CC@ CC = @CC@
# FIXME: Which is it, CC or CC_FOR_TARGET? # FIXME: Which is it, CC or CC_FOR_TARGET?
@ -150,22 +101,26 @@ STDLIB_STUB_OBJS = \
STDIO_STUB_OBJS = \ STDIO_STUB_OBJS = \
snprintf.o vsnprintf.o snwprintf.o vsnwprintf.o snprintf.o vsnprintf.o snwprintf.o vsnwprintf.o
MATH_OBJS = \ MATH_OBJS = \
acosf.o acosl.o asinf.o asinl.o atan2f.o atan2l.o \
atanf.o atanl.o cbrt.o cbrtf.o cbrtl.o ceilf.o ceill.o \
copysign.o copysignf.o copysignl.o cosf.o coshf.o coshl.o cosl.o \
exp2.o exp2f.o exp2l.o expf.o expl.o fabs.o fabsf.o fabsl.o \
fdim.o fdimf.o fdiml.o floorf.o floorl.o fma.o fmaf.o fmal.o \
fmax.o fmaxf.o fmaxl.o fmin.o fminf.o fminl.o fmodf.o \
fmodl.o fp_consts.o fp_constsf.o fp_constsl.o \
fpclassify.o fpclassifyf.o fpclassifyl.o \ fpclassify.o fpclassifyf.o fpclassifyl.o \
fucom.o \ frexpf.o frexpl.o fucom.o hypotf.o hypotl.o ilogb.o ilogbf.o \
round.o roundf.o roundl.o \ ilogbl.o isnan.o isnanf.o isnanl.o ldexpf.o ldexpl.o llrint.o \
rint.o rintf.o rintl.o \ llrintf.o llrintl.o llround.o llroundf.o llroundl.o \
signbit.o signbitf.o signbitl.o \ log10f.o log10l.o log1p.o log1pf.o log1pl.o log2.o log2f.o \
trunc.o truncf.o truncl.o \ log2l.o logb.o logbf.o logbl.o logf.o logl.o lrint.o lrintf.o \
isnan.o isnanf.o isnanl.o \ lrintl.o lround.o lroundf.o lroundl.o modff.o modfl.o \
fp_consts.o \ nearbyint.o nearbyintf.o nearbyintl.o nextafterf.o powf.o powil.o \
fdim.o fdimf.o fdiml.o \ powl.o remainder.o remainderf.o remainderl.o remquo.o \
fmax.o fmaxf.o fmaxl.o \ remquof.o remquol.o rint.o rintf.o rintl.o round.o roundf.o \
fmin.o fminf.o fminl.o \ roundl.o scalbn.o scalbnf.o scalbnl.o signbit.o signbitf.o \
fma.o fmaf.o fmal.o \ signbitl.o sinf.o sinhf.o sinhl.o sinl.o sqrtf.o sqrtl.o \
log2.o log2f.o log2l.o \ tanf.o tanhf.o tanhl.o tanl.o trunc.o truncf.o truncl.o
copysignl.o
MATH_STUB_OBJS = \
math_stubs.o
FENV_OBJS = fesetround.o fegetround.o \ FENV_OBJS = fesetround.o fegetround.o \
fegetenv.o fesetenv.o feupdateenv.o \ fegetenv.o fesetenv.o feupdateenv.o \
feclearexcept.o feholdexcept.o fegetexceptflag.o \ feclearexcept.o feholdexcept.o fegetexceptflag.o \
@ -176,7 +131,7 @@ REPLACE_OBJS = \
mingw-fseek.o mingw-fseek.o
LIB_OBJS = $(Q8_OBJS) $(STDLIB_STUB_OBJS) $(STDIO_STUB_OBJS) \ LIB_OBJS = $(Q8_OBJS) $(STDLIB_STUB_OBJS) $(STDIO_STUB_OBJS) \
$(MATH_OBJS) $(MATH_STUB_OBJS) $(FENV_OBJS) $(POSIX_OBJS) \ $(MATH_OBJS) $(FENV_OBJS) $(POSIX_OBJS) \
$(REPLACE_OBJS) $(REPLACE_OBJS)
LIBS = $(LIBMINGWEX_A) LIBS = $(LIBMINGWEX_A)
@ -185,6 +140,7 @@ DLLS =
all: $(LIBMINGWEX_A) all: $(LIBMINGWEX_A)
$(LIBMINGWEX_A): $(LIB_OBJS) $(LIBMINGWEX_A): $(LIB_OBJS)
rm -f $(LIBMINGWEX_A)
$(AR) $(ARFLAGS) $@ $(LIB_OBJS) $(AR) $(ARFLAGS) $@ $(LIB_OBJS)
$(RANLIB) $@ $(RANLIB) $@
@ -234,3 +190,9 @@ dist:
@for i in $(DISTFILES); do\ @for i in $(DISTFILES); do\
cp -p $(srcdir)/$$i $(distdir)/mingwex/$$i ; \ cp -p $(srcdir)/$$i $(distdir)/mingwex/$$i ; \
done done
mkdir $(distdir)/mingwex/math
chmod 755 $(distdir)//mingwex/math
@for i in $(MATH_DISTFILES); do\
cp -p $(srcdir)/math/$$i $(distdir)/mingwex/math/$$i ; \
done

View File

@ -1,4 +0,0 @@
long double
fmal ( long double _x, long double _y, long double _z){
return ((_x * _y) + _z);
}

View File

@ -1,81 +0,0 @@
/* Floating point consts needed by STL class mumeric_limits<float>
and numeric_limits<double>. Also used as return values by nan, inf */
#include <math.h>
/*
According to IEEE 754 a QNaN has exponent bits of all 1 values and
initial significand bit of 1. A SNaN has has an exponent of all 1
values and initial significand bit of 0 (with one or more other
significand bits of 1). An Inf has significand of 0 and
exponent of all 1 values. A denormal value has all exponent bits of 0.
The following does _not_ follow those rules, but uses values
equal to those exported from MS C++ runtime lib, msvcprt.dll
for float and double. MSVC however, does not have long doubles.
*/
#define __DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 }
#define __DOUBLE_QNAN_REP { 0, 0, 0, 0xfff8 } /* { 0, 0, 0, 0x7ff8 } */
#define __DOUBLE_SNAN_REP { 0, 0, 0, 0xfff0 } /* { 1, 0, 0, 0x7ff0 } */
#define __DOUBLE_DENORM_REP {1, 0, 0, 0}
#define D_NAN_MASK 0x7ff0000000000000LL /* this will mask NaN's and Inf's */
#define __FLOAT_INF_REP { 0, 0x7f80 }
#define __FLOAT_QNAN_REP { 0, 0xffc0 } /* { 0, 0x7fc0 } */
#define __FLOAT_SNAN_REP { 0, 0xff80 } /* { 1, 0x7f80 } */
#define __FLOAT_DENORM_REP {1,0}
#define F_NAN_MASK 0x7f800000
/* This assumes no implicit (hidden) bit in extended mode */
#define __LONG_DOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff }
#define __LONG_DOUBLE_QNAN_REP { 0, 0, 0, 0xc000, 0xffff }
#define __LONG_DOUBLE_SNAN_REP { 0, 0, 0, 0x8000, 0xffff }
#define __LONG_DOUBLE_DENORM_REP {1, 0, 0, 0, 0}
union _ieee_rep
{
unsigned short rep[5];
float float_val;
double double_val;
long double ldouble_val;
} ;
const union _ieee_rep __QNAN = { __DOUBLE_QNAN_REP };
/*
const union _ieee_rep __SNAN = { __DOUBLE_SNAN_REP };
const union _ieee_rep __INF = { __DOUBLE_INF_REP };
const union _ieee_rep __DENORM = { __DOUBLE_DENORM_REP };
*/
/* ISO C99 */
#undef nan
/* FIXME */
double nan (const char * tagp __attribute__((unused)) )
{ return __QNAN.double_val; }
const union _ieee_rep __QNANF = { __FLOAT_QNAN_REP };
/*
const union _ieee_rep __SNANF = { __FLOAT_SNAN_REP };
const union _ieee_rep __INFF = { __FLOAT_INF_REP };
const union _ieee_rep __DENORMF = { __FLOAT_DENORM_REP };
*/
#undef nanf
/* FIXME */
float nanf(const char * tagp __attribute__((unused)) )
{ return __QNANF.float_val;}
const union _ieee_rep __QNANL = { __LONG_DOUBLE_QNAN_REP };
/*
const union _ieee_rep __SNANL = { __LONG_DOUBLE_SNAN_REP };
const union _ieee_rep __INFL = { __LONG_DOUBLE_INF_REP };
const union _ieee_rep __DENORML = { __LONG_DOUBLE_DENORM_REP };
*/
#undef nanl
/* FIXME */
long double nanl (const char * tagp __attribute__((unused)) )
{ return __QNANL.ldouble_val;}

View File

@ -1,8 +0,0 @@
#include <math.h>
double
log2 (double _x)
{
double retval;
__asm__ ("fyl2x;" : "=t" (retval) : "0" (_x), "u" (1.0L) : "st(1)");
return retval;
}

View File

@ -1,8 +0,0 @@
#include <math.h>
float
log2f (float _x)
{
float retval;
__asm__ ("fyl2x;" : "=t" (retval) : "0" (_x), "u" (1.0L) : "st(1)");
return retval;
}

View File

@ -1,8 +0,0 @@
#include <math.h>
long double
log2l (long double _x)
{
long double retval;
__asm__ ("fyl2x;" : "=t" (retval) : "0" (_x), "u" (1.0L) : "st(1)");
return retval;
}

View File

@ -0,0 +1,23 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
#include <math.h>
float
acosf (float x)
{
float res;
/* acosl = atanl (sqrtl(1 - x^2) / x) */
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrtl (1 - x^2) */
"fxch %%st(1)\n\t"
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,25 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
acosl (long double x)
{
long double res;
/* acosl = atanl (sqrtl(1 - x^2) / x) */
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrtl (1 - x^2) */
"fxch %%st(1)\n\t"
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,20 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
/* asin = atan (x / sqrt(1 - x^2)) */
float asinf (float x)
{
float res;
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrt (1 - x^2) */
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,21 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for long double type by Danny Smith <dannysmith@users.sourceforge.net>.
*/
/* asin = atan (x / sqrt(1 - x^2)) */
long double asinl (long double x)
{
long double res;
asm ( "fld %%st\n\t"
"fmul %%st(0)\n\t" /* x^2 */
"fld1\n\t"
"fsubp\n\t" /* 1 - x^2 */
"fsqrt\n\t" /* sqrt (1 - x^2) */
"fpatan"
: "=t" (res) : "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,15 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
*/
#include <math.h>
float
atan2f (float y, float x)
{
float res;
asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,16 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
atan2l (long double y, long double x)
{
long double res;
asm ("fpatan" : "=t" (res) : "u" (y), "0" (x) : "st(1)");
return res;
}

View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
*/
#include <math.h>
float
atanf (float x)
{
float res;
asm ("fld1\n\t"
"fpatan" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
atanl (long double x)
{
long double res;
asm ("fld1\n\t"
"fpatan"
: "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,162 @@
/* cbrt.c
*
* Cube root
*
*
*
* SYNOPSIS:
*
* double x, y, cbrt();
*
* y = cbrt( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used three times to converge to an accurate
* result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* DEC -10,10 200000 1.8e-17 6.2e-18
* IEEE 0,1e308 30000 1.5e-16 5.0e-17
*
*/
/* cbrt.c */
/*
Cephes Math Library Release 2.2: January, 1991
Copyright 1984, 1991 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include <math.h>
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const double CBRT2 = 1.2599210498948731647672;
static const double CBRT4 = 1.5874010519681994747517;
static const double CBRT2I = 0.79370052598409973737585;
static const double CBRT4I = 0.62996052494743658238361;
#ifndef __MINGW32__
#ifdef ANSIPROT
extern double frexp ( double, int * );
extern double ldexp ( double, int );
extern int isnan ( double );
extern int isfinite ( double );
#else
double frexp(), ldexp();
int isnan(), isfinite();
#endif
#endif
double cbrt(x)
double x;
{
int e, rem, sign;
double z;
#ifdef __MINGW32__
if (!isfinite (x) || x == 0 )
return x;
#else
#ifdef NANS
if( isnan(x) )
return x;
#endif
#ifdef INFINITIES
if( !isfinite(x) )
return x;
#endif
if( x == 0 )
return( x );
#endif /* __MINGW32__ */
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexp( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 9.2e-6
*/
x = (((-1.3466110473359520655053e-1 * x
+ 5.4664601366395524503440e-1) * x
- 9.5438224771509446525043e-1) * x
+ 1.1399983354717293273738e0 ) * x
+ 4.0238979564544752126924e-1;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
/* argument less than 1 */
else
{
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2I;
else if( rem == 2 )
x *= CBRT4I;
e = -e;
}
/* multiply by power of 2 */
x = ldexp( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) )*0.33333333333333333333;
#ifdef DEC
x -= ( x - (z/(x*x)) )/3.0;
#else
x -= ( x - (z/(x*x)) )*0.33333333333333333333;
#endif
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,147 @@
/* cbrtf.c
*
* Cube root
*
*
*
* SYNOPSIS:
*
* float x, y, cbrtf();
*
* y = cbrtf( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used to converge to an accurate result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE 0,1e38 100000 7.6e-8 2.7e-8
*
*/
/* cbrt.c */
/*
Cephes Math Library Release 2.2: June, 1992
Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include <math.h>
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const float CBRT2 = 1.25992104989487316477;
static const float CBRT4 = 1.58740105196819947475;
#ifndef __MINGW32__
#ifdef ANSIC
float frexpf(float, int *), ldexpf(float, int);
float cbrtf( float xx )
#else
float frexpf(), ldexpf();
float cbrtf(xx)
double xx;
#endif
{
int e, rem, sign;
float x, z;
x = xx;
#else /* __MINGW32__ */
float cbrtf (float x)
{
int e, rem, sign;
float z;
#endif /* __MINGW32__ */
#ifdef __MINGW32__
if (!isfinite (x) || x == 0.0F )
return x;
#else
if( x == 0 )
return( 0.0 );
#endif
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexpf( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 9.2e-6
*/
x = (((-0.13466110473359520655053 * x
+ 0.54664601366395524503440 ) * x
- 0.95438224771509446525043 ) * x
+ 1.1399983354717293273738 ) * x
+ 0.40238979564544752126924;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
/* argument less than 1 */
else
{
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x /= CBRT2;
else if( rem == 2 )
x /= CBRT4;
e = -e;
}
/* multiply by power of 2 */
x = ldexpf( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) ) * 0.333333333333;
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,161 @@
/* cbrtl.c
*
* Cube root, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, cbrtl();
*
* y = cbrtl( x );
*
*
*
* DESCRIPTION:
*
* Returns the cube root of the argument, which may be negative.
*
* Range reduction involves determining the power of 2 of
* the argument. A polynomial of degree 2 applied to the
* mantissa, and multiplication by the cube root of 1, 2, or 4
* approximates the root to within about 0.1%. Then Newton's
* iteration is used three times to converge to an accurate
* result.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE .125,8 80000 7.0e-20 2.2e-20
* IEEE exp(+-707) 100000 7.0e-20 2.4e-20
*
*/
/*
Cephes Math Library Release 2.2: January, 1991
Copyright 1984, 1991 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/*
Modified for mingwex.a
2002-07-01 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
static const long double CBRT2 = 1.2599210498948731647672L;
static const long double CBRT4 = 1.5874010519681994747517L;
static const long double CBRT2I = 0.79370052598409973737585L;
static const long double CBRT4I = 0.62996052494743658238361L;
#ifndef __MINGW32__
#ifdef ANSIPROT
extern long double frexpl ( long double, int * );
extern long double ldexpl ( long double, int );
extern int isnanl ( long double );
#else
long double frexpl(), ldexpl();
extern int isnanl();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#endif /* __MINGW32__ */
long double cbrtl(x)
long double x;
{
int e, rem, sign;
long double z;
#ifdef __MINGW32__
if (!isfinite (x) || x == 0.0L)
return(x);
#else
#ifdef NANS
if(isnanl(x))
return(x);
#endif
#ifdef INFINITIES
if( x == INFINITYL)
return(x);
if( x == -INFINITYL)
return(x);
#endif
if( x == 0 )
return( x );
#endif /* __MINGW32__ */
if( x > 0 )
sign = 1;
else
{
sign = -1;
x = -x;
}
z = x;
/* extract power of 2, leaving
* mantissa between 0.5 and 1
*/
x = frexpl( x, &e );
/* Approximate cube root of number between .5 and 1,
* peak relative error = 1.2e-6
*/
x = (((( 1.3584464340920900529734e-1L * x
- 6.3986917220457538402318e-1L) * x
+ 1.2875551670318751538055e0L) * x
- 1.4897083391357284957891e0L) * x
+ 1.3304961236013647092521e0L) * x
+ 3.7568280825958912391243e-1L;
/* exponent divided by 3 */
if( e >= 0 )
{
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2;
else if( rem == 2 )
x *= CBRT4;
}
else
{ /* argument less than 1 */
e = -e;
rem = e;
e /= 3;
rem -= 3*e;
if( rem == 1 )
x *= CBRT2I;
else if( rem == 2 )
x *= CBRT4I;
e = -e;
}
/* multiply by power of 2 */
x = ldexpl( x, e );
/* Newton iteration */
x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
x -= ( x - (z/(x*x)) )*0.3333333333333333333333L;
if( sign < 0 )
x = -x;
return(x);
}

View File

@ -0,0 +1,31 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "ceilf.S"
.text
.align 4
.globl _ceilf
.def _ceilf; .scl 2; .type 32; .endef
_ceilf:
flds 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*/
.file "ceill.S"
.text
.align 4
.globl _ceill
.def _ceill; .scl 2; .type 32; .endef
_ceill:
fldt 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x0800,%edx /* round towards +oo */
orl 4(%esp),%edx
andl $0xfbff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,134 @@
#include <math.h>
#include <errno.h>
/* constants used by cephes functions */
#define MAXNUML 1.189731495357231765021263853E4932L
#define MAXLOGL 1.1356523406294143949492E4L
#define MINLOGL -1.13994985314888605586758E4L
#define LOGE2L 6.9314718055994530941723E-1L
#define LOG2EL 1.4426950408889634073599E0L
#define PIL 3.1415926535897932384626L
#define PIO2L 1.5707963267948966192313L
#define PIO4L 7.8539816339744830961566E-1L
#define isfinitel isfinite
#define isinfl isinf
#define isnanl isnan
#define signbitl signbit
#define IBMPC 1
#define ANSIPROT 1
#define MINUSZERO 1
#define INFINITIES 1
#define NANS 1
#define DENORMAL 1
#define NEGZEROL (-0.0L)
extern long double __INFL;
#define INFINITYL (__INFL)
extern long double __QNANL;
#define NANL (__QNANL)
#define VOLATILE
#define mtherr(fname, code)
#define XPD 0,
#ifdef _CEPHES_USE_ERRNO
#define _SET_ERRNO(x) errno = (x)
#else
#define _SET_ERRNO(x)
#endif
/*
Cephes Math Library Release 2.2: July, 1992
Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
/* polevll.c
* p1evll.c
*
* Evaluate polynomial
*
*
*
* SYNOPSIS:
*
* int N;
* long double x, y, coef[N+1], polevl[];
*
* y = polevll( x, coef, N );
*
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evll() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevll().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
/* Polynomial evaluator:
* P[0] x^n + P[1] x^(n-1) + ... + P[n]
*/
static __inline__ long double polevll( x, p, n )
long double x;
const void *p;
int n;
{
register long double y;
register long double *P = (long double *)p;
y = *P++;
do
{
y = y * x + *P++;
}
while( --n );
return(y);
}
/* Polynomial evaluator:
* x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
*/
static __inline__ long double p1evll( x, p, n )
long double x;
const void *p;
int n;
{
register long double y;
register long double *P = (long double *)p;
n -= 1;
y = x + *P++;
do
{
y = y * x + *P++;
}
while( --n );
return( y );
}

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "copysign.S"
.text
.align 4
.globl _copysign
.def _copysign; .scl 2; .type 32; .endef
_copysign:
movl 16(%esp),%edx
movl 8(%esp),%eax
andl $0x80000000,%edx
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,8(%esp)
fldl 4(%esp)
ret

View File

@ -0,0 +1,19 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "copysignf.S"
.text
.align 4
.globl _copysignf
.def _copysignf; .scl 2; .type 32; .endef
_copysignf:
movl 8(%esp),%edx
movl 4(%esp),%eax
andl $0x80000000,%edx
andl $0x7fffffff,%eax
orl %edx,%eax
movl %eax,4(%esp)
flds 4(%esp)
ret

View File

@ -6,8 +6,7 @@
.file "copysignl.S" .file "copysignl.S"
.text .text
.align 2 .align 4
.p2align 4,,15
.globl _copysignl .globl _copysignl
.def _copysignl; .scl 2; .type 32; .endef .def _copysignl; .scl 2; .type 32; .endef
_copysignl: _copysignl:

View File

@ -0,0 +1,29 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Removed glibc header dependancy by Danny Smith
* <dannysmith@users.sourceforge.net>
*/
.file "cosf.S"
.text
.align 4
.globl _cosl
.def _cosf; .scl 2; .type 32; .endef
_cosf:
flds 4(%esp)
fcos
fnstsw %ax
testl $0x400,%eax
jnz 1f
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fcos
ret

View File

@ -0,0 +1,3 @@
#include <math.h>
float coshf (float x)
{return (float) cosh (x);}

View File

@ -0,0 +1,110 @@
/* coshl.c
*
* Hyperbolic cosine, long double precision
*
*
*
* SYNOPSIS:
*
* long double x, y, coshl();
*
* y = coshl( x );
*
*
*
* DESCRIPTION:
*
* Returns hyperbolic cosine of argument in the range MINLOGL to
* MAXLOGL.
*
* cosh(x) = ( exp(x) + exp(-x) )/2.
*
*
*
* ACCURACY:
*
* Relative error:
* arithmetic domain # trials peak rms
* IEEE +-10000 30000 1.1e-19 2.8e-20
*
*
* ERROR MESSAGES:
*
* message condition value returned
* cosh overflow |x| > MAXLOGL+LOGE2L INFINITYL
*
*
*/
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1985, 1991, 1998 by Stephen L. Moshier
*/
/*
Modified for mingw
2002-07-22 Danny Smith <dannysmith@users.sourceforge.net>
*/
#ifdef __MINGW32__
#include "cephes_mconf.h"
#else
#include "mconf.h"
#endif
#ifndef _SET_ERRNO
#define _SET_ERRNO(x)
#endif
#ifndef __MINGW32__
extern long double MAXLOGL, MAXNUML, LOGE2L;
#ifdef ANSIPROT
extern long double expl ( long double );
extern int isnanl ( long double );
#else
long double expl(), isnanl();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
#endif /* __MINGW32__ */
long double coshl(x)
long double x;
{
long double y;
#ifdef NANS
if( isnanl(x) )
{
_SET_ERRNO(EDOM);
return(x);
}
#endif
if( x < 0 )
x = -x;
if( x > (MAXLOGL + LOGE2L) )
{
mtherr( "coshl", OVERFLOW );
_SET_ERRNO(ERANGE);
#ifdef INFINITIES
return( INFINITYL );
#else
return( MAXNUML );
#endif
}
if( x >= (MAXLOGL - LOGE2L) )
{
y = expl(0.5L * x);
y = (0.5L * y) * y;
return(y);
}
y = expl(x);
y = 0.5L * (y + 1.0L / y);
return( y );
}

View File

@ -0,0 +1,30 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
* Removed glibc header dependancy by Danny Smith
* <dannysmith@users.sourceforge.net>
*/
.file "cosl.S"
.text
.align 4
.globl _cosl
.def _cosl; .scl 2; .type 32; .endef
_cosl:
fldt 4(%esp)
fcos
fnstsw %ax
testl $0x400,%eax
jnz 1f
ret
1: fldpi
fadd %st(0)
fxch %st(1)
2: fprem1
fnstsw %ax
testl $0x400,%eax
jnz 2b
fstp %st(1)
fcos
ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2.S"
.text
.align 4
.globl _exp2
.def _exp2; .scl 2; .type 32; .endef
_exp2:
fldl 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2f.S"
.text
.align 4
.globl _exp2f
.def _exp2f; .scl 2; .type 32; .endef
_exp2f:
flds 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for exp2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*/
.file "exp2l.S"
.text
.align 4
.globl _exp2l
.def _exp2l; .scl 2; .type 32; .endef
_exp2l:
fldt 4(%esp)
/* I added the following ugly construct because exp(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fld %st
frndint /* int(x) */
fsubr %st,%st(1) /* fract(x) */
fxch
f2xm1 /* 2^(fract(x)) - 1 */
fld1
faddp /* 2^(fract(x)) */
fscale /* e^x */
fstp %st(1)
ret
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2: ret

View File

@ -0,0 +1,3 @@
#include <math.h>
float expf (float x)
{return (float) exp (x);}

View File

@ -0,0 +1,77 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
/*
* The 8087 method for the exponential function is to calculate
* exp(x) = 2^(x log2(e))
* after separating integer and fractional parts
* x log2(e) = i + f, |f| <= .5
* 2^i is immediate but f needs to be precise for long double accuracy.
* Suppress range reduction error in computing f by the following.
* Separate x into integer and fractional parts
* x = xi + xf, |xf| <= .5
* Separate log2(e) into the sum of an exact number c0 and small part c1.
* c0 + c1 = log2(e) to extra precision
* Then
* f = (c0 xi - i) + c0 xf + c1 x
* where c0 xi is exact and so also is (c0 xi - i).
* -- moshier@na-net.ornl.gov
*/
#include <math.h>
static long double c0 = 1.44268798828125L;
static long double c1 = 7.05260771340735992468e-6L;
long double
expl (long double x)
{
long double res;
/* I added the following ugly construct because expl(+-Inf) resulted
in NaN. The ugliness results from the bright minds at Intel.
For the i686 the code can be written better.
-- drepper@cygnus.com. */
asm ("fxam\n\t" /* Is NaN or +-Inf? */
"fstsw %%ax\n\t"
"movb $0x45, %%dh\n\t"
"andb %%ah, %%dh\n\t"
"cmpb $0x05, %%dh\n\t"
"je 1f\n\t" /* Is +-Inf, jump. */
"fldl2e\n\t" /* 1 log2(e) */
"fmul %%st(1),%%st\n\t" /* 1 x log2(e) */
"frndint\n\t" /* 1 i */
"fld %%st(1)\n\t" /* 2 x */
"frndint\n\t" /* 2 xi */
"fld %%st(1)\n\t" /* 3 i */
"fldt %2\n\t" /* 4 c0 */
"fld %%st(2)\n\t" /* 5 xi */
"fmul %%st(1),%%st\n\t" /* 5 c0 xi */
"fsubp %%st,%%st(2)\n\t" /* 4 f = c0 xi - i */
"fld %%st(4)\n\t" /* 5 x */
"fsub %%st(3),%%st\n\t" /* 5 xf = x - xi */
"fmulp %%st,%%st(1)\n\t" /* 4 c0 xf */
"faddp %%st,%%st(1)\n\t" /* 3 f = f + c0 xf */
"fldt %3\n\t" /* 4 */
"fmul %%st(4),%%st\n\t" /* 4 c1 * x */
"faddp %%st,%%st(1)\n\t" /* 3 f = f + c1 * x */
"f2xm1\n\t" /* 3 2^(fract(x * log2(e))) - 1 */
"fld1\n\t" /* 4 1.0 */
"faddp\n\t" /* 3 2^(fract(x * log2(e))) */
"fstp %%st(1)\n\t" /* 2 */
"fscale\n\t" /* 2 scale factor is st(1); e^x */
"fstp %%st(1)\n\t" /* 1 */
"fstp %%st(1)\n\t" /* 0 */
"jmp 2f\n\t"
"1:\ttestl $0x200, %%eax\n\t" /* Test sign. */
"jz 2f\n\t" /* If positive, jump. */
"fstp %%st\n\t"
"fldz\n\t" /* Set result to 0. */
"2:\t\n"
: "=t" (res) : "0" (x), "m" (c0), "m" (c1) : "ax", "dx");
return res;
}

View File

@ -0,0 +1,10 @@
#include <math.h>
double
fabs (double x)
{
double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
float
fabsf (float x)
{
float res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
long double
fabsl (long double x)
{
long double res;
asm ("fabs;" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1 @@
cvs -z9 add acosf.c acosl.c asinf.c asinl.c atan2f.c atan2l.c atanf.c atanl.c cbrt.c cbrtf.c cbrtl.c ceilf.S ceill.S cephes_mconf.h copysign.S copysignf.S copysignl.S cosf.S coshf.c coshl.c cosl.S exp2.S exp2f.S exp2l.S expf.c expl.c fabs.c fabsf.c fabsl.c fdim.c fdimf.c fdiml.c files.txt floorf.S floorl.S fma.S fmaf.S fmal.c fmax.c fmaxf.c fmaxl.c fmin.c fminf.c fminl.c fmodf.c fmodl.c fp_consts.c fp_consts.h fp_constsf.c fp_constsl.c fpclassify.c fpclassifyf.c fpclassifyl.c frexpf.c frexpl.S fucom.c hypotf.c hypotl.c ilogb.S ilogbf.S ilogbl.S isnan.c isnanf.c isnanl.c ldexpf.c ldexpl.c llrint.c llrintf.c llrintl.c llround.c llroundf.c llroundl.c log10f.S log10l.S log1p.S log1pf.S log1pl.S log2.S log2f.S log2l.S logb.c logbf.c logbl.c logf.S logl.S lrint.c lrintf.c lrintl.c lround.c lroundf.c lroundl.c modff.c modfl.c nearbyint.S nearbyintf.S nearbyintl.S nextafterf.c powf.c powil.c powl.c remainder.S remainderf.S remainderl.S remquo.S remquof.S remquol.S rint.c rintf.c rintl.c round.c roundf.c roundl.c scalbn.S scalbnf.S scalbnl.S signbit.c signbitf.c signbitl.c sinf.S sinhf.c sinhl.c sinl.S sqrtf.c sqrtl.c tanf.S tanhf.c tanhl.c tanl.S trunc.c truncf.c truncl.c

View File

@ -0,0 +1,35 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "floorf.S"
.text
.align 4
.globl _floorf
.def _floorf; .scl 2; .type 32; .endef
_floorf:
flds 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
orl 4(%esp),%edx
andl $0xf7ff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,33 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
*
*/
.file "floorl.S"
.text
.align 4
.globl _floorl
.def _floorl; .scl 2; .type 32; .endef
_floorl:
fldt 4(%esp)
subl $8,%esp
fstcw 4(%esp) /* store fpu control word */
/* We use here %edx although only the low 1 bits are defined.
But none of the operations should care and they are faster
than the 16 bit operations. */
movl $0x400,%edx /* round towards -oo */
orl 4(%esp),%edx
andl $0xf7ff,%edx
movl %edx,(%esp)
fldcw (%esp) /* load modified control word */
frndint /* round */
fldcw 4(%esp) /* restore original control word */
addl $8,%esp
ret

View File

@ -0,0 +1,5 @@
long double
fmal ( long double _x, long double _y, long double _z)
{
return ((_x * _y) + _z);
}

View File

@ -0,0 +1,23 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for float type by Danny Smith
* <dannysmith@users.sourceforge.net>.
*/
#include <math.h>
float
fmodf (float x, float y)
{
float res;
asm ("1:\tfprem\n\t"
"fstsw %%ax\n\t"
"sahf\n\t"
"jp 1b\n\t"
"fstp %%st(1)"
: "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
return res;
}

View File

@ -0,0 +1,22 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*/
#include <math.h>
long double
fmodl (long double x, long double y)
{
long double res;
asm ("1:\tfprem\n\t"
"fstsw %%ax\n\t"
"sahf\n\t"
"jp 1b\n\t"
"fstp %%st(1)"
: "=t" (res) : "0" (x), "u" (y) : "ax", "st(1)");
return res;
}

View File

@ -0,0 +1,14 @@
#include "fp_consts.h"
const union _ieee_rep __QNAN = { __DOUBLE_QNAN_REP };
const union _ieee_rep __SNAN = { __DOUBLE_SNAN_REP };
const union _ieee_rep __INF = { __DOUBLE_INF_REP };
const union _ieee_rep __DENORM = { __DOUBLE_DENORM_REP };
/* ISO C99 */
#undef nan
/* FIXME */
double nan (const char * tagp __attribute__((unused)) )
{ return __QNAN.double_val; }

View File

@ -0,0 +1,48 @@
#ifndef _FP_CONSTS_H
#define _FP_CONSTS_H
/*
According to IEEE 754 a QNaN has exponent bits of all 1 values and
initial significand bit of 1. A SNaN has has an exponent of all 1
values and initial significand bit of 0 (with one or more other
significand bits of 1). An Inf has significand of 0 and
exponent of all 1 values. A denormal value has all exponent bits of 0.
The following does _not_ follow those rules, but uses values
equal to those exported from MS C++ runtime lib, msvcprt.dll
for float and double. MSVC however, does not have long doubles.
*/
#define __DOUBLE_INF_REP { 0, 0, 0, 0x7ff0 }
#define __DOUBLE_QNAN_REP { 0, 0, 0, 0xfff8 } /* { 0, 0, 0, 0x7ff8 } */
#define __DOUBLE_SNAN_REP { 0, 0, 0, 0xfff0 } /* { 1, 0, 0, 0x7ff0 } */
#define __DOUBLE_DENORM_REP {1, 0, 0, 0}
#define D_NAN_MASK 0x7ff0000000000000LL /* this will mask NaN's and Inf's */
#define __FLOAT_INF_REP { 0, 0x7f80 }
#define __FLOAT_QNAN_REP { 0, 0xffc0 } /* { 0, 0x7fc0 } */
#define __FLOAT_SNAN_REP { 0, 0xff80 } /* { 1, 0x7f80 } */
#define __FLOAT_DENORM_REP {1,0}
#define F_NAN_MASK 0x7f800000
/*
This assumes no implicit (hidden) bit in extended mode.
Padded to 96 bits
*/
#define __LONG_DOUBLE_INF_REP { 0, 0, 0, 0x8000, 0x7fff, 0 }
#define __LONG_DOUBLE_QNAN_REP { 0, 0, 0, 0xc000, 0xffff, 0 }
#define __LONG_DOUBLE_SNAN_REP { 0, 0, 0, 0x8000, 0xffff, 0 }
#define __LONG_DOUBLE_DENORM_REP {1, 0, 0, 0, 0, 0}
union _ieee_rep
{
unsigned short rep[6];
float float_val;
double double_val;
long double ldouble_val;
} ;
#endif

View File

@ -0,0 +1,12 @@
#include "fp_consts.h"
const union _ieee_rep __QNANF = { __FLOAT_QNAN_REP };
const union _ieee_rep __SNANF = { __FLOAT_SNAN_REP };
const union _ieee_rep __INFF = { __FLOAT_INF_REP };
const union _ieee_rep __DENORMF = { __FLOAT_DENORM_REP };
/* ISO C99 */
#undef nanf
/* FIXME */
float nanf(const char * tagp __attribute__((unused)) )
{ return __QNANF.float_val;}

View File

@ -0,0 +1,12 @@
#include "fp_consts.h"
const union _ieee_rep __QNANL = { __LONG_DOUBLE_QNAN_REP };
const union _ieee_rep __SNANL = { __LONG_DOUBLE_SNAN_REP };
const union _ieee_rep __INFL = { __LONG_DOUBLE_INF_REP };
const union _ieee_rep __DENORML = { __LONG_DOUBLE_DENORM_REP };
#undef nanl
/* FIXME */
long double nanl (const char * tagp __attribute__((unused)) )
{ return __QNANL.ldouble_val; }

View File

@ -0,0 +1,3 @@
#include <math.h>
float frexpf (float x, int* expn)
{return (float)frexp(x, expn);}

View File

@ -0,0 +1,71 @@
/*
Cephes Math Library Release 2.7: May, 1998
Copyright 1984, 1987, 1988, 1992, 1998 by Stephen L. Moshier
Extracted from floorl.387 for use in libmingwex.a by
Danny Smith <dannysmith@users.sourceforge.net>
2002-06-20
*/
/*
* frexpl(long double x, int* expnt) extracts the exponent from x.
* It returns an integer power of two to expnt and the significand
* between 0.5 and 1 to y. Thus x = y * 2**expn.
*/
.align 2
.globl _frexpl
_frexpl:
pushl %ebp
movl %esp,%ebp
subl $24,%esp
pushl %esi
pushl %ebx
fldt 8(%ebp)
movl 20(%ebp),%ebx
fld %st(0)
fstpt -12(%ebp)
leal -4(%ebp),%ecx
movw -4(%ebp),%dx
andl $32767,%edx
jne L25
fldz
fucompp
fnstsw %ax
andb $68,%ah
xorb $64,%ah
jne L21
movl $0,(%ebx)
fldz
jmp L24
.align 2,0x90
.align 2,0x90
L21:
fldt -12(%ebp)
fadd %st(0),%st
fstpt -12(%ebp)
decl %edx
movw (%ecx),%si
andl $32767,%esi
jne L22
cmpl $-66,%edx
jg L21
L22:
addl %esi,%edx
jmp L19
.align 2,0x90
L25:
fstp %st(0)
L19:
addl $-16382,%edx
movl %edx,(%ebx)
movw (%ecx),%ax
andl $-32768,%eax
orl $16382,%eax
movw %ax,(%ecx)
fldt -12(%ebp)
L24:
leal -32(%ebp),%esp
popl %ebx
popl %esi
leave
ret

View File

@ -0,0 +1,4 @@
#include <math.h>
float hypotf (float x, float y)
{ return (float) _hypot (x, y);}

View File

@ -0,0 +1,58 @@
#include <math.h>
typedef union
{
long double value;
struct
{
unsigned mantissa[2];
unsigned sign_exponent : 16;
unsigned empty : 16;
} parts;
} ieee_long_double_shape_type;
/* Get int from the exponent of a long double. */
static __inline__ void
get_ld_exp (unsigned exp,long double d)
{
ieee_long_double_shape_type u;
u.value = d;
exp = u.parts.sign_exponent;
}
/* Set exponent of a long double from an int. */
static __inline__ void
set_ld_exp (long double d,unsigned exp)
{
ieee_long_double_shape_type u;
u.value = d;
u.parts.sign_exponent = exp;
d = u.value;
}
long double
hypotl (long double x, long double y)
{
unsigned exx = 0U;
unsigned eyy = 0U;
unsigned scale;
long double xx =fabsl(x);
long double yy =fabsl(y);
if (!isfinite(xx) || !isfinite(yy))
return xx + yy; /* Return INF or NAN. */
/* Scale to avoid overflow.*/
get_ld_exp (exx, xx);
get_ld_exp (eyy, yy);
scale = (exx > eyy ? exx : eyy);
if (scale == 0)
return 0.0L;
set_ld_exp (xx, exx - scale);
set_ld_exp (yy, eyy - scale);
xx = sqrtl(xx * xx + yy * yy);
get_ld_exp (exx,xx);
set_ld_exp (xx, exx + scale);
return xx;
}

View File

@ -0,0 +1,37 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "ilogb.S"
.text
.align 4
.globl _ilogb
.def _ilogb; .scl 2; .type 32; .endef
_ilogb:
fldl 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fxtract
pushl %eax
fstp %st
fistpl (%esp)
fwait
popl %eax
ret
1: fstp %st
movl $0x7fffffff, %eax
ret

View File

@ -0,0 +1,35 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
.file "ilogbf.S"
.text
.align 4
.globl _ilogbf
.def _ilogbf; .scl 2; .type 32; .endef
_ilogbf:
flds 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fxtract
pushl %eax
fstp %st
fistpl (%esp)
fwait
popl %eax
ret
1: fstp %st
movl $0x7fffffff, %eax
ret

View File

@ -0,0 +1,36 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
.file "ilogbl.S"
.text
.align 4
.globl _ilogbl
.def _ilogbl; .scl 2; .type 32; .endef
_ilogbl:
fldt 4(%esp)
/* I added the following ugly construct because ilogb(+-Inf) is
required to return INT_MAX in ISO C99.
-- jakub@redhat.com. */
fxam /* Is NaN or +-Inf? */
fstsw %ax
movb $0x45, %dh
andb %ah, %dh
cmpb $0x05, %dh
je 1f /* Is +-Inf, jump. */
fxtract
pushl %eax
fstp %st
fistpl (%esp)
fwait
popl %eax
ret
1: fstp %st
movl $0x7fffffff, %eax
ret

View File

@ -0,0 +1,3 @@
#include <math.h>
float ldexpf (float x, int expn)
{return (float) ldexp (x, expn);}

View File

@ -0,0 +1,14 @@
#include <math.h>
#include <errno.h>
long double ldexpl(long double x, int expn)
{
if (isfinite (x) && x != 0.0L)
{
x = scalbnl (x , expn);
if (!isfinite (x) || x == 0.0) errno = ERANGE;
}
return x;
}

View File

@ -0,0 +1,10 @@
#include <math.h>
long long llrint (double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
long long llrintf (float x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,10 @@
#include <math.h>
long long llrintl (long double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,24 @@
#include <fenv.h>
#include <math.h>
long
lround (double x) {
long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpll %0" : "=m" (retval) : "t" (x) : "st"
);
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,23 @@
#include <fenv.h>
#include <math.h>
long long
llroundf (float x) {
long long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpll %0" : "=m" (retval) : "t" (x) : "st"
);
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,22 @@
#include <fenv.h>
#include <math.h>
long long
llroundl (long double x) {
long long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpll %0" : "=m" (retval) : "t" (x) : "st");
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,48 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for float type by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
.file "log10f.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _log10f
.def _log10f; .scl 2; .type 32; .endef
_log10f:
fldlg2 // log10(2)
flds 4(%esp) // x : log10(2)
fxam
fnstsw
fld %st // x : x : log10(2)
sahf
jc 3f // in case x is NaN or ±Inf
4: fsubl one // x-1 : x : log10(2)
fld %st // x-1 : x-1 : x : log10(2)
fabs // |x-1| : x-1 : x : log10(2)
fcompl limit // x-1 : x : log10(2)
fnstsw // x-1 : x : log10(2)
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : log10(2)
fyl2xp1 // log10(x)
ret
2: fstp %st(0) // x : log10(2)
fyl2x // log10(x)
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,52 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log10l.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _log10l
.def _log10l; .scl 2; .type 32; .endef
_log10l:
fldlg2 // log10(2)
fldt 4(%esp) // x : log10(2)
fxam
fnstsw
fld %st // x : x : log10(2)
sahf
jc 3f // in case x is NaN or ±Inf
4: fsubl one // x-1 : x : log10(2)
fld %st // x-1 : x-1 : x : log10(2)
fabs // |x-1| : x-1 : x : log10(2)
fcompl limit // x-1 : x : log10(2)
fnstsw // x-1 : x : log10(2)
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : log10(2)
fyl2xp1 // log10(x)
ret
2: fstp %st(0) // x : log10(2)
fyl2x // log10(x)
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,47 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log1p.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .double 0.29
one: .double 1.0
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1p;
.def _log1p; .scl 2; .type 32; .endef
_log1p:
fldln2
fldl 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f // in case x is NaN or ±Inf
4: fabs
fcompl limit
fnstsw
sahf
jc 2f
faddl one
fyl2x
ret
2: fyl2xp1
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,47 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log1pf.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .float 0.29
one: .float 1.0
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1pf;
.def _log1pf; .scl 2; .type 32; .endef
_log1pf:
fldln2
flds 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f // in case x is NaN or ±Inf
4: fabs
fcomps limit
fnstsw
sahf
jc 2f
fadds one
fyl2x
ret
2: fyl2xp1
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,54 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log1pl.S"
.text
.align 4
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .tfloat 0.29
/* Please note: we use a double value here. Since 1.0 has
an exact representation this does not effect the accuracy
but it helps to optimize the code. */
one: .double 1.0
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.globl _log1pl;
.def _log1pl; .scl 2; .type 32; .endef
_log1pl:
fldln2
fldt 4(%esp)
fxam
fnstsw
fld %st
sahf
jc 3f // in case x is NaN or ±Inf
4:
fabs
fldt limit
fcompp
fnstsw
sahf
jnc 2f
faddl one
fyl2x
ret
2: fyl2xp1
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,51 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log2.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _log2
.def _log2; .scl 2; .type 32; .endef
_log2:
fldl one
fldl 4(%esp) // x : 1
fxam
fnstsw
fld %st // x : x : 1
sahf
jc 3f // in case x is NaN or ±Inf
4: fsub %st(2), %st // x-1 : x : 1
fld %st // x-1 : x-1 : x : 1
fabs // |x-1| : x-1 : x : 1
fcompl limit // x-1 : x : 1
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret
2: fstp %st(0) // x : 1
fyl2x // log(x)
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,51 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "log2f.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _log2f
.def _log2f; .scl 2; .type 32; .endef
_log2f:
fldl one
flds 4(%esp) // x : 1
fxam
fnstsw
fld %st // x : x : 1
sahf
jc 3f // in case x is NaN or ±Inf
4: fsub %st(2), %st // x-1 : x : 1
fld %st // x-1 : x-1 : x : 1
fabs // |x-1| : x-1 : x : 1
fcompl limit // x-1 : x : 1
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret
2: fstp %st(0) // x : 1
fyl2x // log(x)
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,48 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
* Public domain.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
.file "log2l.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _log2l
.def _log2l; .scl 2; .type 32; .endef
_log2l:
fldl one
fldt 4(%esp) // x : 1
fxam
fnstsw
fld %st // x : x : 1
sahf
jc 3f // in case x is NaN or ±Inf
4: fsub %st(2), %st // x-1 : x : 1
fld %st // x-1 : x-1 : x : 1
fabs // |x-1| : x-1 : x : 1
fcompl limit // x-1 : x : 1
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret
2: fstp %st(0) // x : 1
fyl2x // log(x)
ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret

View File

@ -0,0 +1,16 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
#include <math.h>
double
logb (double x)
{
double res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,16 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
#include <math.h>
float
logbf (float x)
{
float res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,17 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Changes for long double by Ulrich Drepper <drepper@cygnus.com>
* Public domain.
*/
#include <math.h>
long double
logbl (long double x)
{
long double res;
asm ("fxtract\n\t"
"fstp %%st" : "=t" (res) : "0" (x));
return res;
}

View File

@ -0,0 +1,39 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
* Adapted for float by Ulrich Drepper <drepper@cygnus.com>.
*
* Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
*/
.file "logf.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _logf
.def _logf; .scl 2; .type 32; .endef
_logf:
fldln2 // log(2)
flds 4(%esp) // x : log(2)
fld %st // x : x : log(2)
fsubl one // x-1 : x : log(2)
fld %st // x-1 : x-1 : x : log(2)
fabs // |x-1| : x-1 : x : log(2)
fcompl limit // x-1 : x : log(2)
fnstsw // x-1 : x : log(2)
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : log(2)
fyl2xp1 // log(x)
ret
2: fstp %st(0) // x : log(2)
fyl2x // log(x)
ret

View File

@ -0,0 +1,40 @@
/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*
* Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
*
* Removed header file dependency for use in libmingwex.a by
* Danny Smith <dannysmith@users.sourceforge.net>
*/
.file "logl.S"
.text
.align 4
one: .double 1.0
/* It is not important that this constant is precise. It is only
a value which is known to be on the safe side for using the
fyl2xp1 instruction. */
limit: .double 0.29
.text
.align 4
.globl _logl
.def _logl; .scl 2; .type 32; .endef
_logl:
fldln2 // log(2)
fldt 4(%esp) // x : log(2)
fld %st // x : x : log(2)
fsubl one // x-1 : x : log(2)
fld %st // x-1 : x-1 : x : log(2)
fabs // |x-1| : x-1 : x : log(2)
fcompl limit // x-1 : x : log(2)
fnstsw // x-1 : x : log(2)
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : log(2)
fyl2xp1 // log(x)
ret
2: fstp %st(0) // x : log(2)
fyl2x // log(x)
ret

View File

@ -0,0 +1,9 @@
#include <math.h>
long lrint (double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,9 @@
#include <math.h>
long lrintf (float x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,10 @@
#include <math.h>
long lrintl (long double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
return retval;
}

View File

@ -0,0 +1,24 @@
#include <fenv.h>
#include <math.h>
long
lround (double x) {
long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpl %0" : "=m" (retval) : "t" (x) : "st"
);
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,23 @@
#include <fenv.h>
#include <math.h>
long
lroundf (float x) {
long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpl %0" : "=m" (retval) : "t" (x) : "st"
);
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,22 @@
#include <fenv.h>
#include <math.h>
long
lroundl (long double x) {
long retval;
unsigned short saved_cw, _cw;
__asm__ (
"fnstcw %0;" : "=m" (saved_cw)
); /* save control word */
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
__asm__ (
"fldcw %0;" : : "m" (_cw)
); /* load the rounding control */
__asm__ __volatile__ (
"fistpl %0" : "=m" (retval) : "t" (x) : "st");
__asm__ (
"fldcw %0;" : : "m" (saved_cw)
); /* restore control word */
return retval;
}

View File

@ -0,0 +1,21 @@
#include <fenv.h>
#include <math.h>
#include <errno.h>
#define FE_ROUNDING_MASK \
(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
float
modff (float value, float* iptr)
{
float int_part;
unsigned short saved_cw;
/* truncate */
asm ("fnstcw %0;" : "=m" (saved_cw)); /* save control word */
asm ("fldcw %0;" : : "m" ((saved_cw & ~FE_ROUNDING_MASK)
| FE_TOWARDZERO));
asm ("frndint;" : "=t" (int_part) : "0" (value)); /* round */
asm ("fldcw %0;" : : "m" (saved_cw)); /* restore saved cw */
if (iptr)
*iptr = int_part;
return (isinf (value) ? 0.0F : value - int_part);
}

Some files were not shown because too many files have changed in this diff Show More