Author: hyperion
Date: Thu Jun 18 03:25:22 2009
New Revision: 41440
URL:
http://svn.reactos.org/svn/reactos?rev=41440&view=rev
Log:
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
Modified:
trunk/reactos/include/crt/math.h
Modified: trunk/reactos/include/crt/math.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/crt/math.h?rev=414…
==============================================================================
--- trunk/reactos/include/crt/math.h [iso-8859-1] (original)
+++ trunk/reactos/include/crt/math.h [iso-8859-1] Thu Jun 18 03:25:22 2009
@@ -100,7 +100,7 @@
_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 @@
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 @@
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 @@
#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 @@
__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 __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 __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 __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 @@
/* 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 @@
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 @@
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 @@
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 @@
/* 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;
- }
-
- __CRT_INLINE long __cdecl lrintf (float 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;
- }
-
- __CRT_INLINE long __cdecl lrintl (long double x)
+ __fistpl(x, retval);
+ return retval;
+ }
+
+ __CRT_INLINE long __cdecl lrintf (float x)
{
long retval;
- __asm__ __volatile__ \
- ("fistpl %0" : "=m" (retval) : "t" (x) :
"st"); \
- return retval;
- }
-
- __CRT_INLINE long long __cdecl llrint (double x)
+ __fistpl(x, retval);
+ return retval;
+ }
+
+ __CRT_INLINE long __cdecl lrintl (long double x)
+ {
+ long retval;
+ __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"); \
- return retval;
- }
-
- __CRT_INLINE long long __cdecl llrintf (float x)
+ __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"); \
- return retval;
- }
-
- __CRT_INLINE long long __cdecl llrintl (long double x)
+ __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"); \
- return retval;
+ __fistpll(x, retval);
+ return retval;
}
/* 7.12.9.6 */
@@ -578,7 +626,7 @@
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 @@
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 __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 @@
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 @@
#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 */