Piotr Caban : msvcrt: Import fmodf implementation from musl.
Alexandre Julliard
julliard at winehq.org
Tue May 18 15:42:38 CDT 2021
Module: wine
Branch: master
Commit: bc5f28888ce57514dc7a7b4eec316d3327bcbb51
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bc5f28888ce57514dc7a7b4eec316d3327bcbb51
Author: Piotr Caban <piotr at codeweavers.com>
Date: Tue May 18 19:08:28 2021 +0200
msvcrt: Import fmodf implementation from musl.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/math.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++-----
dlls/msvcrt/unixlib.c | 9 -------
dlls/msvcrt/unixlib.h | 1 -
3 files changed, 64 insertions(+), 16 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index d71a7108b5d..de0db9cca50 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -620,12 +620,70 @@ float CDECL expf( float x )
/*********************************************************************
* fmodf (MSVCRT.@)
+ *
+ * Copied from musl: src/math/fmodf.c
*/
float CDECL fmodf( float x, float y )
{
- float ret = unix_funcs->fmodf( x, y );
- if (!isfinite(x) || !isfinite(y)) return math_error(_DOMAIN, "fmodf", x, 0, ret);
- return ret;
+ UINT32 xi = *(UINT32*)&x;
+ UINT32 yi = *(UINT32*)&y;
+ int ex = xi>>23 & 0xff;
+ int ey = yi>>23 & 0xff;
+ UINT32 sx = xi & 0x80000000;
+ UINT32 i;
+
+ if (isinf(x)) return math_error(_DOMAIN, "fmodf", x, y, (x * y) / (x * y));
+ if (yi << 1 == 0 || isnan(y) || ex == 0xff)
+ return (x * y) / (x * y);
+ if (xi << 1 <= yi << 1) {
+ if (xi << 1 == yi << 1)
+ return 0 * x;
+ return x;
+ }
+
+ /* normalize x and y */
+ if (!ex) {
+ for (i = xi << 9; i >> 31 == 0; ex--, i <<= 1);
+ xi <<= -ex + 1;
+ } else {
+ xi &= -1U >> 9;
+ xi |= 1U << 23;
+ }
+ if (!ey) {
+ for (i = yi << 9; i >> 31 == 0; ey--, i <<= 1);
+ yi <<= -ey + 1;
+ } else {
+ yi &= -1U >> 9;
+ yi |= 1U << 23;
+ }
+
+ /* x mod y */
+ for (; ex > ey; ex--) {
+ i = xi - yi;
+ if (i >> 31 == 0) {
+ if (i == 0)
+ return 0 * x;
+ xi = i;
+ }
+ xi <<= 1;
+ }
+ i = xi - yi;
+ if (i >> 31 == 0) {
+ if (i == 0)
+ return 0 * x;
+ xi = i;
+ }
+ for (; xi>>23 == 0; xi <<= 1, ex--);
+
+ /* scale result up */
+ if (ex > 0) {
+ xi -= 1U << 23;
+ xi |= (UINT32)ex << 23;
+ } else {
+ xi >>= -ex + 1;
+ }
+ xi |= sx;
+ return *(float*)ξ
}
/*********************************************************************
@@ -633,9 +691,9 @@ float CDECL fmodf( float x, float y )
*/
float CDECL logf( float x )
{
- float ret = unix_funcs->logf( x );
- if (x < 0.0) return math_error(_DOMAIN, "logf", x, 0, ret);
- if (x == 0.0) return math_error(_SING, "logf", x, 0, ret);
+ float ret = unix_funcs->logf( x );
+ if (x < 0.0) return math_error(_DOMAIN, "logf", x, 0, ret);
+ if (x == 0.0) return math_error(_SING, "logf", x, 0, ret);
return ret;
}
diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c
index 69ce6bb027e..a2bae9c6e5e 100644
--- a/dlls/msvcrt/unixlib.c
+++ b/dlls/msvcrt/unixlib.c
@@ -297,14 +297,6 @@ static float CDECL unix_fmaf( float x, float y, float z )
#endif
}
-/*********************************************************************
- * fmodf
- */
-static float CDECL unix_fmodf( float x, float y )
-{
- return fmodf( x, y );
-}
-
/*********************************************************************
* frexp
*/
@@ -665,7 +657,6 @@ static const struct unix_funcs funcs =
unix_expm1f,
unix_fma,
unix_fmaf,
- unix_fmodf,
unix_frexp,
unix_frexpf,
unix_hypot,
diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h
index c1cd2c60d29..edb9e99d3e4 100644
--- a/dlls/msvcrt/unixlib.h
+++ b/dlls/msvcrt/unixlib.h
@@ -45,7 +45,6 @@ struct unix_funcs
float (CDECL *expm1f)(float x);
double (CDECL *fma)(double x, double y, double z);
float (CDECL *fmaf)(float x, float y, float z);
- float (CDECL *fmodf)(float x, float y);
double (CDECL *frexp)(double x, int *exp);
float (CDECL *frexpf)(float x, int *exp);
double (CDECL *hypot)(double x, double y);
More information about the wine-cvs
mailing list