Piotr Caban : msvcp: Add _Exp implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Oct 2 09:21:48 CDT 2015


Module: wine
Branch: master
Commit: ce24b284eeabba8c7b0c8e9b6163f770e9207da9
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ce24b284eeabba8c7b0c8e9b6163f770e9207da9

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Thu Oct  1 18:43:18 2015 +0200

msvcp: Add _Exp implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>

---

 dlls/msvcp100/msvcp100.spec         |  4 +-
 dlls/msvcp110/msvcp110.spec         |  4 +-
 dlls/msvcp120/msvcp120.spec         |  4 +-
 dlls/msvcp120/tests/msvcp120.c      | 76 +++++++++++++++++++++++++++++++++++++
 dlls/msvcp120_app/msvcp120_app.spec |  4 +-
 dlls/msvcp60/msvcp60.spec           |  4 +-
 dlls/msvcp70/msvcp70.spec           |  4 +-
 dlls/msvcp71/msvcp71.spec           |  4 +-
 dlls/msvcp80/msvcp80.spec           |  4 +-
 dlls/msvcp90/math.c                 | 42 ++++++++++++++++++++
 dlls/msvcp90/msvcp90.spec           |  4 +-
 11 files changed, 136 insertions(+), 18 deletions(-)

diff --git a/dlls/msvcp100/msvcp100.spec b/dlls/msvcp100/msvcp100.spec
index c5d8fcc..d2b75f4 100644
--- a/dlls/msvcp100/msvcp100.spec
+++ b/dlls/msvcp100/msvcp100.spec
@@ -2894,14 +2894,14 @@
 @ cdecl _Dscale(ptr long)
 @ cdecl _Dtest(ptr)
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDnorm
 @ cdecl _FDscale(ptr long)
 @ cdecl _FDtest(ptr)
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps
diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec
index a3776cf..b8d21eb 100644
--- a/dlls/msvcp110/msvcp110.spec
+++ b/dlls/msvcp110/msvcp110.spec
@@ -3748,7 +3748,7 @@
 @ cdecl _Dtest(ptr)
 @ stub _Dunscale
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDint
@@ -3758,7 +3758,7 @@
 @ cdecl _FDtest(ptr)
 @ stub _FDunscale
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps
diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec
index 2b07f13..0458b01 100644
--- a/dlls/msvcp120/msvcp120.spec
+++ b/dlls/msvcp120/msvcp120.spec
@@ -3689,7 +3689,7 @@
 @ cdecl _Dtest(ptr)
 @ stub _Dunscale
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDint
@@ -3699,7 +3699,7 @@
 @ cdecl _FDtest(ptr)
 @ stub _FDunscale
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 @ stub _FPlsw
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 358c408..d754191 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -19,6 +19,7 @@
 #include <locale.h>
 #include <stdio.h>
 #include <math.h>
+#include <limits.h>
 
 #include "wine/test.h"
 #include "winbase.h"
@@ -65,6 +66,22 @@ enum file_type {
     type_unknown
 };
 
+static BOOL compare_float(float f, float g, unsigned int ulps)
+{
+    int x = *(int *)&f;
+    int y = *(int *)&g;
+
+    if (x < 0)
+        x = INT_MIN - x;
+    if (y < 0)
+        y = INT_MIN - y;
+
+    if (abs(x - y) > ulps)
+        return FALSE;
+
+    return TRUE;
+}
+
 static inline const char* debugstr_longlong(ULONGLONG ll)
 {
     static char string[17];
@@ -87,6 +104,7 @@ static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *
 static void (CDECL *p__Do_call)(void *this);
 static short (__cdecl *p__Dtest)(double *d);
 static short (__cdecl *p__Dscale)(double *d, int exp);
+static short (__cdecl *p__FExp)(float *x, float y, int exp);
 
 /* filesystem */
 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
@@ -142,6 +160,8 @@ static BOOL init(void)
             "_Dtest");
     SET(p__Dscale,
             "_Dscale");
+    SET(p__FExp,
+            "_FExp");
     if(sizeof(void*) == 8) { /* 64-bit initialization */
         SET(p_tr2_sys__File_size,
                 "?_File_size at sys@tr2 at std@@YA_KPEBD at Z");
@@ -514,6 +534,61 @@ static void test__Dscale(void)
     ok(ret == FP_NAN, "ret = %x\n", ret);
 }
 
+static void test__FExp(void)
+{
+    float d;
+    short ret;
+
+    d = 0;
+    ret = p__FExp(&d, 0, 0);
+    ok(d == 0, "d = %f\n", d);
+    ok(ret == FP_ZERO, "ret = %x\n", ret);
+
+    d = 0;
+    ret = p__FExp(&d, 1, 0);
+    ok(d == 1.0, "d = %f\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+
+    d = 0;
+    ret = p__FExp(&d, 1, 1);
+    ok(d == 2.0, "d = %f\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+
+    d = 0;
+    ret = p__FExp(&d, 1, 2);
+    ok(d == 4.0, "d = %f\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+
+    d = 0;
+    ret = p__FExp(&d, 10, 0);
+    ok(d == 10.0, "d = %f\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+
+    d = 1;
+    ret = p__FExp(&d, 0, 0);
+    ok(d == 0, "d = %f\n", d);
+    ok(ret == FP_ZERO, "ret = %x\n", ret);
+
+    d = 1;
+    ret = p__FExp(&d, 1, 0);
+    ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+
+    d = 9e20;
+    ret = p__FExp(&d, 0, 0);
+    ok(d == 0, "d = %f\n", d);
+    ok(ret == FP_ZERO, "ret = %x\n", ret);
+
+    d = 90;
+    ret = p__FExp(&d, 1, 0);
+    ok(ret == FP_INFINITE, "ret = %x\n", ret);
+
+    d = 90;
+    ret = p__FExp(&d, 1, -50);
+    ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
+    ok(ret == FP_NORMAL, "ret = %x\n", ret);
+}
+
 static void test_tr2_sys__File_size(void)
 {
     ULONGLONG val;
@@ -1055,6 +1130,7 @@ START_TEST(msvcp120)
     test__Do_call();
     test__Dtest();
     test__Dscale();
+    test__FExp();
 
     test_tr2_sys__File_size();
     test_tr2_sys__Equivalent();
diff --git a/dlls/msvcp120_app/msvcp120_app.spec b/dlls/msvcp120_app/msvcp120_app.spec
index 1470b3c..2598904 100644
--- a/dlls/msvcp120_app/msvcp120_app.spec
+++ b/dlls/msvcp120_app/msvcp120_app.spec
@@ -3689,7 +3689,7 @@
 @ cdecl _Dtest(ptr) msvcp120._Dtest
 @ stub _Dunscale
 @ extern _Eps msvcp120._Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long) msvcp120._Exp
 @ stub _FCosh
 @ extern _FDenorm msvcp120._FDenorm
 @ stub _FDint
@@ -3699,7 +3699,7 @@
 @ cdecl _FDtest(ptr) msvcp120._FDtest
 @ stub _FDunscale
 @ extern _FEps msvcp120._FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long) msvcp120._FExp
 @ extern _FInf msvcp120._FInf
 @ extern _FNan msvcp120._FNan
 @ stub _FPlsw
diff --git a/dlls/msvcp60/msvcp60.spec b/dlls/msvcp60/msvcp60.spec
index 05d0435..48f1add 100644
--- a/dlls/msvcp60/msvcp60.spec
+++ b/dlls/msvcp60/msvcp60.spec
@@ -4260,14 +4260,14 @@
 @ cdecl _Dscale(ptr long)
 @ cdecl _Dtest(ptr)
 @ extern _Eps _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm _FDenorm
 @ stub _FDnorm
 @ cdecl _FDscale(ptr long)
 @ cdecl _FDtest(ptr)
 @ extern _FEps _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf _FInf
 @ extern _FNan _FNan
 # extern _FRteps
diff --git a/dlls/msvcp70/msvcp70.spec b/dlls/msvcp70/msvcp70.spec
index a6f5ef3..f97c87c 100644
--- a/dlls/msvcp70/msvcp70.spec
+++ b/dlls/msvcp70/msvcp70.spec
@@ -5046,14 +5046,14 @@
 @ cdecl _Dscale(ptr long)
 @ cdecl _Dtest(ptr)
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDnorm
 @ cdecl _FDscale(ptr long)
 @ cdecl _FDtest(ptr)
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps
diff --git a/dlls/msvcp71/msvcp71.spec b/dlls/msvcp71/msvcp71.spec
index ba2fcaf..46e5213 100644
--- a/dlls/msvcp71/msvcp71.spec
+++ b/dlls/msvcp71/msvcp71.spec
@@ -5100,14 +5100,14 @@
 @ cdecl _Dscale(ptr long)
 @ cdecl _Dtest(ptr)
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDnorm
 @ cdecl _FDscale(ptr long)
 @ cdecl _FDtest(ptr)
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps
diff --git a/dlls/msvcp80/msvcp80.spec b/dlls/msvcp80/msvcp80.spec
index d801608..f6bec69 100644
--- a/dlls/msvcp80/msvcp80.spec
+++ b/dlls/msvcp80/msvcp80.spec
@@ -5708,7 +5708,7 @@
 @ cdecl _Dtest(ptr)
 @ stub _Dunscale
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDnorm
@@ -5717,7 +5717,7 @@
 @ cdecl _FDtest(ptr)
 @ stub _FDunscale
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps
diff --git a/dlls/msvcp90/math.c b/dlls/msvcp90/math.c
index 2d9996db..6c3a33a 100644
--- a/dlls/msvcp90/math.c
+++ b/dlls/msvcp90/math.c
@@ -2274,3 +2274,45 @@ short __cdecl _FDscale(float *x, int exp)
     *x *= pow(2, exp);
     return dclass(*x);
 }
+
+/* _Exp */
+/* computes y * e^(*x) * 2^scale */
+short __cdecl _Exp(double *x, double y, int scale)
+{
+    double ed;
+    int e;
+
+    if(y == 0) {
+        *x = 0;
+        return FP_ZERO;
+    }
+
+    *x /= M_LN2;
+    ed = floor(*x);
+    *x -= ed;
+    e = ed;
+
+    if(ed!=e && ed>0)
+        scale = INT_MAX;
+    else if(ed!=e && ed<0)
+        scale = INT_MIN;
+    else if(scale>0 && e>0 && scale+e<=0)
+        scale = INT_MAX;
+    else if(scale<0 && e<0 && scale+e>=0)
+        scale = INT_MIN;
+    else
+        scale += e;
+
+    *x = y * pow(2.0, *x);
+    return _Dscale(x, scale);
+}
+
+/* _FExp */
+short __cdecl _FExp(float *x, float y, short scale)
+{
+    double d = *x;
+    _Exp(&d, y, scale);
+    *x = d;
+
+    return dclass(*x);
+}
diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec
index f2e3a5b..a0ba849 100644
--- a/dlls/msvcp90/msvcp90.spec
+++ b/dlls/msvcp90/msvcp90.spec
@@ -6482,14 +6482,14 @@
 @ cdecl _Dscale(ptr long)
 @ cdecl _Dtest(ptr)
 @ extern _Eps
-@ stub _Exp
+@ cdecl _Exp(ptr double long)
 @ stub _FCosh
 @ extern _FDenorm
 @ stub _FDnorm
 @ cdecl _FDscale(ptr long)
 @ cdecl _FDtest(ptr)
 @ extern _FEps
-@ stub _FExp
+@ cdecl _FExp(ptr float long)
 @ extern _FInf
 @ extern _FNan
 # extern _FRteps




More information about the wine-cvs mailing list