https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a67170616e2b4d0aa01d1...
commit 8a67170616e2b4d0aa01d15f3cda8d7ca2aa62b2 Author: Timo Kreuzer timo.kreuzer@reactos.org AuthorDate: Wed Aug 4 17:22:01 2021 +0200 Commit: Timo Kreuzer timo.kreuzer@reactos.org CommitDate: Sun Jun 26 19:13:47 2022 +0200
[CRT_APITEST] Implement tests for fabs/fabsf --- modules/rostests/apitests/crt/fabs.c | 112 +++++++++++++++++++++ modules/rostests/apitests/crt/math_helpers.h | 77 ++++++++++++++ .../rostests/apitests/crt/msvcrt_crt_apitest.cmake | 6 +- .../rostests/apitests/crt/static_crt_apitest.cmake | 5 + modules/rostests/apitests/crt/testlist.c | 2 + sdk/include/crt/math.h | 4 +- 6 files changed, 204 insertions(+), 2 deletions(-)
diff --git a/modules/rostests/apitests/crt/fabs.c b/modules/rostests/apitests/crt/fabs.c new file mode 100644 index 00000000000..88fd9fb8410 --- /dev/null +++ b/modules/rostests/apitests/crt/fabs.c @@ -0,0 +1,112 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Tests for fabs / fabsf + * COPYRIGHT: Copyright 2021 Timo Kreuzer timo.kreuzer@reactos.org + */ + +/* Don't use the inline ceilf, unless required */ +#if defined(TEST_STATIC_CRT) || defined(_M_ARM) +#define _CRTBLD +#endif +#include "math_helpers.h" + +#ifdef _MSC_VER +#pragma function(fabs) +// fabsf is not available as an intrinsic +#endif + +static TESTENTRY_DBL s_fabs_tests[] = +{ + /* Special values */ + { 0x7FF0000000000000ull /* INF */, 0x7FF0000000000000ull /* INF */ }, +#ifdef _M_AMD64 + { 0x7FF0000000000001ull /* NAN(SNAN) */, 0x7FF0000000000001ull /* NAN(SNAN) */ }, + { 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */, 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */ }, +#else + { 0x7FF0000000000001ull /* NAN(SNAN) */, 0x7FF8000000000001ull /* NAN */ }, + { 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */, 0x7FFFFFFFFFFFFFFFull /* NAN */ }, +#endif + { 0x7FF8000000000000ull /* NAN */, 0x7FF8000000000000ull /* NAN */ }, + { 0x7FF8000000000001ull /* NAN */, 0x7FF8000000000001ull /* NAN */ }, + { 0x7FFFFFFFFFFFFFFFull /* NAN */, 0x7FFFFFFFFFFFFFFFull /* NAN */ }, + { 0xFFF0000000000000ull /* -INF */, 0x7FF0000000000000ull /* INF */ }, +#ifdef _M_AMD64 + { 0xFFF0000000000001ull /* -NAN(SNAN) */, 0xFFF0000000000001ull /* NAN(SNAN) */ }, + { 0xFFF7FFFFFFFFFFFFull /* -NAN(SNAN) */, 0xFFF7FFFFFFFFFFFFull /* NAN(SNAN) */ }, +#else + { 0xFFF0000000000001ull /* -NAN(SNAN) */, 0xFFF8000000000001ull /* -NAN */ }, + { 0xFFF7FFFFFFFFFFFFull /* -NAN(SNAN) */, 0xFFFFFFFFFFFFFFFFull /* -NAN */ }, +#endif + { 0xFFF8000000000000ull /* -NAN(IND) */, 0xFFF8000000000000ull /* -NAN(IND) */ }, + { 0xFFF8000000000001ull /* -NAN */, 0xFFF8000000000001ull /* -NAN */ }, + { 0xFFFFFFFFFFFFFFFFull /* -NAN */, 0xFFFFFFFFFFFFFFFFull /* -NAN */ }, + + /* Some random floats */ + { 0x0000000000000000 /* 0.000000000000000e+000 */, 0x0000000000000000 /* 0.000000000000000e+000 */ }, + { 0x8000000000000000 /* -0.000000000000000e+000 */, 0x0000000000000000 /* 0.000000000000000e+000 */ }, + { 0x0123456789abcdef /* 3.512700564088504e-303 */, 0x0123456789abcdef /* 3.512700564088504e-303 */ }, + { 0x8123456789abcdef /* -3.512700564088504e-303 */, 0x0123456789abcdef /* 3.512700564088504e-303 */ }, + { 0x472ad8b31f506c9e /* 6.969745516432332e+034 */, 0x472ad8b31f506c9e /* 6.969745516432332e+034 */ }, + { 0xc72ad8b31f506c9e /* -6.969745516432332e+034 */, 0x472ad8b31f506c9e /* 6.969745516432332e+034 */ }, + { 0x1d289e506fa47cb3 /* 3.261613668384938e-168 */, 0x1d289e506fa47cb3 /* 3.261613668384938e-168 */ }, + { 0x9d289e506fa47cb3 /* -3.261613668384938e-168 */, 0x1d289e506fa47cb3 /* 3.261613668384938e-168 */ }, +}; + + +void Test_fabs(void) +{ + int i; + + for (i = 0; i < _countof(s_fabs_tests); i++) + { + double x = u64_to_dbl(s_fabs_tests[i].x); + double z = fabs(x); + ok_eq_dbl_exact("fabs", s_fabs_tests[i].x, z, s_fabs_tests[i].result); + } +} + +static TESTENTRY_FLT s_fabsf_tests[] = +{ + /* Special values */ + { 0x7F800000 /* INF */, 0x7F800000 /* INF */ }, + { 0x7F800001 /* NAN(SNAN) */, 0x7FC00001 /* NAN */ }, + { 0x7FBFFFFF /* NAN(SNAN) */, 0x7FFFFFFF /* NAN */ }, + { 0x7FC00000 /* NAN */, 0x7FC00000 /* NAN */ }, + { 0x7FC00001 /* NAN */, 0x7FC00001 /* NAN */ }, + { 0x7FCFFFFF /* NAN */, 0x7FCFFFFF /* NAN */ }, + { 0xFF800000 /* -INF */, 0x7F800000 /* INF */ }, + { 0xFF800001 /* -NAN(SNAN) */, 0xFFC00001 /* -NAN */ }, + { 0xFFBFFFFF /* -NAN(SNAN) */, 0xFFFFFFFF /* -NAN */ }, + { 0xFFC00000 /* -NAN(IND) */, 0xFFC00000 /* -NAN */ }, + { 0xFFC00001 /* -NAN */, 0xFFC00001 /* -NAN */ }, + { 0xFFCFFFFF /* -NAN */, 0xFFCFFFFF /* -NAN */ }, + + /* Some random floats */ + { 0x00000000 /* 0.000000e+000 */, 0x00000000 /* 0.000000e+000 */ }, + { 0x80000000 /* -0.000000e+000 */, 0x00000000 /* 0.000000e+000 */ }, + { 0x01234567 /* 2.998817e-038 */, 0x01234567 /* 2.998817e-038 */ }, + { 0x81234567 /* -2.998817e-038 */, 0x01234567 /* 2.998817e-038 */ }, + { 0x472ad8b3 /* 4.373670e+004 */, 0x472ad8b3 /* 4.373670e+004 */ }, + { 0xc72ad8b3 /* -4.373670e+004 */, 0x472ad8b3 /* 4.373670e+004 */ }, + { 0x1d289e50 /* 2.231646e-021 */, 0x1d289e50 /* 2.231646e-021 */ }, + { 0x9d289e50 /* -2.231646e-021 */, 0x1d289e50 /* 2.231646e-021 */ }, +}; + +void Test_fabsf(void) +{ + int i; + + for (i = 0; i < _countof(s_fabsf_tests); i++) + { + float x = u32_to_flt(s_fabsf_tests[i].x); + float z = fabsf(x); + ok_eq_flt_exact("fabsf", s_fabsf_tests[i].x, z, s_fabsf_tests[i].result); + } +} + +START_TEST(fabs) +{ + Test_fabs(); + Test_fabsf(); +} diff --git a/modules/rostests/apitests/crt/math_helpers.h b/modules/rostests/apitests/crt/math_helpers.h new file mode 100644 index 00000000000..667f5b63dce --- /dev/null +++ b/modules/rostests/apitests/crt/math_helpers.h @@ -0,0 +1,77 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Helpers for testing math functions + * COPYRIGHT: Copyright 2021 Timo Kreuzer timo.kreuzer@reactos.org + */ + +#pragma once + +#define _USE_MATH_DEFINES +#include <math.h> +#include <float.h> +#include <apitest.h> + +static +__inline +double +u64_to_dbl(UINT64 x) +{ + return *(double*)(&x); +} + +static +__inline +UINT64 +dbl_to_u64(double x) +{ + return *(UINT64*)(&x); +} + +static +__inline +float +u32_to_flt(UINT32 x) +{ + return *(float*)(&x); +} + +static +__inline +UINT32 +flt_to_u32(float x) +{ + return *(UINT32*)(&x); +} + +typedef struct _TESTENTRY_DBL +{ + unsigned long long x; + unsigned long long result; +} TESTENTRY_DBL; + +typedef struct _TESTENTRY_FLT +{ + unsigned long x; + unsigned long result; +} TESTENTRY_FLT; + +#define ok_eq_dbl_exact_(file, line, func, ullx, z, ullexp) \ + { \ + double x = u64_to_dbl(ullx); \ + unsigned long long ullz = dbl_to_u64(z); \ + double exp = u64_to_dbl(ullexp); \ + ok_(file, line)(ullz == ullexp, "Wrong value for '%s(%f)' [0x%016llx], expected: %f [0x%016llx], got: %f [0x%016llx]\n", \ + func, x, ullx, exp, ullexp, z, ullz); \ + } +#define ok_eq_dbl_exact(func, ullx, z, ullexp) ok_eq_dbl_exact_(__FILE__, __LINE__, func, ullx, z, ullexp) + +#define ok_eq_flt_exact_(file, line, func, ux, z, uexp) \ + { \ + float x = u32_to_flt(ux); \ + unsigned int uz = flt_to_u32(z); \ + float exp = u32_to_flt(uexp); \ + ok_(file, line)(uz == uexp, "Wrong value for '%s(%f)' [0x%08x], expected: %f [0x%08x], got: %f [0x%08x]\n", \ + func, x, ux, exp, uexp, z, uz); \ + } +#define ok_eq_flt_exact(func, ux, z, uexp) ok_eq_flt_exact_(__FILE__, __LINE__, func, ux, z, uexp) diff --git a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake index 82283e5a3a6..58a598bb6fb 100644 --- a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake @@ -1033,7 +1033,7 @@ list(APPEND SOURCE_MSVCRT # div.c # exit.c # exp.c -# fabs.c + fabs.c # fclose.c # feof.c # ferror.c @@ -1404,6 +1404,10 @@ set_module_type(msvcrt_crt_apitest win32cui) add_importlibs(msvcrt_crt_apitest msvcrt kernel32 ntdll) add_rostests_file(TARGET msvcrt_crt_apitest)
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(msvcrt_crt_apitest PRIVATE -Wno-format) +endif() + spec2def(msvcrt_crt_dll_startup.dll dll_startup.spec) add_library(msvcrt_crt_dll_startup MODULE dll_startup.cpp diff --git a/modules/rostests/apitests/crt/static_crt_apitest.cmake b/modules/rostests/apitests/crt/static_crt_apitest.cmake index a3e35c412b3..cb1cfaac48e 100644 --- a/modules/rostests/apitests/crt/static_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/static_crt_apitest.cmake @@ -7,6 +7,7 @@ list(APPEND SOURCE_STATIC _vsnprintf.c _vsnwprintf.c atexit.c + fabs.c mbstowcs.c mbtowc.c sprintf.c @@ -40,3 +41,7 @@ target_link_libraries(static_crt_apitest crt wine ${PSEH_LIB}) set_module_type(static_crt_apitest win32cui) add_importlibs(static_crt_apitest kernel32 ntdll) add_rostests_file(TARGET static_crt_apitest) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(static_crt_apitest PRIVATE -Wno-format) +endif() diff --git a/modules/rostests/apitests/crt/testlist.c b/modules/rostests/apitests/crt/testlist.c index e8b4c7670fb..16a3a9d394c 100644 --- a/modules/rostests/apitests/crt/testlist.c +++ b/modules/rostests/apitests/crt/testlist.c @@ -18,6 +18,7 @@ extern void func___64tof(void); #if defined(TEST_NTDLL) extern void func__vscwprintf(void); #endif +extern void func_fabs(void); extern void func_fputc(void); extern void func_fputwc(void); extern void func__snprintf(void); @@ -60,6 +61,7 @@ const struct test winetest_testlist[] = // ... #endif #if defined(TEST_STATIC_CRT) || defined(TEST_MSVCRT) + { "fabs", func_fabs }, #if defined(_M_ARM) { "__rt_div", func___rt_div }, { "__fto64", func___fto64 }, diff --git a/sdk/include/crt/math.h b/sdk/include/crt/math.h index 2f92da209fe..ce896484cd7 100644 --- a/sdk/include/crt/math.h +++ b/sdk/include/crt/math.h @@ -169,7 +169,9 @@ _Check_return_ __CRT_INLINE float __CRTDECL ldexpf(_In_ float x, _In_ int y) { r _Check_return_ __CRT_INLINE long double __CRTDECL tanl(_In_ long double x) { return (tan((double)x)); } #endif
-#if defined(__ia64__) || defined(_M_IA64) || \ +#if defined(_CRTBLD) +_Check_return_ float __cdecl fabsf(_In_ float x); +#elif defined(__ia64__) || defined(_M_IA64) || \ defined(__arm__) || defined(_M_ARM) || \ defined(__arm64__) || defined(_M_ARM64) _Check_return_ _CRT_JIT_INTRINSIC _CRTIMP float __cdecl fabsf(_In_ float x);