From 5632264d339742b6adef8654449c17c64d5144d7 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 17 Jun 2009 23:25:22 +0000 Subject: [PATCH] modified include/crt/math.h Ported to Visual C++ Fixed some miscellaneous stupidity. I see Arch has been committing to MinGW-W64 too svn path=/trunk/; revision=41440 --- reactos/include/crt/math.h | 279 ++++++++++++++++++++----------------- 1 file changed, 148 insertions(+), 131 deletions(-) diff --git a/reactos/include/crt/math.h b/reactos/include/crt/math.h index c66003ed53b..9a67899aadc 100644 --- a/reactos/include/crt/math.h +++ b/reactos/include/crt/math.h @@ -100,7 +100,7 @@ extern "C" { _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); @@ -131,7 +131,7 @@ extern "C" { 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); @@ -142,57 +142,52 @@ extern "C" { 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(_Number)); } - __CRT_INLINE long double _copysignl(long double _Number,long double _Sign) { return _copysign(static_cast(_Number),static_cast(_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); } -#endif -#endif -#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)); } @@ -255,11 +250,26 @@ extern "C" { #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.) */ @@ -268,7 +278,7 @@ extern "C" { __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 ); } @@ -310,8 +320,7 @@ __CRT_INLINE int isinf (double d) { __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; } @@ -319,8 +328,7 @@ __CRT_INLINE int isinf (double d) { __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; } @@ -328,8 +336,7 @@ __CRT_INLINE int isinf (double d) { __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; } @@ -345,19 +352,19 @@ __CRT_INLINE int isinf (double d) { /* 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; } @@ -387,27 +394,40 @@ __CRT_INLINE int isinf (double d) { 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; } @@ -423,7 +443,7 @@ __CRT_INLINE int isinf (double d) { 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); @@ -449,14 +469,14 @@ __CRT_INLINE int isinf (double d) { 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); @@ -485,74 +505,102 @@ __CRT_INLINE int isinf (double d) { /* 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) - { - long retval; - __asm__ __volatile__ \ - ("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \ - return retval; - } +#if defined(__GNUC__) - __CRT_INLINE long __cdecl lrintf (float x) +#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; + __fistpl(x, retval); + return retval; } - __CRT_INLINE long __cdecl lrintl (long double 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 long __cdecl llrint (double x) + __CRT_INLINE long __cdecl lrintl (long double x) { - long long retval; - __asm__ __volatile__ \ - ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \ - return retval; + long retval; + __fistpl(x, retval); + return retval; } - __CRT_INLINE long long __cdecl llrintf (float x) + __CRT_INLINE long long __cdecl llrint (double x) { long long retval; - __asm__ __volatile__ \ - ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \ - return retval; + __fistpll(x, retval); + return retval; } - __CRT_INLINE long long __cdecl llrintl (long double x) + __CRT_INLINE long long __cdecl llrintf (float x) { long long retval; - __asm__ __volatile__ \ - ("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \ - return retval; + __fistpll(x, retval); + return retval; + } + + __CRT_INLINE long long __cdecl llrintl (long double x) + { + long long retval; + __fistpll(x, retval); + return retval; } /* 7.12.9.6 */ @@ -578,7 +626,7 @@ __CRT_INLINE int isinf (double d) { 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); @@ -633,22 +681,22 @@ __CRT_INLINE int isinf (double d) { 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) @@ -662,8 +710,20 @@ __CRT_INLINE int isinf (double d) { __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; } @@ -695,7 +755,7 @@ extern "C++" { 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); } } } @@ -735,47 +795,4 @@ extern "C++" { #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 /* !_INC_MATH */