https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b85afdfd258cb959893d28ae194db9118d3e6f5c

commit b85afdfd258cb959893d28ae194db9118d3e6f5c
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sat May 29 19:40:30 2021 +0200
Commit:     Timo Kreuzer <[email protected]>
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-general-purpose-register-in-ml64
---
 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 ([email protected])
+ * PROJECT:     ReactOS CRT library
+ * LICENSE:     MIT (https://spdx.org/licenses/MIT)
+ * PURPOSE:     x64 asm implementation of fabs
+ * COPYRIGHT:   Copyright 2021 Timo Kreuzer <[email protected]>
  */
 
 /* 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 <[email protected]>
+ */
+
+/* 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 ([email protected])
- */
-
-/* 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 <[email protected]>
+ */
+
+#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 <[email protected]>
  */
 
 #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

Reply via email to