ucrtbase: Add __fpe_flt_rounds implementation.

Based on a patch by Alex Henrie.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2016-06-13 11:34:49 +02:00 committed by Alexandre Julliard
parent 10f58a5e25
commit 6b6f3406f4
4 changed files with 67 additions and 4 deletions

View File

@ -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

View File

@ -1198,6 +1198,28 @@ int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask
return 0;
}
/*********************************************************************
* __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.@)
*/

View File

@ -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();
}

View File

@ -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