mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 11:43:31 +00:00
msvcp: Add _Exp implementation.
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
This commit is contained in:
parent
643ff988c4
commit
ce24b284ee
11 changed files with 136 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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@sys@tr2@std@@YA_KPEBD@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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue