diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -1,3 +1,41 @@ +add_subdirectory(generic) +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_MACHINE}) + add_subdirectory(${LIBC_TARGET_MACHINE}) +endif() + +function(add_math_entrypoint_object name) + # We prefer machine specific implementation if available. Hence we check + # that first and retrun early if we are able to add an alias target for the + # machine specific implementation. + get_fq_target_name("${LIBC_TARGET_MACHINE}.${name}" fq_machine_specific_target_name) + if(TARGET ${fq_machine_specific_target_name}) + add_entrypoint_object( + ${name} + ALIAS + DEPENDS + .${LIBC_TARGET_MACHINE}.${name} + ) + return() + endif() + + get_fq_target_name("generic.${name}" fq_generic_target_name) + if(TARGET ${fq_generic_target_name}) + add_entrypoint_object( + ${name} + ALIAS + DEPENDS + .generic.${name} + ) + return() + endif() + + message(FATAL_ERROR "No machine specific or generic implementation found for ${name}.") +endfunction() + +add_math_entrypoint_object(ceil) +add_math_entrypoint_object(ceilf) +add_math_entrypoint_object(ceill) + add_object_library( math_utils SRCS @@ -128,42 +166,6 @@ -O2 ) -add_entrypoint_object( - ceil - SRCS - ceil.cpp - HDRS - ceil.h - DEPENDS - libc.utils.FPUtil.fputil - COMPILE_OPTIONS - -O2 -) - -add_entrypoint_object( - ceilf - SRCS - ceilf.cpp - HDRS - ceilf.h - DEPENDS - libc.utils.FPUtil.fputil - COMPILE_OPTIONS - -O2 -) - -add_entrypoint_object( - ceill - SRCS - ceill.cpp - HDRS - ceill.h - DEPENDS - libc.utils.FPUtil.fputil - COMPILE_OPTIONS - -O2 -) - add_entrypoint_object( floor SRCS diff --git a/libc/src/math/aarch64/CMakeLists.txt b/libc/src/math/aarch64/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/math/aarch64/CMakeLists.txt @@ -0,0 +1,19 @@ +add_entrypoint_object( + ceil + SRCS + ceil.cpp + HDRS + ../ceil.h + COMPILE_OPTIONS + -O2 +) + +add_entrypoint_object( + ceilf + SRCS + ceilf.cpp + HDRS + ../ceilf.h + COMPILE_OPTIONS + -O2 +) diff --git a/libc/src/math/ceil.cpp b/libc/src/math/aarch64/ceil.cpp rename from libc/src/math/ceil.cpp rename to libc/src/math/aarch64/ceil.cpp --- a/libc/src/math/ceil.cpp +++ b/libc/src/math/aarch64/ceil.cpp @@ -1,4 +1,4 @@ -//===-- Implementation of ceil function -----------------------------------===// +//===-- Implementation of the ceil function for aarch64 -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,18 @@ #include "src/math/ceil.h" #include "src/__support/common.h" -#include "utils/FPUtil/NearestIntegerOperations.h" namespace __llvm_libc { -LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return fputil::ceil(x); } +LLVM_LIBC_FUNCTION(double, ceil, (double x)) { + double y; + __asm__ __volatile__("ldr d0, %1\n" + "frintp d0, d0\n" + "str d0, %0\n" + : "=m"(y) + : "m"(x) + : "d0"); + return y; +} } // namespace __llvm_libc diff --git a/libc/src/math/ceilf.cpp b/libc/src/math/aarch64/ceilf.cpp rename from libc/src/math/ceilf.cpp rename to libc/src/math/aarch64/ceilf.cpp --- a/libc/src/math/ceilf.cpp +++ b/libc/src/math/aarch64/ceilf.cpp @@ -1,4 +1,4 @@ -//===-- Implementation of ceilf function ----------------------------------===// +//===-- Implementation of the ceilf function for aarch64 ------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,10 +8,18 @@ #include "src/math/ceilf.h" #include "src/__support/common.h" -#include "utils/FPUtil/NearestIntegerOperations.h" namespace __llvm_libc { -LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return fputil::ceil(x); } +LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { + float y; + __asm__ __volatile__("ldr s0, %1\n" + "frintp s0, s0\n" + "str s0, %0\n" + : "=m"(y) + : "m"(x) + : "s0"); + return y; +} } // namespace __llvm_libc diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/math/generic/CMakeLists.txt @@ -0,0 +1,35 @@ +add_entrypoint_object( + ceil + SRCS + ceil.cpp + HDRS + ../ceil.h + DEPENDS + libc.utils.FPUtil.fputil + COMPILE_OPTIONS + -O2 +) + +add_entrypoint_object( + ceilf + SRCS + ceilf.cpp + HDRS + ../ceilf.h + DEPENDS + libc.utils.FPUtil.fputil + COMPILE_OPTIONS + -O2 +) + +add_entrypoint_object( + ceill + SRCS + ceill.cpp + HDRS + ../ceill.h + DEPENDS + libc.utils.FPUtil.fputil + COMPILE_OPTIONS + -O2 +) diff --git a/libc/src/math/ceil.cpp b/libc/src/math/generic/ceil.cpp rename from libc/src/math/ceil.cpp rename to libc/src/math/generic/ceil.cpp diff --git a/libc/src/math/ceilf.cpp b/libc/src/math/generic/ceilf.cpp rename from libc/src/math/ceilf.cpp rename to libc/src/math/generic/ceilf.cpp diff --git a/libc/src/math/ceill.cpp b/libc/src/math/generic/ceill.cpp rename from libc/src/math/ceill.cpp rename to libc/src/math/generic/ceill.cpp diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -1070,3 +1070,5 @@ libc.src.math.fmaf libc.utils.FPUtil.fputil ) + +add_subdirectory(generic) diff --git a/libc/test/src/math/generic/CMakeLists.txt b/libc/test/src/math/generic/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/test/src/math/generic/CMakeLists.txt @@ -0,0 +1,39 @@ +add_fp_unittest( + ceil_test + NEED_MPFR + SUITE + libc_math_unittests + SRCS + ../ceil_test.cpp + DEPENDS + libc.include.math + libc.src.math.generic.ceil + libc.utils.FPUtil.fputil +) + +add_fp_unittest( + ceilf_test + NEED_MPFR + SUITE + libc_math_unittests + SRCS + ../ceilf_test.cpp + DEPENDS + libc.include.math + libc.src.math.generic.ceilf + libc.utils.FPUtil.fputil +) + +add_fp_unittest( + ceill_test + NEED_MPFR + SUITE + libc_math_unittests + SRCS + ../ceill_test.cpp + DEPENDS + libc.include.math + libc.src.math.generic.ceill + libc.utils.FPUtil.fputil +) +