Piotr Caban : msvcrt: Import fmod implementation from musl.

Alexandre Julliard julliard at winehq.org
Tue May 18 15:42:38 CDT 2021


Module: wine
Branch: master
Commit: 2e8cfcf5b5e58566615812af0bab602f3bf7c654
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2e8cfcf5b5e58566615812af0bab602f3bf7c654

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue May 18 19:08:17 2021 +0200

msvcrt: Import fmod 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    | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---
 dlls/msvcrt/unixlib.c |  9 --------
 dlls/msvcrt/unixlib.h |  1 -
 3 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index f2caa81712b..d71a7108b5d 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -1266,12 +1266,70 @@ double CDECL exp( double x )
 
 /*********************************************************************
  *		fmod (MSVCRT.@)
+ *
+ * Copied from musl: src/math/fmod.c
  */
 double CDECL fmod( double x, double y )
 {
-  double ret = unix_funcs->fmod( x, y );
-  if (!isfinite(x) || !isfinite(y)) return math_error(_DOMAIN, "fmod", x, y, ret);
-  return ret;
+    UINT64 xi = *(UINT64*)&x;
+    UINT64 yi = *(UINT64*)&y;
+    int ex = xi >> 52 & 0x7ff;
+    int ey = yi >> 52 & 0x7ff;
+    int sx = xi >> 63;
+    UINT64 i;
+
+    if (isinf(x)) return math_error(_DOMAIN, "fmod", x, y, (x * y) / (x * y));
+    if (yi << 1 == 0 || isnan(y) || ex == 0x7ff)
+        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 << 12; i >> 63 == 0; ex--, i <<= 1);
+        xi <<= -ex + 1;
+    } else {
+        xi &= -1ULL >> 12;
+        xi |= 1ULL << 52;
+    }
+    if (!ey) {
+        for (i = yi << 12; i >> 63 == 0; ey--, i <<= 1);
+        yi <<= -ey + 1;
+    } else {
+        yi &= -1ULL >> 12;
+        yi |= 1ULL << 52;
+    }
+
+    /* x mod y */
+    for (; ex > ey; ex--) {
+        i = xi - yi;
+        if (i >> 63 == 0) {
+            if (i == 0)
+                return 0 * x;
+            xi = i;
+        }
+        xi <<= 1;
+    }
+    i = xi - yi;
+    if (i >> 63 == 0) {
+        if (i == 0)
+            return 0 * x;
+        xi = i;
+    }
+    for (; xi >> 52 == 0; xi <<= 1, ex--);
+
+    /* scale result */
+    if (ex > 0) {
+        xi -= 1ULL << 52;
+        xi |= (UINT64)ex << 52;
+    } else {
+        xi >>= -ex + 1;
+    }
+    xi |= (UINT64)sx << 63;
+    return *(double*)ξ
 }
 
 /*********************************************************************
diff --git a/dlls/msvcrt/unixlib.c b/dlls/msvcrt/unixlib.c
index d7e368d1b37..69ce6bb027e 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
 }
 
-/*********************************************************************
- *      fmod
- */
-static double CDECL unix_fmod( double x, double y )
-{
-    return fmod( x, y );
-}
-
 /*********************************************************************
  *      fmodf
  */
@@ -673,7 +665,6 @@ static const struct unix_funcs funcs =
     unix_expm1f,
     unix_fma,
     unix_fmaf,
-    unix_fmod,
     unix_fmodf,
     unix_frexp,
     unix_frexpf,
diff --git a/dlls/msvcrt/unixlib.h b/dlls/msvcrt/unixlib.h
index b8c18b1e2a5..c1cd2c60d29 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);
-    double          (CDECL *fmod)(double x, double y);
     float           (CDECL *fmodf)(float x, float y);
     double          (CDECL *frexp)(double x, int *exp);
     float           (CDECL *frexpf)(float x, int *exp);




More information about the wine-cvs mailing list