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