Module: wine Branch: master Commit: c7fa4673769c42bfb1b44ebfc7c981b458784e5a URL: https://source.winehq.org/git/wine.git/?a=commit;h=c7fa4673769c42bfb1b44ebfc...
Author: Piotr Caban piotr@codeweavers.com Date: Tue May 18 19:09:00 2021 +0200
msvcrt: Import remquo implementation from musl.
Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
configure | 1 - configure.ac | 1 - dlls/msvcrt/math.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-- dlls/msvcrt/unixlib.c | 14 --------- dlls/msvcrt/unixlib.h | 1 - include/config.h.in | 3 -- 6 files changed, 78 insertions(+), 23 deletions(-)
diff --git a/configure b/configure index ac738ca964b..b243f0280f5 100755 --- a/configure +++ b/configure @@ -19640,7 +19640,6 @@ for ac_func in \ log2f \ remainder \ remainderf \ - remquo \ remquof \ tgamma \ tgammaf diff --git a/configure.ac b/configure.ac index 4c98c3e5597..8942a3eefc2 100644 --- a/configure.ac +++ b/configure.ac @@ -2680,7 +2680,6 @@ AC_CHECK_FUNCS(\ log2f \ remainder \ remainderf \ - remquo \ remquof \ tgamma \ tgammaf diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index fab505abfb5..f4c5c69fc4b 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -5496,12 +5496,87 @@ float CDECL remainderf(float x, float y)
/********************************************************************* * remquo (MSVCR120.@) + * + * Copied from musl: src/math/remquo.c */ double CDECL remquo(double x, double y, int *quo) { - if(!isfinite(x)) *_errno() = EDOM; - if(isnan(y) || y==0.0) *_errno() = EDOM; - return unix_funcs->remquo( x, y, quo ); + UINT64 uxi = *(UINT64*)&x; + UINT64 uyi = *(UINT64*)&y; + int ex = uxi >> 52 & 0x7ff; + int ey = uyi >> 52 & 0x7ff; + int sx = uxi >> 63; + int sy = uyi >> 63; + UINT32 q; + UINT64 i; + + *quo = 0; + if (y == 0 || isinf(x)) *_errno() = EDOM; + if (uyi << 1 == 0 || isnan(y) || ex == 0x7ff) + return (x * y) / (x * y); + if (uxi << 1 == 0) + return x; + + /* normalize x and y */ + if (!ex) { + for (i = uxi << 12; i >> 63 == 0; ex--, i <<= 1); + uxi <<= -ex + 1; + } else { + uxi &= -1ULL >> 12; + uxi |= 1ULL << 52; + } + if (!ey) { + for (i = uyi << 12; i >> 63 == 0; ey--, i <<= 1); + uyi <<= -ey + 1; + } else { + uyi &= -1ULL >> 12; + uyi |= 1ULL << 52; + } + + q = 0; + if (ex < ey) { + if (ex+1 == ey) + goto end; + return x; + } + + /* x mod y */ + for (; ex > ey; ex--) { + i = uxi - uyi; + if (i >> 63 == 0) { + uxi = i; + q++; + } + uxi <<= 1; + q <<= 1; + } + i = uxi - uyi; + if (i >> 63 == 0) { + uxi = i; + q++; + } + if (uxi == 0) + ex = -60; + else + for (; uxi >> 52 == 0; uxi <<= 1, ex--); +end: + /* scale result and decide between |x| and |x|-|y| */ + if (ex > 0) { + uxi -= 1ULL << 52; + uxi |= (UINT64)ex << 52; + } else { + uxi >>= -ex + 1; + } + x = *(double*)&uxi; + if (sy) + y = -y; + if (ex == ey || (ex + 1 == ey && (2 * x > y || (2 * x == y && q % 2)))) { + x -= y; + q++; + } + q &= 0x7fffffff; + *quo = sx ^ sy ? -(int)q : (int)q; + return sx ? -x : x; }
/********************************************************************* diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c index 62c6a5ae189..05d8c2bd83a 100644 --- a/dlls/msvcrt/unixlib.c +++ b/dlls/msvcrt/unixlib.c @@ -501,19 +501,6 @@ static float CDECL unix_remainderf(float x, float y) #endif }
-/********************************************************************* - * remquo - */ -static double CDECL unix_remquo(double x, double y, int *quo) -{ -#ifdef HAVE_REMQUO - return remquo(x, y, quo); -#else - FIXME( "not implemented\n" ); - return 0; -#endif -} - /********************************************************************* * remquof */ @@ -662,7 +649,6 @@ static const struct unix_funcs funcs = unix_powf, unix_remainder, unix_remainderf, - unix_remquo, unix_remquof, unix_sin, unix_sinf, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 69f4e02f321..9f91c097d71 100644 --- a/dlls/msvcrt/unixlib.h +++ b/dlls/msvcrt/unixlib.h @@ -66,7 +66,6 @@ struct unix_funcs float (CDECL *powf)(float x, float y); double (CDECL *remainder)(double x, double y); float (CDECL *remainderf)(float x, float y); - double (CDECL *remquo)(double x, double y, int *quo); float (CDECL *remquof)(float x, float y, int *quo); double (CDECL *sin)(double x); float (CDECL *sinf)(float x); diff --git a/include/config.h.in b/include/config.h.in index bf7fc0d4e9b..7d0c5e934e6 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -636,9 +636,6 @@ /* Define to 1 if you have the `remainderf' function. */ #undef HAVE_REMAINDERF
-/* Define to 1 if you have the `remquo' function. */ -#undef HAVE_REMQUO - /* Define to 1 if you have the `remquof' function. */ #undef HAVE_REMQUOF