From 8a2f7c731fcf5bf21449f1cd8eadad8305472621 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 18 May 2021 19:09:07 +0200 Subject: [PATCH] msvcrt: Import remquof implementation from musl. Signed-off-by: Piotr Caban Signed-off-by: Alexandre Julliard --- configure | 1 - configure.ac | 1 - dlls/msvcrt/math.c | 80 +++++++++++++++++++++++++++++++++++++++++-- dlls/msvcrt/unixlib.c | 14 -------- dlls/msvcrt/unixlib.h | 1 - include/config.h.in | 3 -- 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/configure b/configure index b243f0280f5..0ec898ca762 100755 --- a/configure +++ b/configure @@ -19640,7 +19640,6 @@ for ac_func in \ log2f \ remainder \ remainderf \ - remquof \ tgamma \ tgammaf diff --git a/configure.ac b/configure.ac index 8942a3eefc2..72db35563e7 100644 --- a/configure.ac +++ b/configure.ac @@ -2680,7 +2680,6 @@ AC_CHECK_FUNCS(\ log2f \ remainder \ remainderf \ - remquof \ tgamma \ tgammaf ) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index f4c5c69fc4b..ae3b9aa76e6 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -5581,12 +5581,86 @@ end: /********************************************************************* * remquof (MSVCR120.@) + * + * Copied from musl: src/math/remquof.c */ float CDECL remquof(float x, float y, int *quo) { - if(!isfinite(x)) *_errno() = EDOM; - if(isnan(y) || y==0.0f) *_errno() = EDOM; - return unix_funcs->remquof( x, y, quo ); + UINT32 uxi = *(UINT32*)&x; + UINT32 uyi = *(UINT32*)&y; + int ex = uxi >> 23 & 0xff; + int ey = uyi >> 23 & 0xff; + int sx = uxi >> 31; + int sy = uyi>> 31; + UINT32 q, i; + + *quo = 0; + if (y == 0 || isinf(x)) *_errno() = EDOM; + if (uyi << 1 == 0 || isnan(y) || ex == 0xff) + return (x * y) / (x * y); + if (uxi << 1 == 0) + return x; + + /* normalize x and y */ + if (!ex) { + for (i = uxi << 9; i >> 31 == 0; ex--, i <<= 1); + uxi <<= -ex + 1; + } else { + uxi &= -1U >> 9; + uxi |= 1U << 23; + } + if (!ey) { + for (i = uyi << 9; i >> 31 == 0; ey--, i <<= 1); + uyi <<= -ey + 1; + } else { + uyi &= -1U >> 9; + uyi |= 1U << 23; + } + + 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 >> 31 == 0) { + uxi = i; + q++; + } + uxi <<= 1; + q <<= 1; + } + i = uxi - uyi; + if (i >> 31 == 0) { + uxi = i; + q++; + } + if (uxi == 0) + ex = -30; + else + for (; uxi >> 23 == 0; uxi <<= 1, ex--); +end: + /* scale result and decide between |x| and |x|-|y| */ + if (ex > 0) { + uxi -= 1U << 23; + uxi |= (UINT32)ex << 23; + } else { + uxi >>= -ex + 1; + } + x = *(float*)&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 05d8c2bd83a..cd22d36acb4 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 } -/********************************************************************* - * remquof - */ -static float CDECL unix_remquof(float x, float y, int *quo) -{ -#ifdef HAVE_REMQUOF - return remquof(x, y, quo); -#else - FIXME( "not implemented\n" ); - return 0; -#endif -} - /********************************************************************* * sin */ @@ -649,7 +636,6 @@ static const struct unix_funcs funcs = unix_powf, unix_remainder, unix_remainderf, - unix_remquof, unix_sin, unix_sinf, unix_sinh, diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h index 9f91c097d71..f71ceea1cab 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); - float (CDECL *remquof)(float x, float y, int *quo); double (CDECL *sin)(double x); float (CDECL *sinf)(float x); double (CDECL *sinh)(double x); diff --git a/include/config.h.in b/include/config.h.in index 7d0c5e934e6..1d54a041ce2 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 `remquof' function. */ -#undef HAVE_REMQUOF - /* Define to 1 if the system has the type `request_sense'. */ #undef HAVE_REQUEST_SENSE