mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
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:
parent
abdf1ae486
commit
5632264d33
1 changed files with 148 additions and 131 deletions
|
@ -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,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 */
|
||||
|
|
Loading…
Reference in a new issue