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