* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
-#ifndef _MATH_H_
-#define _MATH_H_
-
-#if __GNUC__ >= 3
-#pragma GCC system_header
-#endif
+#ifndef _INC_MATH
+#define _INC_MATH
#include <crtdefs.h>
#define EDOM 33
#define ERANGE 34
-#ifndef _HUGE
-#ifdef _MSVCRT_
- extern double *_HUGE;
-#else
- extern double *_imp___HUGE;
-#define _HUGE (*_imp___HUGE)
-#endif
-#endif
+ _CRTIMP extern double _HUGE;
#define HUGE_VAL _HUGE
#endif
_CRTIMP double __cdecl _cabs(struct _complex _ComplexA);
- double __cdecl ceil(double _X);
- double __cdecl floor(double _X);
- double __cdecl frexp(double _X,int *_Y);
- double __cdecl _hypot(double _X,double _Y);
+ _CRTIMP double __cdecl ceil(double _X);
+ _CRTIMP double __cdecl floor(double _X);
+ _CRTIMP double __cdecl frexp(double _X,int *_Y);
+ _CRTIMP double __cdecl _hypot(double _X,double _Y);
_CRTIMP double __cdecl _j0(double _X);
_CRTIMP double __cdecl _j1(double _X);
_CRTIMP double __cdecl _jn(int _X,double _Y);
- double __cdecl ldexp(double _X,int _Y);
+ _CRTIMP double __cdecl ldexp(double _X,int _Y);
#ifndef _CRT_MATHERR_DEFINED
#define _CRT_MATHERR_DEFINED
int __cdecl _matherr(struct _exception *_Except);
#endif
- double __cdecl modf(double _X,double *_Y);
+ _CRTIMP double __cdecl modf(double _X,double *_Y);
_CRTIMP double __cdecl _y0(double _X);
_CRTIMP double __cdecl _y1(double _X);
_CRTIMP double __cdecl _yn(int _X,double _Y);
-#if(defined(_X86_) && !defined(__x86_64))
+#if defined(__i386__) || defined(_M_IX86)
_CRTIMP int __cdecl _set_SSE2_enable(int _Flag);
/* from libmingwex */
float __cdecl _hypotf(float _X,float _Y);
float __cdecl fmodf(float _X,float _Y);
float __cdecl _hypotf(float _X,float _Y);
float __cdecl fabsf(float _X);
-#if !defined(__ia64__)
+#if !defined(__ia64__) && !defined(_M_IA64)
/* from libmingwex */
float __cdecl _copysignf (float _Number,float _Sign);
float __cdecl _chgsignf (float _X);
int __cdecl _fpclassf(float _X);
#endif
-#ifndef __cplusplus
+#if defined(__GNUC__)
+
+#define __fabs(x, res) \
+ __asm__ ("fabs;" : "=t" (res) : "0" (x))
+
+#elif defined(_MSC_VER)
+
+#define __fabs(x, res) \
+ __asm { fld [(x)] } \
+ __asm { fabs } \
+ __asm { fstp [(res)] }
+
+#endif
+
__CRT_INLINE long double __cdecl fabsl (long double x)
{
long double res;
- __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ __fabs(x, res);
return res;
}
-#define _hypotl(x,y) ((long double)_hypot((double)(x),(double)(y)))
-#define _matherrl _matherr
+
__CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign((double)(_Number)); }
__CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign((double)(_Number),(double)(_Sign)); }
+ __CRT_INLINE long double _hypotl(long double _X,long double _Y) { return _hypot((double)(_X),(double)(_Y)); }
__CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); }
-#if !defined (__ia64__)
+#if !defined (__ia64__) && !defined (_M_IA64)
__CRT_INLINE float __cdecl fabsf (float x)
{
float res;
- __asm__ ("fabs;" : "=t" (res) : "0" (x));
+ __fabs(x, res);
return res;
}
__CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
#endif
-#else
- // cplusplus
- __CRT_INLINE long double __cdecl fabsl (long double x)
- {
- long double res;
- __asm__ ("fabs;" : "=t" (res) : "0" (x));
- return res;
- }
+
+#define _matherrl _matherr
+
__CRT_INLINE long double modfl(long double _X,long double *_Y) {
double _Di,_Df = modf((double)_X,&_Di);
*_Y = (long double)_Di;
return (_Df);
}
- __CRT_INLINE long double _chgsignl(long double _Number) { return _chgsign(static_cast<double>(_Number)); }
- __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign(static_cast<double>(_Number),static_cast<double>(_Sign)); }
- __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); }
-#ifndef __ia64__
- __CRT_INLINE float __cdecl fabsf (float x)
- {
- float res;
- __asm__ ("fabs;" : "=t" (res) : "0" (x));
- return res;
- }
- __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp (x, expn); }
-#ifndef __x86_64
+
+#if !defined(__x86_64) && !defined(_M_AMD64)
__CRT_INLINE float acosf(float _X) { return ((float)acos((double)_X)); }
__CRT_INLINE float asinf(float _X) { return ((float)asin((double)_X)); }
__CRT_INLINE float atanf(float _X) { return ((float)atan((double)_X)); }
__CRT_INLINE float tanf(float _X) { return ((float)tan((double)_X)); }
__CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); }
#endif
-#endif
-#endif
#ifndef NO_OLDNAMES
#define DOMAIN _DOMAIN
#define HUGE _HUGE
/* double __cdecl cabs(struct _complex _X); */
double __cdecl hypot(double _X,double _Y);
+ __CRT_INLINE float __cdecl hypotf (float x, float y)
+ { return (float) hypot (x, y);}
_CRTIMP double __cdecl j0(double _X);
_CRTIMP double __cdecl j1(double _X);
_CRTIMP double __cdecl jn(int _X,double _Y);
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|| !defined __STRICT_ANSI__ || defined __GLIBCPP__
+#if !defined(_MSC_VER)
#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)
+#endif
#define FP_NAN 0x0100
#define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
/* 0x0200 is signbit mask */
+#if defined(__GNUC__)
+
+#define __fxam(x, sw) \
+ __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x))
+
+#elif defined(_MSC_VER)
+
+#define __fxam(x, sw) \
+ __asm { fld [(x)] } \
+ __asm { fxam } \
+ __asm { wait } \
+ __asm { fnstsw [(sw)] } \
+ __asm { fstp st(0) }
+
+#endif
/*
We can't __CRT_INLINE float or double, because we want to ensure truncation
- to semantic type before classification.
- (A normal long double value might become subnormal when
+ to semantic type before classification.
+ (A normal long double value might become subnormal when
converted to double, and zero when converted to float.)
*/
__CRT_INLINE int __cdecl __fpclassifyl (long double x){
unsigned short sw;
- __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
+ __fxam(x, sw);
return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
}
+ __CRT_INLINE int __cdecl __fpclassify (double x){
+ return __fpclassifyl((long double)x);
+ }
+
#define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \
: sizeof (x) == sizeof (double) ? __fpclassify (x) \
: __fpclassifyl (x))
#define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
/* 7.12.3.3 */
-#define isinf(x) (fpclassify(x) == FP_INFINITE)
+/* #define isinf(x) (fpclassify(x) == FP_INFINITE) */
+
+ /* we don't have fpclassify */
+__CRT_INLINE int isinf (double d) {
+ int expon = 0;
+ double val = frexp (d, &expon);
+ if (expon == 1025) {
+ if (val == 0.5) {
+ return 1;
+ } else if (val == -0.5) {
+ return -1;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
/* 7.12.3.4 */
- /* We don't need to worry about trucation here:
+ /* We don't need to worry about truncation here:
A NaN stays a NaN. */
__CRT_INLINE int __cdecl __isnan (double _x)
{
unsigned short sw;
- __asm__ ("fxam;"
- "fstsw %%ax": "=a" (sw) : "t" (_x));
+ __fxam(_x, sw);
return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
__CRT_INLINE int __cdecl __isnanf (float _x)
{
unsigned short sw;
- __asm__ ("fxam;"
- "fstsw %%ax": "=a" (sw) : "t" (_x));
+ __fxam(_x, sw);
return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
__CRT_INLINE int __cdecl __isnanl (long double _x)
{
unsigned short sw;
- __asm__ ("fxam;"
- "fstsw %%ax": "=a" (sw) : "t" (_x));
+ __fxam(_x, sw);
return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
== FP_NAN;
}
/* 7.12.3.6 The signbit macro */
__CRT_INLINE int __cdecl __signbit (double x) {
unsigned short stw;
- __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
+ __fxam(x, stw);
return stw & 0x0200;
}
__CRT_INLINE int __cdecl __signbitf (float x) {
unsigned short stw;
- __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
+ __fxam(x, stw);
return stw & 0x0200;
}
__CRT_INLINE int __cdecl __signbitl (long double x) {
unsigned short stw;
- __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
+ __fxam(x, stw);
return stw & 0x0200;
}
extern float __cdecl logbf (float);
extern long double __cdecl logbl (long double);
+#if defined(__GNUC__)
+
+#define __fxtract(x, res) \
+ __asm__ ("fxtract\n\t" \
+ "fstp %%st" : "=t" (res) : "0" (x))
+
+#elif defined(_MSC_VER)
+
+#define __fxtract(x, res) \
+ __asm { fld [(x)] } \
+ __asm { fxtract } \
+ __asm { fstp st(0) } \
+ __asm { fstp [(res)] }
+
+#endif
+
__CRT_INLINE double __cdecl logb (double x)
{
double res;
- __asm__ ("fxtract\n\t"
- "fstp %%st" : "=t" (res) : "0" (x));
+ __fxtract(x, res);
return res;
}
__CRT_INLINE float __cdecl logbf (float x)
{
float res;
- __asm__ ("fxtract\n\t"
- "fstp %%st" : "=t" (res) : "0" (x));
+ __fxtract(x, res);
return res;
}
__CRT_INLINE long double __cdecl logbl (long double x)
{
long double res;
- __asm__ ("fxtract\n\t"
- "fstp %%st" : "=t" (res) : "0" (x));
+ __fxtract(x, res);
return res;
}
extern long double __cdecl scalblnl (long double, long);
/* 7.12.7.1 */
- /* Implementations adapted from Cephes versions */
+ /* Implementations adapted from Cephes versions */
extern double __cdecl cbrt (double);
extern float __cdecl cbrtf (float);
extern long double __cdecl cbrtl (long double);
- __CRT_INLINE float __cdecl hypotf (float x, float y)
- { return (float) hypot (x, y);}
extern long double __cdecl hypotl (long double, long double);
extern long double __cdecl powl (long double, long double);
extern float __cdecl erff (float);
/* TODO
extern long double __cdecl erfl (long double);
- */
+ */
/* 7.12.8.2 The erfc functions */
extern double __cdecl erfc (double);
extern float __cdecl erfcf (float);
/* TODO
extern long double __cdecl erfcl (long double);
- */
+ */
/* 7.12.8.3 The lgamma functions */
extern double __cdecl lgamma (double);
/* 7.12.9.4 */
/* round, using fpu control word settings */
+#if defined(__GNUC__)
+
+#define __frndint(x, res) \
+ __asm__ ("fabs;" : "=t" (res) : "0" (x))
+
+#elif defined(_MSC_VER)
+
+#define __frndint(x, res) \
+ __asm { fld [(x)] } \
+ __asm { frndint } \
+ __asm { fstp [(res)] }
+
+#endif
+
__CRT_INLINE double __cdecl rint (double x)
{
double retval;
- __asm__ ("frndint;": "=t" (retval) : "0" (x));
+ __frndint(x, retval);
return retval;
}
__CRT_INLINE float __cdecl rintf (float x)
{
float retval;
- __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
+ __frndint(x, retval);
return retval;
}
__CRT_INLINE long double __cdecl rintl (long double x)
{
long double retval;
- __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
+ __frndint(x, retval);
return retval;
}
/* 7.12.9.5 */
- __CRT_INLINE long __cdecl lrint (double x)
+#if defined(__GNUC__)
+
+#define __fistpl(x, res) \
+ __asm__ __volatile__("fistpl %0" : "=m" (res) : "t" (x) : "st")
+
+#define __fistpll(x, res) \
+ __asm__ __volatile__("fistpll %0" : "=m" (res) : "t" (x) : "st")
+
+#elif defined(_MSC_VER)
+
+#define __fistpl(x, res) \
+ __asm { fld [(x)] } \
+ __asm { fistp [(res)] }
+
+#define __fistpll(x, res) \
+ __asm { fld [(x)] } \
+ __asm { fistp [(res)] }
+
+#endif
+
+ __CRT_INLINE long __cdecl lrint (double x)
{
- long retval;
- __asm__ __volatile__ \
- ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ long retval;
+ __fistpl(x, retval);
+ return retval;
}
- __CRT_INLINE long __cdecl lrintf (float x)
+ __CRT_INLINE long __cdecl lrintf (float x)
{
long retval;
- __asm__ __volatile__ \
- ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ __fistpl(x, retval);
+ return retval;
}
- __CRT_INLINE long __cdecl lrintl (long double x)
+ __CRT_INLINE long __cdecl lrintl (long double x)
{
long retval;
- __asm__ __volatile__ \
- ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ __fistpl(x, retval);
+ return retval;
}
- __CRT_INLINE long long __cdecl llrint (double x)
+ __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrint (double x)
{
- long long retval;
- __asm__ __volatile__ \
- ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ __MINGW_EXTENSION long long retval;
+ __fistpll(x, retval);
+ return retval;
}
- __CRT_INLINE long long __cdecl llrintf (float x)
+ __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrintf (float x)
{
- long long retval;
- __asm__ __volatile__ \
- ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ __MINGW_EXTENSION long long retval;
+ __fistpll(x, retval);
+ return retval;
}
- __CRT_INLINE long long __cdecl llrintl (long double x)
+ __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrintl (long double x)
{
- long long retval;
- __asm__ __volatile__ \
- ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
- return retval;
+ __MINGW_EXTENSION long long retval;
+ __fistpll(x, retval);
+ return retval;
}
/* 7.12.9.6 */
extern long __cdecl lroundf (float);
extern long __cdecl lroundl (long double);
- extern long long __cdecl llround (double);
- extern long long __cdecl llroundf (float);
- extern long long __cdecl llroundl (long double);
+ __MINGW_EXTENSION extern long long __cdecl llround (double);
+ __MINGW_EXTENSION extern long long __cdecl llroundf (float);
+ __MINGW_EXTENSION extern long long __cdecl llroundl (long double);
/* 7.12.9.8 */
/* round towards zero, regardless of fpu control word settings */
extern long double __cdecl fmodl (long double, long double);
- /* 7.12.10.2 */
+ /* 7.12.10.2 */
extern double __cdecl remainder (double, double);
extern float __cdecl remainderf (float, float);
extern long double __cdecl remainderl (long double, long double);
extern long double __cdecl fminl (long double, long double);
/* 7.12.13.1 */
- /* return x * y + z as a ternary op */
+ /* return x * y + z as a ternary op */
extern double __cdecl fma (double, double, double);
extern float __cdecl fmaf (float, float, float);
extern long double __cdecl fmal (long double, long double, long double);
/* 7.12.14 */
- /*
+ /*
* With these functions, comparisons involving quiet NaNs set the FP
* condition code to "unordered". The IEEE floating-point spec
* dictates that the result of floating-point comparisons should be
- * false whenever a NaN is involved, with the exception of the != op,
+ * false whenever a NaN is involved, with the exception of the != op,
* which always returns true: yes, (NaN != NaN) is true).
*/
-#if __GNUC__ >= 3
+#if defined(__GNUC__) && __GNUC__ >= 3
#define isgreater(x, y) __builtin_isgreater(x, y)
#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
__CRT_INLINE int __cdecl
__fp_unordered_compare (long double x, long double y){
unsigned short retval;
+#if defined(__GNUC__)
__asm__ ("fucom %%st(1);"
"fnstsw;": "=a" (retval) : "t" (x), "u" (y));
+#elif defined(_MSC_VER)
+ __asm {
+ fld [x]
+ fld [y]
+ fxch st(1)
+ fucom st(1)
+ fnstsw [retval]
+ fstp st(0)
+ fstp st(0)
+ }
+#endif
return retval;
}
else _N = (unsigned int)(-_Y);
for(_Ty _Z = _Ty(1);;_X *= _X) {
if((_N & 1)!=0) _Z *= _X;
- if((_N >>= 1)==0) return (_Y < 0 ? _Ty(1) / _Z : _Z);
+ if((_N >>= 1)==0) return (_Y < 0 ? _Ty(1) / _Z : _Z);
}
}
}
#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
#endif /* __MINGW_FPCLASS_DEFINED */
-/* 7.12.14 */
-/*
- * With these functions, comparisons involving quiet NaNs set the FP
- * condition code to "unordered". The IEEE floating-point spec
- * dictates that the result of floating-point comparisons should be
- * false whenever a NaN is involved, with the exception of the != op,
- * which always returns true: yes, (NaN != NaN) is true).
- */
-
-#if __GNUC__ >= 3
-
-#define isgreater(x, y) __builtin_isgreater(x, y)
-#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
-#define isless(x, y) __builtin_isless(x, y)
-#define islessequal(x, y) __builtin_islessequal(x, y)
-#define islessgreater(x, y) __builtin_islessgreater(x, y)
-#define isunordered(x, y) __builtin_isunordered(x, y)
-
-#else
-/* helper */
-__CRT_INLINE int __cdecl
-__fp_unordered_compare (long double x, long double y){
- unsigned short retval;
- __asm__ ("fucom %%st(1);"
- "fnstsw;": "=a" (retval) : "t" (x), "u" (y));
- return retval;
-}
-
-#define isgreater(x, y) ((__fp_unordered_compare(x, y) \
- & 0x4500) == 0)
-#define isless(x, y) ((__fp_unordered_compare (y, x) \
- & 0x4500) == 0)
-#define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
- & FP_INFINITE) == 0)
-#define islessequal(x, y) ((__fp_unordered_compare(y, x) \
- & FP_INFINITE) == 0)
-#define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
- & FP_SUBNORMAL) == 0)
-#define isunordered(x, y) ((__fp_unordered_compare(x, y) \
- & 0x4500) == 0x4500)
-
-#endif
-
-#endif /* End _MATH_H_ */
-
+#endif /* !_INC_MATH */