[libc] Add [l|ll]abs implementation.
Implement abs, labs and llabs with template.
Reviewed By: sivachandra
Differential Revision: https://reviews.llvm.org/D92626
GitOrigin-RevId: 1fd32dcb294e16781fcfcf1a468180d00cf1e3ca
diff --git a/config/linux/aarch64/entrypoints.txt b/config/linux/aarch64/entrypoints.txt
index 3a3b050..534a4bd 100644
--- a/config/linux/aarch64/entrypoints.txt
+++ b/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/config/linux/x86_64/entrypoints.txt b/config/linux/x86_64/entrypoints.txt
index 2b461c4..4cae553 100644
--- a/config/linux/x86_64/entrypoints.txt
+++ b/config/linux/x86_64/entrypoints.txt
@@ -41,6 +41,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/spec/spec.td b/spec/spec.td
index 29c11a9..9a31d85 100644
--- a/spec/spec.td
+++ b/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/spec/stdc.td b/spec/stdc.td
index 70cc260..051e0a8 100644
--- a/spec/stdc.td
+++ b/spec/stdc.td
@@ -400,6 +400,9 @@
[], // Enumerations
[
FunctionSpec<"abort", RetValSpec<NoReturn>, [ArgSpec<VoidType>]>,
+ FunctionSpec<"abs", RetValSpec<IntType>, [ArgSpec<IntType>]>,
+ FunctionSpec<"labs", RetValSpec<LongType>, [ArgSpec<LongType>]>,
+ FunctionSpec<"llabs", RetValSpec<LongLongType>, [ArgSpec<LongLongType>]>,
FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
]
>;
diff --git a/src/stdlib/CMakeLists.txt b/src/stdlib/CMakeLists.txt
index 50b7421..a599d8a 100644
--- a/src/stdlib/CMakeLists.txt
+++ b/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/src/stdlib/abs.cpp b/src/stdlib/abs.cpp
new file mode 100644
index 0000000..74c47cd
--- /dev/null
+++ b/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/src/stdlib/abs.h b/src/stdlib/abs.h
new file mode 100644
index 0000000..42ef7f8
--- /dev/null
+++ b/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/src/stdlib/abs_utils.h b/src/stdlib/abs_utils.h
new file mode 100644
index 0000000..c0943fe
--- /dev/null
+++ b/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 <typename T> 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/src/stdlib/labs.cpp b/src/stdlib/labs.cpp
new file mode 100644
index 0000000..427cb9d
--- /dev/null
+++ b/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/src/stdlib/labs.h b/src/stdlib/labs.h
new file mode 100644
index 0000000..0f0ea99
--- /dev/null
+++ b/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/src/stdlib/llabs.cpp b/src/stdlib/llabs.cpp
new file mode 100644
index 0000000..8878ce4
--- /dev/null
+++ b/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/src/stdlib/llabs.h b/src/stdlib/llabs.h
new file mode 100644
index 0000000..f173431
--- /dev/null
+++ b/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/test/src/stdlib/CMakeLists.txt b/test/src/stdlib/CMakeLists.txt
index 06adaa2..e5cb04a 100644
--- a/test/src/stdlib/CMakeLists.txt
+++ b/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/test/src/stdlib/abs_test.cpp b/test/src/stdlib/abs_test.cpp
new file mode 100644
index 0000000..6f1a46e
--- /dev/null
+++ b/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/test/src/stdlib/labs_test.cpp b/test/src/stdlib/labs_test.cpp
new file mode 100644
index 0000000..cd81425
--- /dev/null
+++ b/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/test/src/stdlib/llabs_test.cpp b/test/src/stdlib/llabs_test.cpp
new file mode 100644
index 0000000..4b5fde9
--- /dev/null
+++ b/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); }