https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b85afdfd258cb959893d2…
commit b85afdfd258cb959893d28ae194db9118d3e6f5c
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sat May 29 19:40:30 2021 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Sun Jun 26 19:13:47 2022 +0200
[CRT] Implement portable + amd64 asm version of fabs/fabsf
Note: older versions of ML64 are broken and don't understand the register form of
movq.
See
https://stackoverflow.com/questions/24789339/move-quadword-between-xmm-and-…
---
modules/rostests/apitests/crt/fabs.c | 4 +--
sdk/lib/crt/math/amd64/fabs.S | 43 +++++++++++++++++++++++--------
sdk/lib/crt/math/amd64/fabsf.S | 49 ++++++++++++++++++++++++++++++++++++
sdk/lib/crt/math/arm/fabs.s | 24 ------------------
sdk/lib/crt/math/fabs.c | 38 ++++++++++++++++++++++++++++
sdk/lib/crt/math/fabsf.c | 26 ++++++++++++++-----
sdk/lib/crt/math/math.cmake | 11 ++++----
7 files changed, 148 insertions(+), 47 deletions(-)
diff --git a/modules/rostests/apitests/crt/fabs.c b/modules/rostests/apitests/crt/fabs.c
index 88fd9fb8410..eec1f761757 100644
--- a/modules/rostests/apitests/crt/fabs.c
+++ b/modules/rostests/apitests/crt/fabs.c
@@ -20,7 +20,7 @@ static TESTENTRY_DBL s_fabs_tests[] =
{
/* Special values */
{ 0x7FF0000000000000ull /* INF */, 0x7FF0000000000000ull /* INF */ },
-#ifdef _M_AMD64
+#ifndef _M_IX86
{ 0x7FF0000000000001ull /* NAN(SNAN) */, 0x7FF0000000000001ull /* NAN(SNAN) */ },
{ 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */, 0x7FF7FFFFFFFFFFFFull /* NAN(SNAN) */ },
#else
@@ -31,7 +31,7 @@ static TESTENTRY_DBL s_fabs_tests[] =
{ 0x7FF8000000000001ull /* NAN */, 0x7FF8000000000001ull /* NAN */ },
{ 0x7FFFFFFFFFFFFFFFull /* NAN */, 0x7FFFFFFFFFFFFFFFull /* NAN */ },
{ 0xFFF0000000000000ull /* -INF */, 0x7FF0000000000000ull /* INF */ },
-#ifdef _M_AMD64
+#ifndef _M_IX86
{ 0xFFF0000000000001ull /* -NAN(SNAN) */, 0xFFF0000000000001ull /* NAN(SNAN) */ },
{ 0xFFF7FFFFFFFFFFFFull /* -NAN(SNAN) */, 0xFFF7FFFFFFFFFFFFull /* NAN(SNAN) */ },
#else
diff --git a/sdk/lib/crt/math/amd64/fabs.S b/sdk/lib/crt/math/amd64/fabs.S
index fb6db3b32e3..a35222ab93e 100644
--- a/sdk/lib/crt/math/amd64/fabs.S
+++ b/sdk/lib/crt/math/amd64/fabs.S
@@ -1,9 +1,8 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Implementation of fabs
- * FILE: lib/sdk/crt/math/amd64/fabs.S
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: x64 asm implementation of fabs
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
*/
/* INCLUDES ******************************************************************/
@@ -14,18 +13,42 @@
.code64
#ifdef _USE_ML
-/* fabs is now allowed as label name, so create _fabs instead and alias fabs to it */
+/* fabs is not allowed as label name, so create _fabs instead and alias fabs to it */
+ALIAS <fabs> = <_fabs>
PUBLIC _fabs
_fabs:
#else
PUBLIC fabs
fabs:
#endif
- UNIMPLEMENTED fabs
- ret
+ /* Copy parameter into rcx */
+#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
+ movq rcx, xmm0
+#else
+ /* Old ML64 version does not understand this form of movq and uses movd instead */
+ movd rcx, xmm0
+#endif
-#ifdef _USE_ML
-ALIAS <fabs> = <_fabs>
+ /* Copy into rax */
+ mov rax, rcx
+
+ /* Clear sign bit in rax */
+ btr rax, 63
+
+ /* Check for NAN */
+ mov r8, HEX(7FF0000000000000)
+ cmp rax, r8
+
+ /* If it is NAN, copy original value back to rax */
+ cmova rax, rcx
+
+#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
+ movq xmm0, rax
+#else
+ /* Old ML64 version does not understand this form of movq and uses movd instead */
+ movd xmm0, rax
#endif
+ ret
+
END
diff --git a/sdk/lib/crt/math/amd64/fabsf.S b/sdk/lib/crt/math/amd64/fabsf.S
new file mode 100644
index 00000000000..9d4a9af40a0
--- /dev/null
+++ b/sdk/lib/crt/math/amd64/fabsf.S
@@ -0,0 +1,49 @@
+/*
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: x64 asm implementation of fabsf
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <asm.inc>
+
+/* CODE **********************************************************************/
+.code64
+
+PUBLIC fabsf
+fabsf:
+ /* Copy parameter into rcx */
+#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
+ movq rcx, xmm0
+#else
+ /* Old ML64 version does not understand this form of movq and uses movd instead */
+ movd rcx, xmm0
+#endif
+
+ /* Copy into eax */
+ mov eax, ecx
+
+ /* Clear sign bit in eax */
+ btr eax, 31
+
+ /* Set error bit in rcx */
+ bts ecx, 22
+
+ /* Check for NAN */
+ cmp eax, HEX(7F800000)
+
+ /* If eax is NAN, copy error result to rax */
+ cmova eax, ecx
+
+#if !defined(_MSC_VER) || (_MSC_VER >= 1916)
+ movq xmm0, rax
+#else
+ /* Old ML64 version does not understand this form of movq and uses movd instead */
+ movd xmm0, rax
+#endif
+
+ ret
+
+END
diff --git a/sdk/lib/crt/math/arm/fabs.s b/sdk/lib/crt/math/arm/fabs.s
deleted file mode 100644
index 331c6ec64c0..00000000000
--- a/sdk/lib/crt/math/arm/fabs.s
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * COPYRIGHT: BSD - See COPYING.ARM in the top level directory
- * PROJECT: ReactOS CRT library
- * PURPOSE: Implementation of fabs
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <kxarm.h>
-
-/* CODE **********************************************************************/
-
- TEXTAREA
-
- LEAF_ENTRY fabs
-
- __assertfail
- bx lr
-
- LEAF_END fabs
-
- END
-/* EOF */
diff --git a/sdk/lib/crt/math/fabs.c b/sdk/lib/crt/math/fabs.c
new file mode 100644
index 00000000000..771542881c7
--- /dev/null
+++ b/sdk/lib/crt/math/fabs.c
@@ -0,0 +1,38 @@
+/*
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: Portable implementation of fabs
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ */
+
+#include <math.h>
+
+#ifdef _MSC_VER
+#pragma function(fabs)
+#endif
+
+_Check_return_
+double
+__cdecl
+fabs(
+ _In_ double x)
+{
+ /* Load the value as uint64 */
+ unsigned long long u64 = *(unsigned long long*)&x;
+
+ /* Clear the sign bit */
+ u64 &= ~(1ULL << 63);
+
+ /* Check for NAN */
+ if (u64 > 0x7FF0000000000000ull)
+ {
+#ifdef _M_IX86
+ /* Set error bit */
+ *(unsigned long long*)&x |= 0x0008000000000000ull;
+#endif
+ return x;
+ }
+
+ /* Convert back to double */
+ return *(double*)&u64;
+}
diff --git a/sdk/lib/crt/math/fabsf.c b/sdk/lib/crt/math/fabsf.c
index 611d94e8a20..155c8559708 100644
--- a/sdk/lib/crt/math/fabsf.c
+++ b/sdk/lib/crt/math/fabsf.c
@@ -1,8 +1,8 @@
/*
- * COPYRIGHT: BSD - See COPYING.ARM in the top level directory
- * PROJECT: ReactOS CRT library
- * PURPOSE: Implementation of fabsf
- * PROGRAMMER: Timo Kreuzer
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: Portable implementation of fabsf
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
*/
#include <math.h>
@@ -13,6 +13,20 @@ __cdecl
fabsf(
_In_ float x)
{
- return (float)fabs((double)x);
-}
+ /* Load the value as uint */
+ unsigned int u32 = *(unsigned int*)&x;
+
+ /* Clear the sign bit */
+ u32 &= ~(1 << 31);
+ /* Check for NAN */
+ if (u32 > 0x7F800000)
+ {
+ /* Set error bit */
+ *(unsigned int*)&x |= 0x00400000;
+ return x;
+ }
+
+ /* Convert back to float */
+ return *(float*)&u32;
+}
diff --git a/sdk/lib/crt/math/math.cmake b/sdk/lib/crt/math/math.cmake
index fcf9e5eecdf..1f4a4d5da2a 100644
--- a/sdk/lib/crt/math/math.cmake
+++ b/sdk/lib/crt/math/math.cmake
@@ -8,6 +8,8 @@ list(APPEND LIBCNTPR_MATH_SOURCE
if(ARCH STREQUAL "i386")
list(APPEND LIBCNTPR_MATH_SOURCE
+ math/fabs.c
+ math/fabsf.c
math/i386/ci.c
math/i386/cicos.c
math/i386/cilog.c
@@ -31,7 +33,7 @@ if(ARCH STREQUAL "i386")
math/i386/aullshr_asm.s
math/i386/ceil_asm.s
math/i386/cos_asm.s
- math/i386/fabs_asm.s
+ # math/i386/fabs_asm.s # FIXME
math/i386/floor_asm.s
math/i386/ftol_asm.s
math/i386/ftol2_asm.s
@@ -60,6 +62,7 @@ elseif(ARCH STREQUAL "amd64")
math/amd64/ceil.S
math/amd64/exp.S
math/amd64/fabs.S
+ math/amd64/fabsf.S
math/amd64/floor.S
math/amd64/floorf.S
math/amd64/fmod.S
@@ -73,6 +76,8 @@ elseif(ARCH STREQUAL "amd64")
elseif(ARCH STREQUAL "arm")
list(APPEND LIBCNTPR_MATH_SOURCE
math/cos.c
+ math/fabs.c
+ math/fabsf.c
math/floorf.c
math/sin.c
math/sqrt.c
@@ -92,15 +97,11 @@ elseif(ARCH STREQUAL "arm")
math/arm/__u64tos.c
math/arm/__64tof.h
)
- list(APPEND CRT_MATH_SOURCE
- math/fabsf.c
- )
list(APPEND LIBCNTPR_MATH_ASM_SOURCE
math/arm/atan.s
math/arm/atan2.s
math/arm/ceil.s
math/arm/exp.s
- math/arm/fabs.s
math/arm/fmod.s
math/arm/floor.s
math/arm/ldexp.s