[libc-commits] [libc] 74670e7 - [libc] Add implementations of div, ldiv, lldiv and imaxdiv.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Sun Sep 19 21:51:58 PDT 2021
Author: Siva Chandra Reddy
Date: 2021-09-20T04:51:42Z
New Revision: 74670e79b0a00224c04dfc6a446ea4439f4cfca4
URL: https://github.com/llvm/llvm-project/commit/74670e79b0a00224c04dfc6a446ea4439f4cfca4
DIFF: https://github.com/llvm/llvm-project/commit/74670e79b0a00224c04dfc6a446ea4439f4cfca4.diff
LOG: [libc] Add implementations of div, ldiv, lldiv and imaxdiv.
Reviewed By: michaelrj
Differential Revision: https://reviews.llvm.org/D109952
Added:
libc/src/inttypes/imaxdiv.cpp
libc/src/inttypes/imaxdiv.h
libc/src/stdlib/div.cpp
libc/src/stdlib/div.h
libc/src/stdlib/ldiv.cpp
libc/src/stdlib/ldiv.h
libc/src/stdlib/lldiv.cpp
libc/src/stdlib/lldiv.h
libc/test/src/inttypes/imaxdiv_test.cpp
libc/test/src/stdlib/DivTest.h
libc/test/src/stdlib/div_test.cpp
libc/test/src/stdlib/ldiv_test.cpp
libc/test/src/stdlib/lldiv_test.cpp
Modified:
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/api.td
libc/config/linux/x86_64/entrypoints.txt
libc/spec/stdc.td
libc/src/__support/integer_operations.h
libc/src/inttypes/CMakeLists.txt
libc/src/stdlib/CMakeLists.txt
libc/test/src/inttypes/CMakeLists.txt
libc/test/src/stdlib/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 8dbbb64abbd6..20583ea19dc2 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -46,13 +46,20 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strtok_r
# inttypes.h entrypoints
+ libc.src.inttypes.imaxdiv
libc.src.inttypes.strtoimax
libc.src.inttypes.strtoumax
# stdlib.h entrypoints
+ libc.src.stdlib.abs
libc.src.stdlib.atoi
libc.src.stdlib.atol
libc.src.stdlib.atoll
+ libc.src.stdlib.div
+ libc.src.stdlib.labs
+ libc.src.stdlib.ldiv
+ libc.src.stdlib.llabs
+ libc.src.stdlib.lldiv
libc.src.stdlib.strtol
libc.src.stdlib.strtoll
libc.src.stdlib.strtoul
@@ -161,15 +168,6 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.truncl
)
-if(LLVM_LIBC_FULL_BUILD)
- list(APPEND TARGET_LIBC_ENTRYPOINTS
- # stdlib.h entrypoints
- libc.src.stdlib.abs
- libc.src.stdlib.labs
- libc.src.stdlib.llabs
- )
-endif()
-
set(TARGET_LLVMLIBC_ENTRYPOINTS
${TARGET_LIBC_ENTRYPOINTS}
${TARGET_LIBM_ENTRYPOINTS}
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index ddcf9018f66d..757469b0de91 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -111,6 +111,21 @@ def AssertAPI : PublicAPI<"assert.h"> {
def CTypeAPI : PublicAPI<"ctype.h"> {
}
+def IMaxDivT : TypeDecl<"imaxdiv_t"> {
+ let Decl = [{
+ typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+ } imaxdiv_t;
+ }];
+}
+
+def IntTypesAPI : PublicAPI<"inttypes.h"> {
+ let TypeDeclarations = [
+ IMaxDivT,
+ ];
+}
+
def MathErrHandlingMacro : MacroDef<"math_errhandling"> {
let Defn = [{
#ifndef math_errhandling
@@ -239,7 +254,39 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
];
}
+def DivT : TypeDecl<"div_t"> {
+ let Decl = [{
+ typedef struct {
+ int quot;
+ int rem;
+ } div_t;
+ }];
+}
+
+def LDivT : TypeDecl<"ldiv_t"> {
+ let Decl = [{
+ typedef struct {
+ long quot;
+ long rem;
+ } ldiv_t;
+ }];
+}
+
+def LLDivT : TypeDecl<"lldiv_t"> {
+ let Decl = [{
+ typedef struct {
+ long long quot;
+ long long rem;
+ } lldiv_t;
+ }];
+}
+
def StdlibAPI : PublicAPI<"stdlib.h"> {
+ let TypeDeclarations = [
+ DivT,
+ LDivT,
+ LLDivT,
+ ];
}
def TimeAPI : PublicAPI<"time.h"> {
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9836d62f8904..503bd9a9056a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -46,13 +46,20 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strtok_r
# inttypes.h entrypoints
+ libc.src.inttypes.imaxdiv
libc.src.inttypes.strtoimax
libc.src.inttypes.strtoumax
# stdlib.h entrypoints
+ libc.src.stdlib.abs
libc.src.stdlib.atoi
libc.src.stdlib.atol
libc.src.stdlib.atoll
+ libc.src.stdlib.div
+ libc.src.stdlib.labs
+ libc.src.stdlib.ldiv
+ libc.src.stdlib.llabs
+ libc.src.stdlib.lldiv
libc.src.stdlib.strtol
libc.src.stdlib.strtoll
libc.src.stdlib.strtoul
@@ -172,9 +179,6 @@ if(LLVM_LIBC_FULL_BUILD)
# stdlib.h entrypoints
libc.src.stdlib._Exit
libc.src.stdlib.abort
- libc.src.stdlib.abs
- libc.src.stdlib.labs
- libc.src.stdlib.llabs
# signal.h entrypoints
libc.src.signal.raise
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index c50f9175fb69..46f56a44068c 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -7,6 +7,10 @@ def StdC : StandardSpec<"stdc"> {
PtrType StructTmPtr = PtrType<StructTmType>;
PtrType TimeTTypePtr = PtrType<TimeTType>;
+ NamedType DivTType = NamedType<"div_t">;
+ NamedType LDivTType = NamedType<"ldiv_t">;
+ NamedType LLDivTType = NamedType<"lldiv_t">;
+
HeaderSpec Assert = HeaderSpec<
"assert.h",
[
@@ -471,32 +475,48 @@ def StdC : StandardSpec<"stdc"> {
HeaderSpec StdLib = HeaderSpec<
"stdlib.h",
[], // Macros
- [], // Types
+ [
+ DivTType,
+ LDivTType,
+ LLDivTType,
+ ], // Types
[], // 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<"atoi", RetValSpec<IntType>, [ArgSpec<ConstCharPtr>]>,
FunctionSpec<"atol", RetValSpec<LongType>, [ArgSpec<ConstCharPtr>]>,
FunctionSpec<"atoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharPtr>]>,
- FunctionSpec<"labs", RetValSpec<LongType>, [ArgSpec<LongType>]>,
- FunctionSpec<"llabs", RetValSpec<LongLongType>, [ArgSpec<LongLongType>]>,
+
+ FunctionSpec<"div", RetValSpec<DivTType>, [ArgSpec<IntType>, ArgSpec<IntType>]>,
+ FunctionSpec<"ldiv", RetValSpec<LDivTType>, [ArgSpec<LongType>, ArgSpec<LongType>]>,
+ FunctionSpec<"lldiv", RetValSpec<LLDivTType>, [ArgSpec<LongLongType>, ArgSpec<LongLongType>]>,
+
FunctionSpec<"strtol", RetValSpec<LongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoll", RetValSpec<LongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoul", RetValSpec<UnsignedLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoull", RetValSpec<UnsignedLongLongType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
+
FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
]
>;
+ NamedType IMaxDivTType = NamedType<"imaxdiv_t">;
+
HeaderSpec IntTypes = HeaderSpec<
"inttypes.h",
[], // Macros
- [], // Types
+ [
+ IMaxDivTType,
+ ], // Types
[], // Enumerations
[
FunctionSpec<"imaxabs", RetValSpec<IntMaxTType>, [ArgSpec<IntMaxTType>]>,
- FunctionSpec<"imaxdiv", RetValSpec<IntMaxTType>, [ArgSpec<IntMaxTType>, ArgSpec<IntMaxTType>]>,
+ FunctionSpec<"imaxdiv", RetValSpec<IMaxDivTType>, [ArgSpec<IntMaxTType>, ArgSpec<IntMaxTType>]>,
FunctionSpec<"strtoimax", RetValSpec<IntMaxTType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
FunctionSpec<"strtoumax", RetValSpec<UIntMaxTType>, [ArgSpec<ConstCharRestrictedPtr>, ArgSpec<CharRestrictedPtrPtr>, ArgSpec<IntType>]>,
]
diff --git a/libc/src/__support/integer_operations.h b/libc/src/__support/integer_operations.h
index 4c13bb86e2d8..c27a2632964b 100644
--- a/libc/src/__support/integer_operations.h
+++ b/libc/src/__support/integer_operations.h
@@ -19,6 +19,13 @@ integerAbs(T n) {
return (n < 0) ? -n : n;
}
+template <typename T>
+static constexpr cpp::EnableIfType<cpp::IsIntegral<T>::Value, void>
+integerRemQuo(T x, T y, T ", T &rem) {
+ quot = x / y;
+ rem = x % y;
+}
+
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_STDLIB_ABS_UTILS_H
diff --git a/libc/src/inttypes/CMakeLists.txt b/libc/src/inttypes/CMakeLists.txt
index 65c1d7e2063a..81068bd73c50 100644
--- a/libc/src/inttypes/CMakeLists.txt
+++ b/libc/src/inttypes/CMakeLists.txt
@@ -17,3 +17,13 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.str_conv_utils
)
+
+add_entrypoint_object(
+ imaxdiv
+ SRCS
+ imaxdiv.cpp
+ HDRS
+ imaxdiv.h
+ DEPENDS
+ libc.src.__support.integer_operations
+)
diff --git a/libc/src/inttypes/imaxdiv.cpp b/libc/src/inttypes/imaxdiv.cpp
new file mode 100644
index 000000000000..6189fc197b1e
--- /dev/null
+++ b/libc/src/inttypes/imaxdiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of imaxdiv -----------------------------------------===//
+//
+// 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/inttypes/imaxdiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(imaxdiv_t, imaxdiv, (intmax_t x, intmax_t y)) {
+ imaxdiv_t res;
+ integerRemQuo(x, y, res.quot, res.rem);
+ return res;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/inttypes/imaxdiv.h b/libc/src/inttypes/imaxdiv.h
new file mode 100644
index 000000000000..c8af35272fcc
--- /dev/null
+++ b/libc/src/inttypes/imaxdiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for imaxdiv -----------------------*- 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_INTTYPES_IMAXDIV_H
+#define LLVM_LIBC_SRC_INTTYPES_IMAXDIV_H
+
+#include <inttypes.h>
+
+namespace __llvm_libc {
+
+imaxdiv_t imaxdiv(intmax_t x, intmax_t y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_INTTYPES_IMAXDIV_H
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index bf1b6371f245..4f676129dbd3 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -124,3 +124,33 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.integer_operations
)
+
+add_entrypoint_object(
+ div
+ SRCS
+ div.cpp
+ HDRS
+ div.h
+ DEPENDS
+ libc.src.__support.integer_operations
+)
+
+add_entrypoint_object(
+ ldiv
+ SRCS
+ ldiv.cpp
+ HDRS
+ ldiv.h
+ DEPENDS
+ libc.src.__support.integer_operations
+)
+
+add_entrypoint_object(
+ lldiv
+ SRCS
+ lldiv.cpp
+ HDRS
+ lldiv.h
+ DEPENDS
+ libc.src.__support.integer_operations
+)
diff --git a/libc/src/stdlib/div.cpp b/libc/src/stdlib/div.cpp
new file mode 100644
index 000000000000..042346dd8f59
--- /dev/null
+++ b/libc/src/stdlib/div.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of div ---------------------------------------------===//
+//
+// 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/div.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(div_t, div, (int x, int y)) {
+ div_t res;
+ integerRemQuo(x, y, res.quot, res.rem);
+ return res;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/div.h b/libc/src/stdlib/div.h
new file mode 100644
index 000000000000..ec1ded78a0ab
--- /dev/null
+++ b/libc/src/stdlib/div.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for div ---------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_DIV_H
+#define LLVM_LIBC_SRC_STDLIB_DIV_H
+
+namespace __llvm_libc {
+
+div_t div(int x, int y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_DIV_H
diff --git a/libc/src/stdlib/ldiv.cpp b/libc/src/stdlib/ldiv.cpp
new file mode 100644
index 000000000000..fdac26045724
--- /dev/null
+++ b/libc/src/stdlib/ldiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of ldiv --------------------------------------------===//
+//
+// 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/ldiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(ldiv_t, ldiv, (long x, long y)) {
+ ldiv_t res;
+ integerRemQuo(x, y, res.quot, res.rem);
+ return res;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/ldiv.h b/libc/src/stdlib/ldiv.h
new file mode 100644
index 000000000000..f4e7730a522f
--- /dev/null
+++ b/libc/src/stdlib/ldiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for ldiv --------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_LDIV_H
+#define LLVM_LIBC_SRC_STDLIB_LDIV_H
+
+namespace __llvm_libc {
+
+ldiv_t ldiv(long x, long y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
diff --git a/libc/src/stdlib/lldiv.cpp b/libc/src/stdlib/lldiv.cpp
new file mode 100644
index 000000000000..958b01fcc01e
--- /dev/null
+++ b/libc/src/stdlib/lldiv.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of lldiv -------------------------------------------===//
+//
+// 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/lldiv.h"
+#include "src/__support/common.h"
+#include "src/__support/integer_operations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(lldiv_t, lldiv, (long long x, long long y)) {
+ lldiv_t res;
+ integerRemQuo(x, y, res.quot, res.rem);
+ return res;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdlib/lldiv.h b/libc/src/stdlib/lldiv.h
new file mode 100644
index 000000000000..7f0de5c99393
--- /dev/null
+++ b/libc/src/stdlib/lldiv.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for lldiv -------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdlib.h>
+
+#ifndef LLVM_LIBC_SRC_STDLIB_LLDIV_H
+#define LLVM_LIBC_SRC_STDLIB_LLDIV_H
+
+namespace __llvm_libc {
+
+lldiv_t lldiv(long long x, long long y);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
diff --git a/libc/test/src/inttypes/CMakeLists.txt b/libc/test/src/inttypes/CMakeLists.txt
index d9885ba53eed..9a6d6ac71bbe 100644
--- a/libc/test/src/inttypes/CMakeLists.txt
+++ b/libc/test/src/inttypes/CMakeLists.txt
@@ -19,3 +19,16 @@ add_libc_unittest(
DEPENDS
libc.src.inttypes.strtoumax
)
+
+add_libc_unittest(
+ imaxdiv_test
+ SUITE
+ libc_inttypes_unittests
+ SRCS
+ imaxdiv_test.cpp
+ HDRS
+ ../stdlib/DivTest.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.inttypes.imaxdiv
+)
diff --git a/libc/test/src/inttypes/imaxdiv_test.cpp b/libc/test/src/inttypes/imaxdiv_test.cpp
new file mode 100644
index 000000000000..321aad5d0ebc
--- /dev/null
+++ b/libc/test/src/inttypes/imaxdiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for imaxdiv ---------------------------------------------===//
+//
+// 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 "../stdlib/DivTest.h"
+
+#include "src/inttypes/imaxdiv.h"
+
+#include <inttypes.h>
+
+LIST_DIV_TESTS(intmax_t, imaxdiv_t, __llvm_libc::imaxdiv)
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 6aed171938de..4eb8526d4e52 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -128,3 +128,42 @@ add_libc_unittest(
DEPENDS
libc.src.stdlib.llabs
)
+
+add_libc_unittest(
+ div_test
+ SUITE
+ libc_stdlib_unittests
+ SRCS
+ div_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.stdlib.div
+)
+
+add_libc_unittest(
+ ldiv_test
+ SUITE
+ libc_stdlib_unittests
+ SRCS
+ ldiv_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.stdlib.ldiv
+)
+
+add_libc_unittest(
+ lldiv_test
+ SUITE
+ libc_stdlib_unittests
+ SRCS
+ lldiv_test.cpp
+ HDRS
+ DivTest.h
+ DEPENDS
+ libc.include.stdlib
+ libc.src.stdlib.lldiv
+)
diff --git a/libc/test/src/stdlib/DivTest.h b/libc/test/src/stdlib/DivTest.h
new file mode 100644
index 000000000000..13978ac531e4
--- /dev/null
+++ b/libc/test/src/stdlib/DivTest.h
@@ -0,0 +1,37 @@
+//===-- A template class for testing div functions --------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "utils/UnitTest/Test.h"
+
+template <typename IntType, typename ReturnType>
+class DivTest : public __llvm_libc::testing::Test {
+public:
+ using DivFunc = ReturnType(IntType, IntType);
+
+ void simpleTest(DivFunc func) {
+ auto result = func(10, 3);
+ EXPECT_EQ(result.quot, IntType(3));
+ EXPECT_EQ(result.rem, IntType(1));
+
+ result = func(-10, 3);
+ EXPECT_EQ(result.quot, IntType(-3));
+ EXPECT_EQ(result.rem, IntType(-1));
+
+ result = func(-10, -3);
+ EXPECT_EQ(result.quot, IntType(3));
+ EXPECT_EQ(result.rem, IntType(-1));
+
+ result = func(10, -3);
+ EXPECT_EQ(result.quot, IntType(-3));
+ EXPECT_EQ(result.rem, IntType(1));
+ }
+};
+
+#define LIST_DIV_TESTS(IntType, ReturnType, func) \
+ using LlvmLibcDivTest = DivTest<IntType, ReturnType>; \
+ TEST_F(LlvmLibcDivTest, SimpleTest) { simpleTest(func); }
diff --git a/libc/test/src/stdlib/div_test.cpp b/libc/test/src/stdlib/div_test.cpp
new file mode 100644
index 000000000000..6b1f20d18685
--- /dev/null
+++ b/libc/test/src/stdlib/div_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for div -------------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/div.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(int, div_t, __llvm_libc::div)
diff --git a/libc/test/src/stdlib/ldiv_test.cpp b/libc/test/src/stdlib/ldiv_test.cpp
new file mode 100644
index 000000000000..d28d38789a71
--- /dev/null
+++ b/libc/test/src/stdlib/ldiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for ldiv ------------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/ldiv.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(long, ldiv_t, __llvm_libc::ldiv)
diff --git a/libc/test/src/stdlib/lldiv_test.cpp b/libc/test/src/stdlib/lldiv_test.cpp
new file mode 100644
index 000000000000..5fa0de23f930
--- /dev/null
+++ b/libc/test/src/stdlib/lldiv_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for lldiv -----------------------------------------------===//
+//
+// 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 "DivTest.h"
+
+#include "src/stdlib/lldiv.h"
+
+#include <stdlib.h>
+
+LIST_DIV_TESTS(long long, lldiv_t, __llvm_libc::lldiv)
More information about the libc-commits
mailing list