Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- This decreases the compile time and the size of the compiled binaries, though admittedly not as much as I had hoped. It will make more of a difference when we implement more of the new functions.
dlls/msvcrt/math.c | 408 ++++++++++++++++++++++++++++------------------------- 1 file changed, 212 insertions(+), 196 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 7fb4666bef..12600e6712 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -130,17 +130,6 @@ int CDECL MSVCRT__set_SSE2_enable(int flag) return sse2_enabled; }
-#ifdef _WIN64 -/********************************************************************* - * _set_FMA3_enable (MSVCR120.@) - */ -int CDECL MSVCRT__set_FMA3_enable(int flag) -{ - FIXME("(%x) stub\n", flag); - return 0; -} -#endif - #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || _MSVCR_VER>=120
/********************************************************************* @@ -813,14 +802,6 @@ MSVCRT_long CDECL MSVCRT_labs( MSVCRT_long n ) return n >= 0 ? n : -n; }
-/********************************************************************* - * llabs (MSVCRT.@) - */ -MSVCRT_longlong CDECL MSVCRT_llabs( MSVCRT_longlong n ) -{ - return n >= 0 ? n : -n; -} - /********************************************************************* * _abs64 (MSVCRT.@) */ @@ -1227,58 +1208,6 @@ int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask return 0; }
-/********************************************************************* - * fegetenv (MSVCR120.@) - */ -int CDECL MSVCRT_fegetenv(MSVCRT_fenv_t *env) -{ - env->control = _controlfp(0, 0) & (MSVCRT__EM_INEXACT | MSVCRT__EM_UNDERFLOW | - MSVCRT__EM_OVERFLOW | MSVCRT__EM_ZERODIVIDE | MSVCRT__EM_INVALID); - env->status = _statusfp(); - return 0; -} - -/********************************************************************* - * __fpe_flt_rounds (UCRTBASE.@) - */ -int CDECL __fpe_flt_rounds(void) -{ - unsigned int fpc = _controlfp(0, 0) & MSVCRT__RC_CHOP; - - TRACE("()\n"); - - switch(fpc) { - case MSVCRT__RC_CHOP: return 0; - case MSVCRT__RC_NEAR: return 1; -#ifdef _WIN64 - case MSVCRT__RC_UP: return 3; - default: return 2; -#else - case MSVCRT__RC_UP: return 2; - default: return 3; -#endif - } -} - -/********************************************************************* - * fegetround (MSVCR120.@) - */ -int CDECL MSVCRT_fegetround(void) -{ - return _controlfp(0, 0) & MSVCRT__RC_CHOP; -} - -/********************************************************************* - * fesetround (MSVCR120.@) - */ -int CDECL MSVCRT_fesetround(int round_mode) -{ - if (round_mode & (~MSVCRT__RC_CHOP)) - return 1; - _controlfp(round_mode, MSVCRT__RC_CHOP); - return 0; -} - /********************************************************************* * _copysign (MSVCRT.@) */ @@ -1315,74 +1244,6 @@ void CDECL _fpreset(void) #endif }
-/********************************************************************* - * fesetenv (MSVCR120.@) - */ -int CDECL MSVCRT_fesetenv(const MSVCRT_fenv_t *env) -{ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - struct { - WORD control_word; - WORD unused1; - WORD status_word; - WORD unused2; - WORD tag_word; - WORD unused3; - DWORD instruction_pointer; - WORD code_segment; - WORD unused4; - DWORD operand_addr; - WORD data_segment; - WORD unused5; - } fenv; - - TRACE( "(%p)\n", env ); - - if (!env->control && !env->status) { - _fpreset(); - return 0; - } - - __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) ); - - fenv.control_word &= ~0x3d; - if (env->control & MSVCRT__EM_INVALID) fenv.control_word |= 0x1; - if (env->control & MSVCRT__EM_ZERODIVIDE) fenv.control_word |= 0x4; - if (env->control & MSVCRT__EM_OVERFLOW) fenv.control_word |= 0x8; - if (env->control & MSVCRT__EM_UNDERFLOW) fenv.control_word |= 0x10; - if (env->control & MSVCRT__EM_INEXACT) fenv.control_word |= 0x20; - - fenv.status_word &= ~0x3d; - if (env->status & MSVCRT__SW_INVALID) fenv.status_word |= 0x1; - if (env->status & MSVCRT__SW_ZERODIVIDE) fenv.status_word |= 0x4; - if (env->status & MSVCRT__SW_OVERFLOW) fenv.status_word |= 0x8; - if (env->status & MSVCRT__SW_UNDERFLOW) fenv.status_word |= 0x10; - if (env->status & MSVCRT__SW_INEXACT) fenv.status_word |= 0x20; - - __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)", - "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" ); - - if (sse2_supported) - { - DWORD fpword; - - __asm__ __volatile__( "stmxcsr %0" : "=m" (fpword) ); - fpword &= ~0x1e80; - if (env->control & MSVCRT__EM_INVALID) fpword |= 0x80; - if (env->control & MSVCRT__EM_ZERODIVIDE) fpword |= 0x200; - if (env->control & MSVCRT__EM_OVERFLOW) fpword |= 0x400; - if (env->control & MSVCRT__EM_UNDERFLOW) fpword |= 0x800; - if (env->control & MSVCRT__EM_INEXACT) fpword |= 0x1000; - __asm__ __volatile__( "ldmxcsr %0" : : "m" (fpword) ); - } - - return 0; -#else - FIXME( "not implemented\n" ); -#endif - return 1; -} - /********************************************************************* * _isnan (MSVCRT.@) */ @@ -1469,30 +1330,6 @@ double CDECL MSVCRT__yn(int order, double num) return retval; }
-/********************************************************************* - * _nearbyint (MSVCRT.@) - */ -double CDECL MSVCRT_nearbyint(double num) -{ -#ifdef HAVE_NEARBYINT - return nearbyint(num); -#else - return num >= 0 ? floor(num + 0.5) : ceil(num - 0.5); -#endif -} - -/********************************************************************* - * _nearbyintf (MSVCRT.@) - */ -float CDECL MSVCRT_nearbyintf(float num) -{ -#ifdef HAVE_NEARBYINTF - return nearbyintf(num); -#else - return MSVCRT_nearbyint(num); -#endif -} - /********************************************************************* * _nextafter (MSVCRT.@) */ @@ -1888,19 +1725,6 @@ MSVCRT_ldiv_t CDECL MSVCRT_ldiv(MSVCRT_long num, MSVCRT_long denom) } #endif /* ifdef __i386__ */
-/********************************************************************* - * lldiv (MSVCRT.@) - */ -MSVCRT_lldiv_t CDECL MSVCRT_lldiv(MSVCRT_longlong num, MSVCRT_longlong denom) -{ - MSVCRT_lldiv_t ret; - - ret.quot = num / denom; - ret.rem = num % denom; - - return ret; -} - #ifdef __i386__
/********************************************************************* @@ -2376,6 +2200,179 @@ void __cdecl MSVCRT___libm_sse2_sqrt_precise(void)
#endif /* __i386__ */
+/********************************************************************* + * _scalb (MSVCRT.@) + * scalbn (MSVCR120.@) + * scalbln (MSVCR120.@) + */ +double CDECL MSVCRT__scalb(double num, MSVCRT_long power) +{ + return MSVCRT_ldexp(num, power); +} + +/********************************************************************* + * _scalbf (MSVCRT.@) + * scalbnf (MSVCR120.@) + * scalblnf (MSVCR120.@) + */ +float CDECL MSVCRT__scalbf(float num, MSVCRT_long power) +{ + return MSVCRT_ldexp(num, power); +} + +#if _MSVCR_VER>=100 + +/********************************************************************* + * llabs (MSVCR100.@) + * llabs (MSVCR110.@) + * llabs (MSVCR120.@) + */ +MSVCRT_longlong CDECL MSVCRT_llabs( MSVCRT_longlong n ) +{ + return n >= 0 ? n : -n; +} + +/********************************************************************* + * lldiv (MSVCR100.@) + * lldiv (MSVCR110.@) + * lldiv (MSVCR120.@) + */ +MSVCRT_lldiv_t CDECL MSVCRT_lldiv(MSVCRT_longlong num, MSVCRT_longlong denom) +{ + MSVCRT_lldiv_t ret; + + ret.quot = num / denom; + ret.rem = num % denom; + + return ret; +} + +#endif /* _MSVCR_VER>=100 */ + +#if _MSVCR_VER>=120 + +/********************************************************************* + * fegetenv (MSVCR120.@) + */ +int CDECL MSVCRT_fegetenv(MSVCRT_fenv_t *env) +{ + env->control = _controlfp(0, 0) & (MSVCRT__EM_INEXACT | MSVCRT__EM_UNDERFLOW | + MSVCRT__EM_OVERFLOW | MSVCRT__EM_ZERODIVIDE | MSVCRT__EM_INVALID); + env->status = _statusfp(); + return 0; +} + +/********************************************************************* + * fegetround (MSVCR120.@) + */ +int CDECL MSVCRT_fegetround(void) +{ + return _controlfp(0, 0) & MSVCRT__RC_CHOP; +} + +/********************************************************************* + * fesetround (MSVCR120.@) + */ +int CDECL MSVCRT_fesetround(int round_mode) +{ + if (round_mode & (~MSVCRT__RC_CHOP)) + return 1; + _controlfp(round_mode, MSVCRT__RC_CHOP); + return 0; +} + +/********************************************************************* + * fesetenv (MSVCR120.@) + */ +int CDECL MSVCRT_fesetenv(const MSVCRT_fenv_t *env) +{ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + struct { + WORD control_word; + WORD unused1; + WORD status_word; + WORD unused2; + WORD tag_word; + WORD unused3; + DWORD instruction_pointer; + WORD code_segment; + WORD unused4; + DWORD operand_addr; + WORD data_segment; + WORD unused5; + } fenv; + + TRACE( "(%p)\n", env ); + + if (!env->control && !env->status) { + _fpreset(); + return 0; + } + + __asm__ __volatile__( "fnstenv %0" : "=m" (fenv) ); + + fenv.control_word &= ~0x3d; + if (env->control & MSVCRT__EM_INVALID) fenv.control_word |= 0x1; + if (env->control & MSVCRT__EM_ZERODIVIDE) fenv.control_word |= 0x4; + if (env->control & MSVCRT__EM_OVERFLOW) fenv.control_word |= 0x8; + if (env->control & MSVCRT__EM_UNDERFLOW) fenv.control_word |= 0x10; + if (env->control & MSVCRT__EM_INEXACT) fenv.control_word |= 0x20; + + fenv.status_word &= ~0x3d; + if (env->status & MSVCRT__SW_INVALID) fenv.status_word |= 0x1; + if (env->status & MSVCRT__SW_ZERODIVIDE) fenv.status_word |= 0x4; + if (env->status & MSVCRT__SW_OVERFLOW) fenv.status_word |= 0x8; + if (env->status & MSVCRT__SW_UNDERFLOW) fenv.status_word |= 0x10; + if (env->status & MSVCRT__SW_INEXACT) fenv.status_word |= 0x20; + + __asm__ __volatile__( "fldenv %0" : : "m" (fenv) : "st", "st(1)", + "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)" ); + + if (sse2_supported) + { + DWORD fpword; + + __asm__ __volatile__( "stmxcsr %0" : "=m" (fpword) ); + fpword &= ~0x1e80; + if (env->control & MSVCRT__EM_INVALID) fpword |= 0x80; + if (env->control & MSVCRT__EM_ZERODIVIDE) fpword |= 0x200; + if (env->control & MSVCRT__EM_OVERFLOW) fpword |= 0x400; + if (env->control & MSVCRT__EM_UNDERFLOW) fpword |= 0x800; + if (env->control & MSVCRT__EM_INEXACT) fpword |= 0x1000; + __asm__ __volatile__( "ldmxcsr %0" : : "m" (fpword) ); + } + + return 0; +#else + FIXME( "not implemented\n" ); +#endif + return 1; +} + +/********************************************************************* + * _nearbyint (MSVCR120.@) + */ +double CDECL MSVCRT_nearbyint(double num) +{ +#ifdef HAVE_NEARBYINT + return nearbyint(num); +#else + return num >= 0 ? floor(num + 0.5) : ceil(num - 0.5); +#endif +} + +/********************************************************************* + * _nearbyintf (MSVCR120.@) + */ +float CDECL MSVCRT_nearbyintf(float num) +{ +#ifdef HAVE_NEARBYINTF + return nearbyintf(num); +#else + return MSVCRT_nearbyint(num); +#endif +} + /********************************************************************* * cbrt (MSVCR120.@) */ @@ -3126,26 +3123,6 @@ LDOUBLE CDECL MSVCR120_atanhl(LDOUBLE x) return MSVCR120_atanh(x); }
-/********************************************************************* - * _scalb (MSVCRT.@) - * scalbn (MSVCR120.@) - * scalbln (MSVCR120.@) - */ -double CDECL MSVCRT__scalb(double num, MSVCRT_long power) -{ - return MSVCRT_ldexp(num, power); -} - -/********************************************************************* - * _scalbf (MSVCRT.@) - * scalbnf (MSVCR120.@) - * scalblnf (MSVCR120.@) - */ -float CDECL MSVCRT__scalbf(float num, MSVCRT_long power) -{ - return MSVCRT_ldexp(num, power); -} - /********************************************************************* * scalbnl (MSVCR120.@) * scalblnl (MSVCR120.@) @@ -3337,3 +3314,42 @@ double CDECL _except1(DWORD fpe, _FP_OPERATION_CODE op, double arg, double res,
return res; } + +#ifdef _WIN64 +/********************************************************************* + * _set_FMA3_enable (MSVCR120.@) + */ +int CDECL MSVCRT__set_FMA3_enable(int flag) +{ + FIXME("(%x) stub\n", flag); + return 0; +} +#endif + +#endif /* _MSVCR_VER>=120 */ + +#if _MSVCR_VER>=140 + +/********************************************************************* + * __fpe_flt_rounds (UCRTBASE.@) + */ +int CDECL __fpe_flt_rounds(void) +{ + unsigned int fpc = _controlfp(0, 0) & MSVCRT__RC_CHOP; + + TRACE("()\n"); + + switch(fpc) { + case MSVCRT__RC_CHOP: return 0; + case MSVCRT__RC_NEAR: return 1; +#ifdef _WIN64 + case MSVCRT__RC_UP: return 3; + default: return 2; +#else + case MSVCRT__RC_UP: return 2; + default: return 3; +#endif + } +} + +#endif /* _MSVCR_VER>=140 */