[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 &quot, 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