diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -18,6 +18,11 @@ # errno.h entrypoints libc.src.errno.__errno_location + # stdlib.h entrypoints + libc.src.stdlib.abs + libc.src.stdlib.labs + libc.src.stdlib.llabs + # string.h entrypoints libc.src.string.bzero libc.src.string.memchr diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -34,6 +34,9 @@ # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort + libc.src.stdlib.abs + libc.src.stdlib.labs + libc.src.stdlib.llabs # string.h entrypoints libc.src.string.bzero diff --git a/libc/spec/spec.td b/libc/spec/spec.td --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -42,6 +42,8 @@ def FloatType : NamedType<"float">; def DoubleType : NamedType<"double">; def LongDoubleType : NamedType<"long double">; +def LongLongType : NamedType<"long long">; +def LongType : NamedType<"long">; def CharType : NamedType<"char">; // Common types diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -353,6 +353,9 @@ [], // Enumerations [ FunctionSpec<"abort", RetValSpec, [ArgSpec]>, + FunctionSpec<"abs", RetValSpec, [ArgSpec]>, + FunctionSpec<"labs", RetValSpec, [ArgSpec]>, + FunctionSpec<"llabs", RetValSpec, [ArgSpec]>, FunctionSpec<"_Exit", RetValSpec, [ArgSpec]>, ] >; diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -2,6 +2,12 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() +add_header_library( + abs_utils + HDRS + abs_utils.h +) + add_entrypoint_object( _Exit ALIAS @@ -20,3 +26,33 @@ libc.src.signal.raise ._Exit ) + +add_entrypoint_object( + abs + SRCS + abs.cpp + HDRS + abs.h + DEPENDS + .abs_utils +) + +add_entrypoint_object( + labs + SRCS + labs.cpp + HDRS + labs.h + DEPENDS + .abs_utils +) + +add_entrypoint_object( + llabs + SRCS + llabs.cpp + HDRS + llabs.h + DEPENDS + .abs_utils +) diff --git a/libc/src/stdlib/abs.h b/libc/src/stdlib/abs.h new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/abs.h @@ -0,0 +1,18 @@ +//===-- Implementation header for abs ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_ABS_H +#define LLVM_LIBC_SRC_STDLIB_ABS_H + +namespace __llvm_libc { + +int abs(int n); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDLIB_ABS_H diff --git a/libc/src/stdlib/abs.cpp b/libc/src/stdlib/abs.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/abs.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of abs ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/abs.h" +#include "src/__support/common.h" +#include "src/stdlib/abs_utils.h" + +namespace __llvm_libc { + +int LLVM_LIBC_ENTRYPOINT(abs)(int n) { + // integer_abs from abs_utils.h. + return integer_abs(n); +} + +} // namespace __llvm_libc diff --git a/libc/src/stdlib/abs_utils.h b/libc/src/stdlib/abs_utils.h new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/abs_utils.h @@ -0,0 +1,22 @@ +//===-- Utils for abs and friends -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_ABS_UTILS_H +#define LLVM_LIBC_SRC_STDLIB_ABS_UTILS_H + +namespace __llvm_libc { + +template static inline T integer_abs(T n) { + if (n < 0) + return -n; + return n; +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDLIB_ABS_UTILS_H diff --git a/libc/src/stdlib/labs.h b/libc/src/stdlib/labs.h new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/labs.h @@ -0,0 +1,18 @@ +//===-- Implementation header for labs --------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_LABS_H +#define LLVM_LIBC_SRC_STDLIB_LABS_H + +namespace __llvm_libc { + +long labs(long n); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDLIB_LABS_H diff --git a/libc/src/stdlib/labs.cpp b/libc/src/stdlib/labs.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/labs.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of labs --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/labs.h" +#include "src/__support/common.h" +#include "src/stdlib/abs_utils.h" + +namespace __llvm_libc { + +long LLVM_LIBC_ENTRYPOINT(labs)(long n) { + // integer_abs from abs_utils.h. + return integer_abs(n); +} + +} // namespace __llvm_libc diff --git a/libc/src/stdlib/llabs.h b/libc/src/stdlib/llabs.h new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/llabs.h @@ -0,0 +1,18 @@ +//===-- Implementation header for llabs -------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDLIB_LLABS_H +#define LLVM_LIBC_SRC_STDLIB_LLABS_H + +namespace __llvm_libc { + +long long llabs(long long n); + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STDLIB_LLABS_H diff --git a/libc/src/stdlib/llabs.cpp b/libc/src/stdlib/llabs.cpp new file mode 100644 --- /dev/null +++ b/libc/src/stdlib/llabs.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of llabs -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/llabs.h" +#include "src/__support/common.h" +#include "src/stdlib/abs_utils.h" + +namespace __llvm_libc { + +long long LLVM_LIBC_ENTRYPOINT(llabs)(long long n) { + // integer_abs from abs_utils.h. + return integer_abs(n); +} + +} // namespace __llvm_libc diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -24,3 +24,33 @@ libc.src.stdlib._Exit libc.src.signal.raise ) + +add_libc_unittest( + abs_test + SUITE + libc_stdlib_unittests + SRCS + abs_test.cpp + DEPENDS + libc.src.stdlib.abs +) + +add_libc_unittest( + labs_test + SUITE + libc_stdlib_unittests + SRCS + labs_test.cpp + DEPENDS + libc.src.stdlib.labs +) + +add_libc_unittest( + llabs_test + SUITE + libc_stdlib_unittests + SRCS + llabs_test.cpp + DEPENDS + libc.src.stdlib.llabs +) diff --git a/libc/test/src/stdlib/abs_test.cpp b/libc/test/src/stdlib/abs_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/stdlib/abs_test.cpp @@ -0,0 +1,16 @@ +//===-- Unittests for abs -------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/abs.h" +#include "utils/UnitTest/Test.h" + +TEST(AbsTest, Zero) { EXPECT_EQ(__llvm_libc::abs(0), 0); } + +TEST(AbsTest, Positive) { EXPECT_EQ(__llvm_libc::abs(1), 1); } + +TEST(AbsTest, Negative) { EXPECT_EQ(__llvm_libc::abs(-1), 1); } diff --git a/libc/test/src/stdlib/labs_test.cpp b/libc/test/src/stdlib/labs_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/stdlib/labs_test.cpp @@ -0,0 +1,16 @@ +//===-- Unittests for labs ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/labs.h" +#include "utils/UnitTest/Test.h" + +TEST(LabsTest, Zero) { EXPECT_EQ(__llvm_libc::labs(0l), 0l); } + +TEST(LabsTest, Positive) { EXPECT_EQ(__llvm_libc::labs(1l), 1l); } + +TEST(LabsTest, Negative) { EXPECT_EQ(__llvm_libc::labs(-1l), 1l); } diff --git a/libc/test/src/stdlib/llabs_test.cpp b/libc/test/src/stdlib/llabs_test.cpp new file mode 100644 --- /dev/null +++ b/libc/test/src/stdlib/llabs_test.cpp @@ -0,0 +1,16 @@ +//===-- Unittests for llabs -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/llabs.h" +#include "utils/UnitTest/Test.h" + +TEST(LlabsTest, Zero) { EXPECT_EQ(__llvm_libc::llabs(0ll), 0ll); } + +TEST(LlabsTest, Positive) { EXPECT_EQ(__llvm_libc::llabs(1ll), 1ll); } + +TEST(LlabsTest, Negative) { EXPECT_EQ(__llvm_libc::llabs(-1ll), 1ll); }