Commit 6b6f3406 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

ucrtbase: Add __fpe_flt_rounds implementation.

Based on a patch by Alex Henrie. Signed-off-by: 's avatarPiotr Caban <piotr@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 10f58a5e
@ stub _Exit @ stub _Exit
@ cdecl -arch=i386 __control87_2(long long ptr ptr) ucrtbase.__control87_2 @ cdecl -arch=i386 __control87_2(long long ptr ptr) ucrtbase.__control87_2
@ cdecl __doserrno() ucrtbase.__doserrno @ cdecl __doserrno() ucrtbase.__doserrno
@ stub __fpe_flt_rounds @ cdecl __fpe_flt_rounds() ucrtbase.__fpe_flt_rounds
@ cdecl __fpecode() ucrtbase.__fpecode @ cdecl __fpecode() ucrtbase.__fpecode
@ cdecl __p___argc() ucrtbase.__p___argc @ cdecl __p___argc() ucrtbase.__p___argc
@ cdecl __p___argv() ucrtbase.__p___argv @ cdecl __p___argv() ucrtbase.__p___argv
......
...@@ -1199,6 +1199,28 @@ int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask ...@@ -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.@) * _copysign (MSVCRT.@)
*/ */
double CDECL MSVCRT__copysign(double num, double sign) double CDECL MSVCRT__copysign(double num, double sign)
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <wchar.h> #include <wchar.h>
#include <stdio.h> #include <stdio.h>
#include <float.h>
#include <windef.h> #include <windef.h>
#include <winbase.h> #include <winbase.h>
...@@ -38,6 +39,8 @@ typedef struct MSVCRT__onexit_table_t ...@@ -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_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_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_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) static void test__initialize_onexit_table(void)
{ {
...@@ -211,20 +214,58 @@ static void test__execute_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); 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"); 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_initialize_onexit_table = (void*)GetProcAddress(module, "_initialize_onexit_table");
p_register_onexit_function = (void*)GetProcAddress(module, "_register_onexit_function"); p_register_onexit_function = (void*)GetProcAddress(module, "_register_onexit_function");
p_execute_onexit_table = (void*)GetProcAddress(module, "_execute_onexit_table"); 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) START_TEST(misc)
{ {
init(); if(!init())
return;
test__initialize_onexit_table(); test__initialize_onexit_table();
test__register_onexit_function(); test__register_onexit_function();
test__execute_onexit_table(); test__execute_onexit_table();
test___fpe_flt_rounds();
} }
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
@ stub __dcrt_initial_narrow_environment @ stub __dcrt_initial_narrow_environment
@ cdecl __doserrno() MSVCRT___doserrno @ cdecl __doserrno() MSVCRT___doserrno
@ cdecl __dstbias() MSVCRT___p__dstbias @ cdecl __dstbias() MSVCRT___p__dstbias
@ stub __fpe_flt_rounds @ cdecl __fpe_flt_rounds()
@ cdecl __fpecode() @ cdecl __fpecode()
@ stub __initialize_lconv_for_unsigned_char @ stub __initialize_lconv_for_unsigned_char
@ stub __intrinsic_abnormal_termination @ stub __intrinsic_abnormal_termination
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment