https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a67170616e2b4d0aa01d…
commit 8a67170616e2b4d0aa01d15f3cda8d7ca2aa62b2
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Aug 4 17:22:01 2021 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)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(a)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(a)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);