mirror of
https://github.com/reactos/reactos.git
synced 2025-01-25 04:53:33 +08:00
[CRT_APITEST] Add tests for floating point control and status functions
This commit is contained in:
parent
5a9efc4081
commit
a82e46e521
285
modules/rostests/apitests/crt/fpcontrol.c
Normal file
285
modules/rostests/apitests/crt/fpcontrol.c
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/*
|
||||||
|
* PROJECT: ReactOS api tests
|
||||||
|
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||||
|
* PURPOSE: Tests for fp control functions
|
||||||
|
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <apitest.h>
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <pseh/pseh2.h>
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int get_native_fpcw(void)
|
||||||
|
{
|
||||||
|
#ifdef _M_AMD64
|
||||||
|
return _mm_getcsr();
|
||||||
|
#elif defined (_M_IX86)
|
||||||
|
unsigned short fpcw;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
__asm fstsw[fpcw];
|
||||||
|
#else
|
||||||
|
__asm__ __volatile__("fstsw %0" : "=m" (fpcw) : );
|
||||||
|
#endif
|
||||||
|
return fpcw;
|
||||||
|
#else
|
||||||
|
#error "Unsupported architecture"
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_native_fpcw(unsigned int value)
|
||||||
|
{
|
||||||
|
#ifdef _M_AMD64
|
||||||
|
_mm_setcsr(value);
|
||||||
|
#elif defined (_M_IX86)
|
||||||
|
unsigned short fpcw = (unsigned short)value;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
__asm fldcw[fpcw];
|
||||||
|
#else
|
||||||
|
__asm__ __volatile__("fldcw %0" : : "m" (fpcw));
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "Unsupported architecture"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
_clear87
|
||||||
|
_clearfp
|
||||||
|
_controlfp_s
|
||||||
|
_set_controlfp
|
||||||
|
_statusfp
|
||||||
|
__control87_2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
#define ON_IX86(x) x
|
||||||
|
#else
|
||||||
|
#define ON_IX86(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _M_AMD64
|
||||||
|
#define ON_AMD64(x) x
|
||||||
|
#else
|
||||||
|
#define ON_AMD64(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _M_ARM
|
||||||
|
#define ON_ARM(x) x
|
||||||
|
#else
|
||||||
|
#define ON_ARM(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int Value;
|
||||||
|
unsigned int Mask;
|
||||||
|
unsigned int Result;
|
||||||
|
unsigned int Native;
|
||||||
|
} g_controlfp_Testcases[] =
|
||||||
|
{
|
||||||
|
{ 0xffffffff, 0xffffffff, ON_IX86(0x30e031f) ON_AMD64(0x308031f) ON_ARM(0), ON_IX86(0) ON_AMD64(0xff80) ON_ARM(0) },
|
||||||
|
{ 0, 0xffffffff, 0x80000, ON_IX86(0) ON_AMD64(0x100) ON_ARM(0) },
|
||||||
|
{ 0xffffffff, 0x14, 0x80014, ON_IX86(0) ON_AMD64(0x580) ON_ARM(0) },
|
||||||
|
{ _EM_INEXACT, 0xffffffff, _EM_INEXACT | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_INEXACT | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _EM_UNDERFLOW, 0xffffffff, _EM_UNDERFLOW | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_UNDERFLOW | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _EM_OVERFLOW, 0xffffffff, _EM_OVERFLOW | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_OVERFLOW | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _EM_ZERODIVIDE, 0xffffffff, _EM_ZERODIVIDE | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_DIV_ZERO | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _EM_INVALID, 0xffffffff, _EM_INVALID | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_INVALID | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _RC_NEAR, 0xffffffff, _RC_NEAR | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_ROUND_NEAREST | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _RC_DOWN, 0xffffffff, _RC_DOWN | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_ROUND_DOWN | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _RC_UP, 0xffffffff, _RC_UP | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_ROUND_UP | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _RC_CHOP, 0xffffffff, _RC_CHOP | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_ROUND_TOWARD_ZERO | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _IC_AFFINE, 0xffffffff, _EM_DENORMAL ON_IX86(| _IC_AFFINE), ON_IX86(0) ON_AMD64(_MM_MASK_DENORM) ON_ARM(0)},
|
||||||
|
{ _IC_PROJECTIVE, 0xffffffff, _IC_PROJECTIVE | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _DN_SAVE, 0xffffffff, _DN_SAVE | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _DN_FLUSH, 0xffffffff, _DN_FLUSH | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_FLUSH_ZERO_ON | 0x40 | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _DN_FLUSH_OPERANDS_SAVE_RESULTS, 0xffffffff, _DN_FLUSH_OPERANDS_SAVE_RESULTS | _EM_DENORMAL, ON_IX86(0) ON_AMD64(0x40 | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
{ _DN_SAVE_OPERANDS_FLUSH_RESULTS, 0xffffffff, _DN_SAVE_OPERANDS_FLUSH_RESULTS | _EM_DENORMAL, ON_IX86(0) ON_AMD64(_MM_FLUSH_ZERO_ON | _MM_MASK_DENORM) ON_ARM(0) },
|
||||||
|
};
|
||||||
|
|
||||||
|
void Test_controlfp(void)
|
||||||
|
{
|
||||||
|
unsigned int i, native_fpcw, fpcw;
|
||||||
|
|
||||||
|
for (i = 0; i < _countof(g_controlfp_Testcases); i++)
|
||||||
|
{
|
||||||
|
fpcw = _controlfp(g_controlfp_Testcases[i].Value, g_controlfp_Testcases[i].Mask);
|
||||||
|
ok(fpcw == g_controlfp_Testcases[i].Result, "[%u] _controlfp failed: expected 0x%x, got 0x%x\n", i, g_controlfp_Testcases[i].Result, fpcw);
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
ok(native_fpcw == g_controlfp_Testcases[i].Native, "[%u] wrong native_fpcw: expected 0x%x, got 0x%x\n", i, g_controlfp_Testcases[i].Native, native_fpcw);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore sane state */
|
||||||
|
_fpreset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
void Test_control87(void)
|
||||||
|
{
|
||||||
|
unsigned int native_fpcw, fpcw;
|
||||||
|
|
||||||
|
fpcw = _control87(0, 0xffffffff);
|
||||||
|
ok(fpcw == 0, "_control87 failed: expected 0x%x, got 0x%x\n", 0, fpcw);
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
ok_hex(native_fpcw, ON_IX86(0) ON_AMD64(0));
|
||||||
|
|
||||||
|
/* Restore sane state */
|
||||||
|
_fpreset();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum _FP_OP
|
||||||
|
{
|
||||||
|
OP_Inexact,
|
||||||
|
OP_Underflow,
|
||||||
|
OP_Overflow,
|
||||||
|
OP_ZeroDivide,
|
||||||
|
OP_Invalid,
|
||||||
|
OP_Denormal
|
||||||
|
} FP_OP;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FP_OP Operation;
|
||||||
|
unsigned int Fpcw;
|
||||||
|
unsigned int FpStatus;
|
||||||
|
unsigned int ExceptionCode;
|
||||||
|
unsigned int Native;
|
||||||
|
} g_exception_Testcases[] =
|
||||||
|
{
|
||||||
|
{ OP_Inexact, 0xffffffff, _SW_UNDERFLOW | _SW_INEXACT ON_IX86(| _SW_DENORMAL), 0, ON_IX86(0x32) ON_AMD64(0xffb0) ON_ARM(0)},
|
||||||
|
{ OP_Inexact, ~_EM_INEXACT, _SW_INEXACT ON_AMD64(| _SW_UNDERFLOW), STATUS_FLOAT_INEXACT_RESULT, ON_IX86(0x3800) ON_AMD64(0xefb0) ON_ARM(0)},
|
||||||
|
{ OP_Inexact, ~_MCW_EM, _SW_INEXACT ON_AMD64(| _SW_UNDERFLOW), ON_IX86(STATUS_FLOAT_INEXACT_RESULT) ON_AMD64(STATUS_FLOAT_UNDERFLOW) ON_ARM(STATUS_FLOAT_UNDERFLOW), ON_IX86(0x3800) ON_AMD64(0xe130) ON_ARM(0) },
|
||||||
|
{ OP_Underflow, 0xffffffff, _SW_UNDERFLOW | _SW_INEXACT, 0, ON_IX86(0x30) ON_AMD64(0xffb0) ON_ARM(0)},
|
||||||
|
{ OP_Underflow, ~_EM_UNDERFLOW, _SW_UNDERFLOW | _SW_INEXACT, STATUS_FLOAT_UNDERFLOW, ON_IX86(0x3800) ON_AMD64(0xf7b0) ON_ARM(0) },
|
||||||
|
{ OP_Underflow, ~_MCW_EM, _SW_INEXACT ON_AMD64(| _SW_UNDERFLOW), ON_IX86(STATUS_FLOAT_INEXACT_RESULT) ON_AMD64(STATUS_FLOAT_UNDERFLOW) ON_ARM(STATUS_FLOAT_UNDERFLOW), ON_IX86(0x3800) ON_AMD64(0xe130) ON_ARM(0) },
|
||||||
|
{ OP_Overflow, 0xffffffff, _SW_OVERFLOW | _SW_INEXACT, 0, ON_IX86(0x28) ON_AMD64(0xffa8) ON_ARM(0) },
|
||||||
|
{ OP_Overflow, ~_EM_OVERFLOW, _SW_OVERFLOW | _SW_INEXACT, STATUS_FLOAT_OVERFLOW, ON_IX86(0x3800) ON_AMD64(0xfba8) ON_ARM(0) },
|
||||||
|
{ OP_Overflow, ~_MCW_EM, _SW_INEXACT ON_AMD64(| _SW_OVERFLOW), ON_IX86(STATUS_FLOAT_INEXACT_RESULT) ON_AMD64(STATUS_FLOAT_OVERFLOW) ON_ARM(STATUS_FLOAT_OVERFLOW), ON_IX86(0x3800) ON_AMD64(0xe128) ON_ARM(0)},
|
||||||
|
{ OP_ZeroDivide, 0xffffffff, _SW_ZERODIVIDE, 0, ON_IX86(0x4) ON_AMD64(0xff84) ON_ARM(0) },
|
||||||
|
{ OP_ZeroDivide, ~_EM_ZERODIVIDE, _SW_ZERODIVIDE, STATUS_FLOAT_DIVIDE_BY_ZERO, ON_IX86(0x3000) ON_AMD64(0xfd84) ON_ARM(0) },
|
||||||
|
{ OP_ZeroDivide, ~_MCW_EM, _SW_ZERODIVIDE, STATUS_FLOAT_DIVIDE_BY_ZERO, ON_IX86(0x3000) ON_AMD64(0xe104) ON_ARM(0) },
|
||||||
|
{ OP_Invalid, 0xffffffff, _SW_INVALID, 0, ON_IX86(0x1) ON_AMD64(0xff81) ON_ARM(0) },
|
||||||
|
{ OP_Invalid, ~_EM_INVALID, _SW_INVALID, STATUS_FLOAT_INVALID_OPERATION, ON_IX86(0) ON_AMD64(0xff01) ON_ARM(0) },
|
||||||
|
{ OP_Invalid, ~_MCW_EM, _SW_INVALID, STATUS_FLOAT_INVALID_OPERATION, ON_IX86(0) ON_AMD64(0xe101) ON_ARM(0) },
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64) // || defined(_M_ARM64) ?
|
||||||
|
{ OP_Denormal, 0xffffffff, _SW_DENORMAL | _SW_INEXACT ON_AMD64(| _SW_UNDERFLOW), 0, ON_IX86(0x22) ON_AMD64(0xffb2) ON_ARM(0)},
|
||||||
|
{ OP_Denormal, ~_EM_DENORMAL, _SW_DENORMAL, STATUS_FLOAT_INVALID_OPERATION, ON_IX86(0x3800) ON_AMD64(0xfe82) ON_ARM(0) },
|
||||||
|
{ OP_Denormal, ~_MCW_EM, _SW_DENORMAL, STATUS_FLOAT_INVALID_OPERATION, ON_IX86(0x3800) ON_AMD64(0xe002) ON_ARM(0) },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
void Test_exceptions(void)
|
||||||
|
{
|
||||||
|
volatile double a, b;
|
||||||
|
unsigned long long ull;
|
||||||
|
volatile long status = 0;
|
||||||
|
|
||||||
|
unsigned int i, exp_fpstatus, native_fpcw, statusfp;
|
||||||
|
|
||||||
|
for (i = 0; i < _countof(g_exception_Testcases); i++)
|
||||||
|
{
|
||||||
|
/* Start clean */
|
||||||
|
status = 0;
|
||||||
|
_fpreset();
|
||||||
|
_clearfp();
|
||||||
|
ok_hex(_statusfp(), 0);
|
||||||
|
|
||||||
|
_controlfp(g_exception_Testcases[i].Fpcw, 0xffffffff);
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64) // || defined(_M_ARM64) ?
|
||||||
|
if (g_exception_Testcases[i].Operation == OP_Denormal)
|
||||||
|
_control87(g_exception_Testcases[i].Fpcw, 0xffffffff);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
switch (g_exception_Testcases[i].Operation)
|
||||||
|
{
|
||||||
|
case OP_Inexact:
|
||||||
|
a = 1e-40;
|
||||||
|
b = (float)(a + 1e-40);
|
||||||
|
break;
|
||||||
|
case OP_Underflow:
|
||||||
|
a = DBL_MIN;
|
||||||
|
b = a / 3.0e16;
|
||||||
|
break;
|
||||||
|
case OP_Overflow:
|
||||||
|
a = DBL_MAX;
|
||||||
|
b = a * 3.0;
|
||||||
|
break;
|
||||||
|
case OP_ZeroDivide:
|
||||||
|
a = 0.0;
|
||||||
|
b = 1.0 / a;
|
||||||
|
break;
|
||||||
|
case OP_Invalid:
|
||||||
|
ull = 0x7FF0000000000001ull;
|
||||||
|
a = *(double*)&ull;
|
||||||
|
b = a * 2;
|
||||||
|
break;
|
||||||
|
case OP_Denormal:
|
||||||
|
a = DBL_MIN;
|
||||||
|
b = a - 4.9406564584124654e-324;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
(void)b;
|
||||||
|
}
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
statusfp = _clearfp();
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86
|
||||||
|
/* On x86 we need to clear before doing any other fp operations, otherwise it will throw again */
|
||||||
|
statusfp = _clearfp();
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
#else
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
statusfp = _clearfp();
|
||||||
|
#endif
|
||||||
|
status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
exp_fpstatus = g_exception_Testcases[i].FpStatus;
|
||||||
|
ok(statusfp == exp_fpstatus, "[%u] Wrong value for _statusfp(). Expected 0x%lx, got 0x%lx\n", i, exp_fpstatus, statusfp);
|
||||||
|
ok(status == g_exception_Testcases[i].ExceptionCode, "[%u] Wrong value for status. Expected 0x%lx, got 0x%lx\n", i, g_exception_Testcases[i].ExceptionCode, status);
|
||||||
|
ok(native_fpcw == g_exception_Testcases[i].Native, "[%u] wrong native_fpcw: expected 0x%x, got 0x%x\n", i, g_exception_Testcases[i].Native, native_fpcw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(fpcontrol)
|
||||||
|
{
|
||||||
|
unsigned int native_fpcw, fpcw, fpstatus;
|
||||||
|
|
||||||
|
/* Test native start fpcw */
|
||||||
|
native_fpcw = get_native_fpcw();
|
||||||
|
ok_hex(native_fpcw, ON_IX86(0) ON_AMD64(0x1f80) ON_ARM(0) );
|
||||||
|
|
||||||
|
/* Test start fpcw */
|
||||||
|
fpcw = _controlfp(0, 0);
|
||||||
|
ok_hex(fpcw, ON_IX86(0x9001f) ON_AMD64(0x8001f) ON_ARM(0));
|
||||||
|
|
||||||
|
/* Test start status */
|
||||||
|
fpstatus = _statusfp();
|
||||||
|
ok_hex(fpstatus, 0);
|
||||||
|
|
||||||
|
/* Test _fpreset */
|
||||||
|
fpcw = _controlfp(0, 0xffffffff);
|
||||||
|
ok_hex(fpcw, 0x80000);
|
||||||
|
_fpreset();
|
||||||
|
fpcw = _controlfp(0, 0);
|
||||||
|
ok_hex(fpcw, ON_IX86(0x9001f) ON_AMD64(0x8001f) ON_ARM(0));
|
||||||
|
|
||||||
|
Test_controlfp();
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
Test_control87();
|
||||||
|
#endif
|
||||||
|
Test_exceptions();
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
list(APPEND SOURCE_MSVCRT
|
list(APPEND SOURCE_MSVCRT
|
||||||
|
fpcontrol.c
|
||||||
# _CrtCheckMemory.c
|
# _CrtCheckMemory.c
|
||||||
# _CrtDbgBreak.c
|
# _CrtDbgBreak.c
|
||||||
# _CrtDbgReport.c
|
# _CrtDbgReport.c
|
||||||
@ -168,13 +169,9 @@ list(APPEND SOURCE_MSVCRT
|
|||||||
# _chsize_s
|
# _chsize_s
|
||||||
# _chvalidator
|
# _chvalidator
|
||||||
# _chvalidator_l
|
# _chvalidator_l
|
||||||
# _clearfp.c
|
|
||||||
# _close.c
|
# _close.c
|
||||||
# _commit.c
|
# _commit.c
|
||||||
# _commode
|
# _commode
|
||||||
# _control87.c
|
|
||||||
# _controlfp.c
|
|
||||||
# _controlfp_s.c
|
|
||||||
# _copysign.c
|
# _copysign.c
|
||||||
# _cprintf.c
|
# _cprintf.c
|
||||||
# _cprintf_l
|
# _cprintf_l
|
||||||
@ -665,7 +662,6 @@ list(APPEND SOURCE_MSVCRT
|
|||||||
# _searchenv.c
|
# _searchenv.c
|
||||||
# _searchenv_s.c
|
# _searchenv_s.c
|
||||||
# _set_SSE2_enable
|
# _set_SSE2_enable
|
||||||
# _set_controlfp
|
|
||||||
# _set_doserrno.c
|
# _set_doserrno.c
|
||||||
# _set_errno.c
|
# _set_errno.c
|
||||||
# _set_error_mode.c
|
# _set_error_mode.c
|
||||||
@ -717,7 +713,6 @@ list(APPEND SOURCE_MSVCRT
|
|||||||
# _stat.c
|
# _stat.c
|
||||||
# _stat64.c
|
# _stat64.c
|
||||||
# _stati64.c
|
# _stati64.c
|
||||||
# _statusfp.c
|
|
||||||
# _strcmpi.c
|
# _strcmpi.c
|
||||||
# _strcoll_l
|
# _strcoll_l
|
||||||
# _strdate.c
|
# _strdate.c
|
||||||
|
@ -8,6 +8,7 @@ list(APPEND SOURCE_STATIC
|
|||||||
_vsnwprintf.c
|
_vsnwprintf.c
|
||||||
atexit.c
|
atexit.c
|
||||||
fabs.c
|
fabs.c
|
||||||
|
fpcontrol.c
|
||||||
mbstowcs.c
|
mbstowcs.c
|
||||||
mbtowc.c
|
mbtowc.c
|
||||||
sprintf.c
|
sprintf.c
|
||||||
|
@ -18,6 +18,7 @@ extern void func___64tof(void);
|
|||||||
#if defined(TEST_NTDLL)
|
#if defined(TEST_NTDLL)
|
||||||
extern void func__vscwprintf(void);
|
extern void func__vscwprintf(void);
|
||||||
#endif
|
#endif
|
||||||
|
extern void func_fpcontrol(void);
|
||||||
extern void func_fabs(void);
|
extern void func_fabs(void);
|
||||||
extern void func_fputc(void);
|
extern void func_fputc(void);
|
||||||
extern void func_fputwc(void);
|
extern void func_fputwc(void);
|
||||||
@ -61,6 +62,9 @@ const struct test winetest_testlist[] =
|
|||||||
// ...
|
// ...
|
||||||
#endif
|
#endif
|
||||||
#if defined(TEST_STATIC_CRT) || defined(TEST_MSVCRT)
|
#if defined(TEST_STATIC_CRT) || defined(TEST_MSVCRT)
|
||||||
|
#ifdef _M_AMD64 // x86 / arm need fixing
|
||||||
|
{ "fpcontrol", func_fpcontrol },
|
||||||
|
#endif
|
||||||
{ "fabs", func_fabs },
|
{ "fabs", func_fabs },
|
||||||
#if defined(_M_ARM)
|
#if defined(_M_ARM)
|
||||||
{ "__rt_div", func___rt_div },
|
{ "__rt_div", func___rt_div },
|
||||||
|
Loading…
Reference in New Issue
Block a user