Piotr Caban : ucrtbase: Add __fpe_flt_rounds implementation.
Alexandre Julliard
julliard at winehq.org
Mon Jun 13 11:11:30 CDT 2016
Module: wine
Branch: master
Commit: 6b6f3406f4be92287f8f097803fd96811d785a05
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6b6f3406f4be92287f8f097803fd96811d785a05
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Jun 13 11:34:49 2016 +0200
ucrtbase: Add __fpe_flt_rounds implementation.
Based on a patch by Alex Henrie.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
.../api-ms-win-crt-runtime-l1-1-0.spec | 2 +-
dlls/msvcrt/math.c | 22 +++++++++++
dlls/ucrtbase/tests/misc.c | 45 +++++++++++++++++++++-
dlls/ucrtbase/ucrtbase.spec | 2 +-
4 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
index 9864c6c..8d96f98 100644
--- a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec
@@ -1,7 +1,7 @@
@ stub _Exit
@ cdecl -arch=i386 __control87_2(long long ptr ptr) ucrtbase.__control87_2
@ cdecl __doserrno() ucrtbase.__doserrno
-@ stub __fpe_flt_rounds
+@ cdecl __fpe_flt_rounds() ucrtbase.__fpe_flt_rounds
@ cdecl __fpecode() ucrtbase.__fpecode
@ cdecl __p___argc() ucrtbase.__p___argc
@ cdecl __p___argv() ucrtbase.__p___argv
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 402e8b2..3d2104b 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -1199,6 +1199,28 @@ int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask
}
/*********************************************************************
+ * __fpe_flt_rounds (UCRTBASE.@)
+ */
+int CDECL __fpe_flt_rounds(void)
+{
+ unsigned int fpc = _controlfp(0, 0) & MSVCRT__RC_CHOP;
+
+ TRACE("()\n");
+
+ switch(fpc) {
+ case MSVCRT__RC_CHOP: return 0;
+ case MSVCRT__RC_NEAR: return 1;
+#ifdef _WIN64
+ case MSVCRT__RC_UP: return 3;
+ default: return 2;
+#else
+ case MSVCRT__RC_UP: return 2;
+ default: return 3;
+#endif
+ }
+}
+
+/*********************************************************************
* _copysign (MSVCRT.@)
*/
double CDECL MSVCRT__copysign(double num, double sign)
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 63ea465..bfdf3c1 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>
+#include <float.h>
#include <windef.h>
#include <winbase.h>
@@ -38,6 +39,8 @@ typedef struct MSVCRT__onexit_table_t
static int (CDECL *p_initialize_onexit_table)(MSVCRT__onexit_table_t *table);
static int (CDECL *p_register_onexit_function)(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func);
static int (CDECL *p_execute_onexit_table)(MSVCRT__onexit_table_t *table);
+static int (CDECL *p___fpe_flt_rounds)(void);
+static unsigned int (CDECL *p__controlfp)(unsigned int, unsigned int);
static void test__initialize_onexit_table(void)
{
@@ -211,20 +214,58 @@ static void test__execute_onexit_table(void)
ok(g_onexit_called == 2, "got %d\n", g_onexit_called);
}
-static void init(void)
+static void test___fpe_flt_rounds(void)
+{
+ unsigned int cfp = p__controlfp(0, 0);
+ int ret;
+
+ if(!cfp) {
+ skip("_controlfp not supported\n");
+ return;
+ }
+
+ ok((p__controlfp(_RC_NEAR, _RC_CHOP) & _RC_CHOP) == _RC_NEAR, "_controlfp(_RC_NEAR, _RC_CHOP) failed\n");
+ ret = p___fpe_flt_rounds();
+ ok(ret == 1, "__fpe_flt_rounds returned %d\n", ret);
+
+ ok((p__controlfp(_RC_UP, _RC_CHOP) & _RC_CHOP) == _RC_UP, "_controlfp(_RC_UP, _RC_CHOP) failed\n");
+ ret = p___fpe_flt_rounds();
+ ok(ret == 2 + (sizeof(void*)>sizeof(int)), "__fpe_flt_rounds returned %d\n", ret);
+
+ ok((p__controlfp(_RC_DOWN, _RC_CHOP) & _RC_CHOP) == _RC_DOWN, "_controlfp(_RC_DOWN, _RC_CHOP) failed\n");
+ ret = p___fpe_flt_rounds();
+ ok(ret == 3 - (sizeof(void*)>sizeof(int)), "__fpe_flt_rounds returned %d\n", ret);
+
+ ok((p__controlfp(_RC_CHOP, _RC_CHOP) & _RC_CHOP) == _RC_CHOP, "_controlfp(_RC_CHOP, _RC_CHOP) failed\n");
+ ret = p___fpe_flt_rounds();
+ ok(ret == 0, "__fpe_flt_rounds returned %d\n", ret);
+}
+
+static BOOL init(void)
{
HMODULE module = LoadLibraryA("ucrtbase.dll");
+ if(!module) {
+ win_skip("ucrtbase.dll not available\n");
+ return FALSE;
+ }
+
p_initialize_onexit_table = (void*)GetProcAddress(module, "_initialize_onexit_table");
p_register_onexit_function = (void*)GetProcAddress(module, "_register_onexit_function");
p_execute_onexit_table = (void*)GetProcAddress(module, "_execute_onexit_table");
+ p___fpe_flt_rounds = (void*)GetProcAddress(module, "__fpe_flt_rounds");
+ p__controlfp = (void*)GetProcAddress(module, "_controlfp");
+
+ return TRUE;
}
START_TEST(misc)
{
- init();
+ if(!init())
+ return;
test__initialize_onexit_table();
test__register_onexit_function();
test__execute_onexit_table();
+ test___fpe_flt_rounds();
}
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index 9d65d3c..14ffa63 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -89,7 +89,7 @@
@ stub __dcrt_initial_narrow_environment
@ cdecl __doserrno() MSVCRT___doserrno
@ cdecl __dstbias() MSVCRT___p__dstbias
-@ stub __fpe_flt_rounds
+@ cdecl __fpe_flt_rounds()
@ cdecl __fpecode()
@ stub __initialize_lconv_for_unsigned_char
@ stub __intrinsic_abnormal_termination
More information about the wine-cvs
mailing list