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