https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3aa3b3af560859ef97e1d…
commit 3aa3b3af560859ef97e1dfb24d1a2c1d88f3af1b
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: Fri Aug 26 00:44:46 2022 +0200
[CRT] Implement portable ceil/floor
---
sdk/lib/crt/math/amd64/ceil.S | 55 -------------------------------
sdk/lib/crt/math/amd64/ceilf.S | 51 -----------------------------
sdk/lib/crt/math/amd64/floor.S | 41 ------------------------
sdk/lib/crt/math/amd64/floorf.S | 41 ------------------------
sdk/lib/crt/math/ceil.c | 65 +++++++++++++++++++++++++++++++++++++
sdk/lib/crt/math/floor.c | 71 +++++++++++++++++++++++++++++++++++++++++
sdk/lib/crt/math/math.cmake | 7 ++--
7 files changed, 139 insertions(+), 192 deletions(-)
diff --git a/sdk/lib/crt/math/amd64/ceil.S b/sdk/lib/crt/math/amd64/ceil.S
deleted file mode 100644
index f88403e241c..00000000000
--- a/sdk/lib/crt/math/amd64/ceil.S
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Implementation of ceil
- * FILE: lib/sdk/crt/math/amd64/ceil.S
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <asm.inc>
-#include <ksamd64.inc>
-
-/* CODE **********************************************************************/
-.code64
-
-/* ceil(x) = - floor(-x)
- */
-PUBLIC ceil
-.PROC ceil
- sub rsp, 16
- .ENDPROLOG
-
- /* Duplicate the bits into rax */
- movd rax, xmm0
-
- /* Invert the sign bit */
- rol rax, 1
- xor al, 1
- ror rax, 1
-
- /* Copy back to xmm0 */
- movd xmm0, rax
-
- /* Truncate xmm0 to integer (double precision) */
- cvttsd2si rcx, xmm0
-
- /* Shift all bits to the right, keeping the sign bit */
- shr rax, 63
-
- /* Substract the sign bit from the truncated value, so that
- we get the correct result for negative values. */
- sub rcx, rax
-
- /* Now compensate for the previous negation */
- neg rcx
-
- /* Convert the result back to xmm0 (double precision) */
- cvtsi2sd xmm0, rcx
-
- add rsp, 16
- ret
-.ENDP
-
-END
diff --git a/sdk/lib/crt/math/amd64/ceilf.S b/sdk/lib/crt/math/amd64/ceilf.S
deleted file mode 100644
index 6063ddb1d5e..00000000000
--- a/sdk/lib/crt/math/amd64/ceilf.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Implementation of tan
- * FILE: lib/sdk/crt/math/amd64/ceilf.S
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <asm.inc>
-#include <ksamd64.inc>
-
-/* CODE **********************************************************************/
-.code64
-
-PUBLIC ceilf
-FUNC ceilf
- sub rsp, 16
- .ENDPROLOG
-
- /* Duplicate the bits into eax (zero exteneded to rax) */
- movd eax, xmm0
-
- /* Invert the sign bit */
- xor eax, HEX(80000000)
-
- /* Copy back to xmm0 */
- movd xmm0, eax
-
- /* Truncate xmm0 to integer (single precision) */
- cvttss2si rcx, xmm0
-
- /* Shift all bits to the right, keeping the sign bit */
- shr rax, 31
-
- /* Add the sign bit from the truncated value, so that
- we get the correct result for negative values. */
- add rcx, rax
-
- /* Now compensate for the previous negation */
- neg ecx
-
- /* Convert the result back to xmm0 (single precision) */
- cvtsi2ss xmm0, rcx
-
- add rsp, 16
- ret
-ENDFUNC
-
-END
diff --git a/sdk/lib/crt/math/amd64/floor.S b/sdk/lib/crt/math/amd64/floor.S
deleted file mode 100644
index 95724686824..00000000000
--- a/sdk/lib/crt/math/amd64/floor.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Implementation of floor
- * FILE: lib/sdk/crt/math/amd64/floor.S
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <asm.inc>
-
-/* CODE **********************************************************************/
-.code64
-
-PUBLIC floor
-FUNC floor
- sub rsp, 16
- .ENDPROLOG
-
- /* Truncate xmm0 to integer (double precision) */
- cvttsd2si rcx, xmm0
-
- /* Duplicate the bits into rax */
- movd rax, xmm0
-
- /* Shift all bits to the right, keeping the sign bit */
- shr rax, 63
-
- /* Substract the sign bit from the truncated value, so that
- we get the correct result for negative values. */
- sub rcx, rax
-
- /* Convert the result back to xmm0 (double precision) */
- cvtsi2sd xmm0, rcx
-
- add rsp, 16
- ret
-ENDFUNC
-
-END
diff --git a/sdk/lib/crt/math/amd64/floorf.S b/sdk/lib/crt/math/amd64/floorf.S
deleted file mode 100644
index 176c481ba4f..00000000000
--- a/sdk/lib/crt/math/amd64/floorf.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * PURPOSE: Implementation of floorf
- * FILE: lib/sdk/crt/math/amd64/floorf.S
- * PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <asm.inc>
-
-/* CODE **********************************************************************/
-.code64
-
-PUBLIC floorf
-FUNC floorf
- sub rsp, 16
- .ENDPROLOG
-
- /* Truncate xmm0 to integer (single precision) */
- cvttss2si rcx, xmm0
-
- /* Duplicate the bits into rax */
- movd eax, xmm0
-
- /* Shift all bits to the right, keeping the sign bit */
- shr rax, 31
-
- /* Substract the sign bit from the truncated value, so that
- we get the correct result for negative values. */
- sub rcx, rax
-
- /* Convert the result back to xmm0 (single precision) */
- cvtsi2ss xmm0, rcx
-
- add rsp, 16
- ret
-ENDFUNC
-
-END
diff --git a/sdk/lib/crt/math/ceil.c b/sdk/lib/crt/math/ceil.c
new file mode 100644
index 00000000000..f1b6ff8665d
--- /dev/null
+++ b/sdk/lib/crt/math/ceil.c
@@ -0,0 +1,65 @@
+/*
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: Portable implementation of ceil
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ */
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <limits.h>
+
+#ifdef _MSC_VER
+#pragma function(ceil)
+#endif
+
+double
+__cdecl
+ceil(double x)
+{
+ /* Load the value as uint64 */
+ unsigned long long u64 = *(unsigned long long*)&x;
+
+ /* Check for NAN */
+ if ((u64 & ~(1ULL << 63)) > 0x7FF0000000000000ull)
+ {
+ /* Set error bit */
+ u64 |= 0x0008000000000000ull;
+ return *(double*)&u64;
+ }
+
+ /* Check if x is positive */
+ if ((u64 & (1ULL << 63)) == 0)
+ {
+ /* Check if it fits into an int64 */
+ if (x < (double)_I64_MAX)
+ {
+ /* Cast to int64 to truncate towards 0. If this matches the
+ input, return it as is, otherwise add 1 */
+ double y = (double)(long long)x;
+ return (x > y) ? y + 1 : y;
+ }
+ else
+ {
+ /* The exponent is larger than the fraction bits.
+ This means the number is already an integer. */
+ return x;
+ }
+ }
+ else
+ {
+ /* Check if it fits into an int64 */
+ if (x > (double)_I64_MIN)
+ {
+ /* Cast to int64 to truncate towards 0. */
+ x = (double)(long long)x;
+ return (x == 0.) ? -0.0 : x;
+ }
+ else
+ {
+ /* The exponent is larger than the fraction bits.
+ This means the number is already an integer. */
+ return x;
+ }
+ }
+}
diff --git a/sdk/lib/crt/math/floor.c b/sdk/lib/crt/math/floor.c
new file mode 100644
index 00000000000..883105117d4
--- /dev/null
+++ b/sdk/lib/crt/math/floor.c
@@ -0,0 +1,71 @@
+/*
+ * PROJECT: ReactOS CRT library
+ * LICENSE: MIT (
https://spdx.org/licenses/MIT)
+ * PURPOSE: Implementation of floor
+ * COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer(a)reactos.org>
+ */
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <limits.h>
+
+#ifdef _MSC_VER
+#pragma function(floor)
+#endif
+
+double
+__cdecl
+floor(double x)
+{
+ /* Load the value as uint64 */
+ unsigned long long u64 = *(unsigned long long*)&x;
+
+ /* Check for NAN */
+ if ((u64 & ~(1ULL << 63)) > 0x7FF0000000000000ull)
+ {
+ /* Set error bit */
+ u64 |= 0x0008000000000000ull;
+ return *(double*)&u64;
+ }
+
+ /* Check if x is positive */
+ if ((u64 & (1ULL << 63)) == 0)
+ {
+ /* Check if it fits into an int64 */
+ if (x < (double)_I64_MAX)
+ {
+ /* Just cast to int64, which will truncate towards 0,
+ which is what we want here.*/
+ return (double)(long long)x;
+ }
+ else
+ {
+ /* The exponent is larger than the fraction bits.
+ This means the number is already an integer. */
+ return x;
+ }
+ }
+ else
+ {
+ /* Check if it fits into an int64 */
+ if (x > (double)_I64_MIN)
+ {
+ /* Check if it is -0 */
+ if (x == -0.)
+ {
+ return -0.;
+ }
+
+ /* Cast to int64 to truncate towards 0. If this matches the
+ input, return it as is, otherwise subtract 1 */
+ double y = (double)(long long)x;
+ return (x == y) ? y : y - 1;
+ }
+ else
+ {
+ /* The exponent is larger than the fraction bits.
+ This means the number is already an integer. */
+ return x;
+ }
+ }
+}
diff --git a/sdk/lib/crt/math/math.cmake b/sdk/lib/crt/math/math.cmake
index 1f4a4d5da2a..7cc7a795447 100644
--- a/sdk/lib/crt/math/math.cmake
+++ b/sdk/lib/crt/math/math.cmake
@@ -53,18 +53,17 @@ if(ARCH STREQUAL "i386")
)
elseif(ARCH STREQUAL "amd64")
list(APPEND LIBCNTPR_MATH_SOURCE
+ math/ceil.c
math/cos.c
math/sin.c
+ math/floor.c
)
list(APPEND LIBCNTPR_MATH_ASM_SOURCE
math/amd64/atan.S
math/amd64/atan2.S
- 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
math/amd64/ldexp.S
math/amd64/log.S
@@ -78,7 +77,6 @@ elseif(ARCH STREQUAL "arm")
math/cos.c
math/fabs.c
math/fabsf.c
- math/floorf.c
math/sin.c
math/sqrt.c
math/arm/__rt_sdiv.c
@@ -131,6 +129,7 @@ if(NOT ARCH STREQUAL "i386")
math/cos.c
math/coshf.c
math/expf.c
+ math/floorf.c
math/fmodf.c
math/log10f.c
math/modff.c