modified include/crt/math.h

Ported <math.h> to Visual C++
   Fixed some miscellaneous stupidity. I see Arch has been committing to MinGW-W64 too

svn path=/trunk/; revision=41440
This commit is contained in:
KJK::Hyperion 2009-06-17 23:25:22 +00:00
parent abdf1ae486
commit 5632264d33

View file

@ -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<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); }
#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,6 +250,21 @@ 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
@ -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;
}
@ -485,73 +505,101 @@ __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 */
#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"); \
__fistpl(x, retval);
return retval;
}
__CRT_INLINE long __cdecl lrintf (float x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
__fistpl(x, retval);
return retval;
}
__CRT_INLINE long __cdecl lrintl (long double x)
{
long retval;
__asm__ __volatile__ \
("fistpl %0" : "=m" (retval) : "t" (x) : "st"); \
__fistpl(x, retval);
return retval;
}
__CRT_INLINE long long __cdecl llrint (double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
__fistpll(x, retval);
return retval;
}
__CRT_INLINE long long __cdecl llrintf (float x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
__fistpll(x, retval);
return retval;
}
__CRT_INLINE long long __cdecl llrintl (long double x)
{
long long retval;
__asm__ __volatile__ \
("fistpll %0" : "=m" (retval) : "t" (x) : "st"); \
__fistpll(x, retval);
return retval;
}
@ -648,7 +696,7 @@ __CRT_INLINE int isinf (double d) {
* 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;
}
@ -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 */