[libc-commits] [libc] [libc][stdfix] Implement divifx functions in LLVM libc (PR #206115)
via libc-commits
libc-commits at lists.llvm.org
Sat Jun 27 07:55:31 PDT 2026
https://github.com/sohail103 updated https://github.com/llvm/llvm-project/pull/206115
>From 6c54655ee4a93a0501231461fb13f0ad2f7bdb7e Mon Sep 17 00:00:00 2001
From: sohail103 <sohailraj.satapathy at gmail.com>
Date: Fri, 26 Jun 2026 13:04:10 +0530
Subject: [PATCH 1/3] [libc][stdfix] add divir implementation
---
libc/config/baremetal/arm/entrypoints.txt | 1 +
libc/config/baremetal/riscv/entrypoints.txt | 1 +
libc/config/linux/riscv/entrypoints.txt | 1 +
libc/config/linux/x86_64/entrypoints.txt | 1 +
libc/docs/headers/stdfix.rst | 2 +-
libc/include/stdfix.yaml | 8 ++
libc/src/__support/fixed_point/CMakeLists.txt | 1 +
libc/src/__support/fixed_point/fx_bits.h | 46 +++++++++++
libc/src/stdfix/CMakeLists.txt | 14 ++++
libc/src/stdfix/divir.cpp | 21 +++++
libc/src/stdfix/divir.h | 21 +++++
libc/test/src/stdfix/CMakeLists.txt | 17 ++++
libc/test/src/stdfix/DiviFxTest.h | 80 +++++++++++++++++++
libc/test/src/stdfix/divir_test.cpp | 14 ++++
14 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 libc/src/stdfix/divir.cpp
create mode 100644 libc/src/stdfix/divir.h
create mode 100644 libc/test/src/stdfix/DiviFxTest.h
create mode 100644 libc/test/src/stdfix/divir_test.cpp
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index a5c1b20a7a434..8c592f211a4e1 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -970,6 +970,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
+ libc.src.stdfix.divir
)
endif()
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 60bc924993fc8..03b48cbd4e3f6 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -967,6 +967,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
+ libc.src.stdfix.divir
)
endif()
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 2508de5cfe5a4..a1d5836307ba8 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1102,6 +1102,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
libc.src.stdfix.rdivi
+ libc.src.stdfix.divir
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5ace968a739c8..059a171662b75 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1173,6 +1173,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
libc.src.stdfix.rdivi
+ libc.src.stdfix.divir
)
endif()
diff --git a/libc/docs/headers/stdfix.rst b/libc/docs/headers/stdfix.rst
index 76ac7e7b71c95..84294a4e14792 100644
--- a/libc/docs/headers/stdfix.rst
+++ b/libc/docs/headers/stdfix.rst
@@ -73,7 +73,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| countls | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
-| divi\* | | | | | | | | | | | | |
+| divi\* | | | | |check| | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| idiv\* | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
diff --git a/libc/include/stdfix.yaml b/libc/include/stdfix.yaml
index 8b7485555c080..4f3cfa39ce974 100644
--- a/libc/include/stdfix.yaml
+++ b/libc/include/stdfix.yaml
@@ -565,3 +565,11 @@ functions:
- type: int
- type: int
guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: divir
+ standards:
+ - stdc_ext
+ return_type: int
+ arguments:
+ - type: int
+ - type: fract
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
diff --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt
index 145eedb6ae8e7..c1b0ab30e0307 100644
--- a/libc/src/__support/fixed_point/CMakeLists.txt
+++ b/libc/src/__support/fixed_point/CMakeLists.txt
@@ -23,6 +23,7 @@ add_header_library(
libc.src.__support.CPP.bit
libc.src.__support.CPP.limits
libc.src.__support.math_extras
+ libc.src.__support.uint128
)
add_header_library(
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 91814bda7dd7e..8622040e2215e 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -14,12 +14,14 @@
#include "src/__support/CPP/bit.h"
#include "src/__support/CPP/limits.h" // numeric_limits
#include "src/__support/CPP/type_traits.h"
+#include "src/__support/CPP/type_traits/conditional.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
#include "src/__support/macros/null_check.h" // LIBC_CRASH_ON_VALUE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/math_extras.h"
+#include "src/__support/uint128.h"
#include "fx_rep.h"
@@ -333,6 +335,50 @@ template <typename XType> LIBC_INLINE constexpr XType divi(int n, int d) {
}
}
+// divide an integer operand by a fixed-point operand and return the
+// mathematically exact result as an IntType rounded towards 0. assumes
+// signedness of IntType matches the signedness of FXType. all divifx variants
+// satisfy this requirement.
+template <typename IntType, typename FXType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<FXType>, IntType>
+divifx(IntType n, FXType d) {
+ using FXBits = FXBits<FXType>;
+ using FXRep = FXRep<FXType>;
+ using CompType = typename FXRep::CompType;
+
+ static_assert(cpp::is_signed_v<IntType> == (FXRep::SIGN_LEN > 0),
+ "IntType and FXType must have matching signedness");
+
+ // UB if denominator is 0
+ LIBC_CRASH_ON_VALUE(d, FXRep::ZERO());
+
+ if (LIBC_UNLIKELY(n == 0)) {
+ return static_cast<IntType>(0);
+ }
+
+ // get integer representation of denominator
+ CompType d_comp = static_cast<CompType>(FXBits(d).get_bits());
+
+ constexpr int F = FXRep::FRACTION_LEN;
+
+ // calculating the required number of bits to represent n*2^F without
+ // overflowing
+ constexpr int INTERMEDIATE_BITS =
+ sizeof(IntType) * 8 - cpp::is_signed_v<IntType> + F;
+
+ // use 64 or 128 bit intermediates depending on INTERMEDIATE_BITS
+ using WideType = cpp::conditional_t<
+ cpp::is_signed_v<IntType>,
+ cpp::conditional_t<INTERMEDIATE_BITS <= 64, int64_t, Int128>,
+ cpp::conditional_t<INTERMEDIATE_BITS <= 64, uint64_t, UInt128>>;
+
+ // (n*2^F/d)
+ WideType scaled_n = static_cast<WideType>(n) << F;
+ WideType result = scaled_n / static_cast<WideType>(d_comp);
+
+ return static_cast<IntType>(result);
+}
+
} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index e9841cd940315..f7b48b375cdba 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -102,6 +102,20 @@ foreach(suffix IN ITEMS r)
)
endforeach()
+foreach(suffix IN ITEMS r)
+ add_entrypoint_object(
+ divi${suffix}
+ HDRS
+ divi${suffix}.h
+ SRCS
+ divi${suffix}.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ DEPENDS
+ libc.src.__support.fixed_point.fx_bits
+ )
+endforeach()
+
add_entrypoint_object(
uhksqrtus
HDRS
diff --git a/libc/src/stdfix/divir.cpp b/libc/src/stdfix/divir.cpp
new file mode 100644
index 0000000000000..990db419ef1b6
--- /dev/null
+++ b/libc/src/stdfix/divir.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of divir function ---------------------------------===//
+//
+// 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 "divir.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, divir, (int n, fract d)) {
+ return fixed_point::divifx<int, fract>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/divir.h b/libc/src/stdfix/divir.h
new file mode 100644
index 0000000000000..f54dcd9e8ca32
--- /dev/null
+++ b/libc/src/stdfix/divir.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for divir ------------------------*- 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_STDFIX_DIVIR_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int divir(int n, fract d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIR_H
diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 04bedc3e00fe2..3bf3051c6b85a 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -147,6 +147,23 @@ foreach(suffix IN ITEMS r)
)
endforeach()
+foreach(suffix IN ITEMS r)
+ add_libc_test(
+ divi${suffix}_test
+ SUITE
+ libc-stdfix-tests
+ HDRS
+ DiviFxTest.h
+ SRCS
+ divi${suffix}_test.cpp
+ DEPENDS
+ libc.src.stdfix.divi${suffix}
+ libc.src.__support.fixed_point.fx_rep
+ libc.src.__support.fixed_point.fx_bits
+ libc.hdr.signal_macros
+ )
+endforeach()
+
add_libc_test(
uhksqrtus_test
SUITE
diff --git a/libc/test/src/stdfix/DiviFxTest.h b/libc/test/src/stdfix/DiviFxTest.h
new file mode 100644
index 0000000000000..c3e0b8ac038e9
--- /dev/null
+++ b/libc/test/src/stdfix/DiviFxTest.h
@@ -0,0 +1,80 @@
+//===-- Utility class to test divifx 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 "test/UnitTest/Test.h"
+
+#include "hdr/signal_macros.h"
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/fixed_point/fx_rep.h"
+
+template <typename IntType, typename FXType>
+class DiviFxTest : public LIBC_NAMESPACE::testing::Test {
+
+ using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<FXType>;
+
+ static constexpr FXType zero = FXRep::ZERO();
+ static constexpr FXType min = FXRep::MIN();
+ static constexpr FXType one_half = FXRep::ONE_HALF();
+ static constexpr FXType one_fourth = FXRep::ONE_FOURTH();
+
+public:
+ typedef IntType (*DiviFxFunc)(IntType, FXType);
+
+ void testBasicNumbers(DiviFxFunc func) {
+ constexpr bool is_signed = (FXRep::SIGN_LEN > 0);
+
+ EXPECT_EQ(func(1, one_fourth), static_cast<IntType>(4));
+ EXPECT_EQ(func(1, one_half), static_cast<IntType>(2));
+ EXPECT_EQ(func(1, 0.125r), static_cast<IntType>(8));
+ EXPECT_EQ(func(2, one_fourth), static_cast<IntType>(8));
+ EXPECT_EQ(func(2, one_half), static_cast<IntType>(4));
+ EXPECT_EQ(func(2, 0.125r), static_cast<IntType>(16));
+
+ // verify rounding towards 0
+ EXPECT_EQ(func(1, 3 * one_fourth), static_cast<IntType>(1));
+ EXPECT_EQ(func(2, 3 * one_fourth), static_cast<IntType>(2));
+
+ if constexpr (is_signed) {
+ EXPECT_EQ(func(-1, one_half), static_cast<IntType>(-2));
+ EXPECT_EQ(func(1, -one_half), static_cast<IntType>(-2));
+ EXPECT_EQ(func(-1, -one_half), static_cast<IntType>(2));
+ EXPECT_EQ(func(-2, one_fourth), static_cast<IntType>(-8));
+ EXPECT_EQ(func(2, -one_fourth), static_cast<IntType>(-8));
+
+ // verify rounding towards 0
+ EXPECT_EQ(func(-1, 3 * one_fourth), static_cast<IntType>(-1));
+ EXPECT_EQ(func(1, -3 * one_fourth), static_cast<IntType>(-1));
+ EXPECT_EQ(func(-2, 3 * one_fourth), static_cast<IntType>(-2));
+ EXPECT_EQ(func(2, -3 * one_fourth), static_cast<IntType>(-2));
+ } else {
+ // min of unsigned type = 0
+ EXPECT_EQ(func(min, one_half), static_cast<IntType>(0));
+ EXPECT_EQ(func(min, one_fourth), static_cast<IntType>(0));
+ }
+ }
+
+ void testInvalidNumbers(DiviFxFunc func) {
+ EXPECT_DEATH([func] { func(1, zero); }, WITH_SIGNAL(-1));
+ }
+};
+
+#if defined(LIBC_ADD_NULL_CHECKS)
+#define LIST_DIVIFX_TESTS(Name, IntType, FXType, func) \
+ using LlvmLibcDivi##Name##Test = DiviFxTest<IntType, FXType>; \
+ TEST_F(LlvmLibcDivi##Name##Test, InvalidNumbers) { \
+ testInvalidNumbers(&func); \
+ } \
+ TEST_F(LlvmLibcDivi##Name##Test, BasicNumbers) { testBasicNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
+#else
+#define LIST_DIVIFX_TESTS(Name, IntType, FXType, func) \
+ using LlvmLibcDivi##Name##Test = DiviFxTest<IntType, FXType>; \
+ TEST_F(LlvmLibcDivi##Name##Test, BasicNumbers) { testBasicNumbers(&func); } \
+ static_assert(true, "Require semicolon.")
+#endif // LIBC_ADD_NULL_CHECKS
diff --git a/libc/test/src/stdfix/divir_test.cpp b/libc/test/src/stdfix/divir_test.cpp
new file mode 100644
index 0000000000000..97f8dab63afba
--- /dev/null
+++ b/libc/test/src/stdfix/divir_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for divir -----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // fract
+#include "src/stdfix/divir.h"
+
+LIST_DIVIFX_TESTS(r, int, fract, LIBC_NAMESPACE::divir);
>From e46bbc429fb729b3d87048fd679807b7a5d7d348 Mon Sep 17 00:00:00 2001
From: sohail103 <sohailraj.satapathy at gmail.com>
Date: Fri, 26 Jun 2026 20:57:59 +0530
Subject: [PATCH 2/3] [libc][stdfix] implement remaining divifx functions along
with tests
---
libc/config/baremetal/arm/entrypoints.txt | 7 +++
libc/config/baremetal/riscv/entrypoints.txt | 7 +++
libc/config/linux/riscv/entrypoints.txt | 7 +++
libc/config/linux/x86_64/entrypoints.txt | 7 +++
libc/docs/headers/stdfix.rst | 2 +-
libc/include/stdfix.yaml | 56 +++++++++++++++++++++
libc/src/stdfix/CMakeLists.txt | 2 +-
libc/src/stdfix/divik.cpp | 21 ++++++++
libc/src/stdfix/divik.h | 21 ++++++++
libc/src/stdfix/divilk.cpp | 21 ++++++++
libc/src/stdfix/divilk.h | 21 ++++++++
libc/src/stdfix/divilr.cpp | 21 ++++++++
libc/src/stdfix/divilr.h | 21 ++++++++
libc/src/stdfix/diviuk.cpp | 20 ++++++++
libc/src/stdfix/diviuk.h | 21 ++++++++
libc/src/stdfix/diviulk.cpp | 22 ++++++++
libc/src/stdfix/diviulk.h | 21 ++++++++
libc/src/stdfix/diviulr.cpp | 21 ++++++++
libc/src/stdfix/diviulr.h | 21 ++++++++
libc/src/stdfix/diviur.cpp | 21 ++++++++
libc/src/stdfix/diviur.h | 21 ++++++++
libc/test/src/stdfix/CMakeLists.txt | 2 +-
libc/test/src/stdfix/DiviFxTest.h | 33 ++++++++++--
libc/test/src/stdfix/divik_test.cpp | 14 ++++++
libc/test/src/stdfix/divilk_test.cpp | 14 ++++++
libc/test/src/stdfix/divilr_test.cpp | 14 ++++++
libc/test/src/stdfix/divir_test.cpp | 2 +-
libc/test/src/stdfix/diviuk_test.cpp | 14 ++++++
libc/test/src/stdfix/diviulk_test.cpp | 15 ++++++
libc/test/src/stdfix/diviulr_test.cpp | 15 ++++++
libc/test/src/stdfix/diviur_test.cpp | 14 ++++++
31 files changed, 511 insertions(+), 8 deletions(-)
create mode 100644 libc/src/stdfix/divik.cpp
create mode 100644 libc/src/stdfix/divik.h
create mode 100644 libc/src/stdfix/divilk.cpp
create mode 100644 libc/src/stdfix/divilk.h
create mode 100644 libc/src/stdfix/divilr.cpp
create mode 100644 libc/src/stdfix/divilr.h
create mode 100644 libc/src/stdfix/diviuk.cpp
create mode 100644 libc/src/stdfix/diviuk.h
create mode 100644 libc/src/stdfix/diviulk.cpp
create mode 100644 libc/src/stdfix/diviulk.h
create mode 100644 libc/src/stdfix/diviulr.cpp
create mode 100644 libc/src/stdfix/diviulr.h
create mode 100644 libc/src/stdfix/diviur.cpp
create mode 100644 libc/src/stdfix/diviur.h
create mode 100644 libc/test/src/stdfix/divik_test.cpp
create mode 100644 libc/test/src/stdfix/divilk_test.cpp
create mode 100644 libc/test/src/stdfix/divilr_test.cpp
create mode 100644 libc/test/src/stdfix/diviuk_test.cpp
create mode 100644 libc/test/src/stdfix/diviulk_test.cpp
create mode 100644 libc/test/src/stdfix/diviulr_test.cpp
create mode 100644 libc/test/src/stdfix/diviur_test.cpp
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 8c592f211a4e1..894c6dcd760c7 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -971,6 +971,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
libc.src.stdfix.divir
+ libc.src.stdfix.divilr
+ libc.src.stdfix.divik
+ libc.src.stdfix.divilk
+ libc.src.stdfix.diviur
+ libc.src.stdfix.diviulr
+ libc.src.stdfix.diviuk
+ libc.src.stdfix.diviulk
)
endif()
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 03b48cbd4e3f6..4194135f50a0c 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -968,6 +968,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
libc.src.stdfix.divir
+ libc.src.stdfix.divilr
+ libc.src.stdfix.divik
+ libc.src.stdfix.divilk
+ libc.src.stdfix.diviur
+ libc.src.stdfix.diviulr
+ libc.src.stdfix.diviuk
+ libc.src.stdfix.diviulk
)
endif()
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index a1d5836307ba8..33e588d9aa837 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -1103,6 +1103,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivulk
libc.src.stdfix.rdivi
libc.src.stdfix.divir
+ libc.src.stdfix.divilr
+ libc.src.stdfix.divik
+ libc.src.stdfix.divilk
+ libc.src.stdfix.diviur
+ libc.src.stdfix.diviulr
+ libc.src.stdfix.diviuk
+ libc.src.stdfix.diviulk
)
endif()
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 059a171662b75..96cbebdfa1609 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1174,6 +1174,13 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.idivulk
libc.src.stdfix.rdivi
libc.src.stdfix.divir
+ libc.src.stdfix.divilr
+ libc.src.stdfix.divik
+ libc.src.stdfix.divilk
+ libc.src.stdfix.diviur
+ libc.src.stdfix.diviulr
+ libc.src.stdfix.diviuk
+ libc.src.stdfix.diviulk
)
endif()
diff --git a/libc/docs/headers/stdfix.rst b/libc/docs/headers/stdfix.rst
index 84294a4e14792..efb836f964fa2 100644
--- a/libc/docs/headers/stdfix.rst
+++ b/libc/docs/headers/stdfix.rst
@@ -73,7 +73,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| countls | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
-| divi\* | | | | |check| | | | | | | | | |
+| divi\* | | | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| idiv\* | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
diff --git a/libc/include/stdfix.yaml b/libc/include/stdfix.yaml
index 4f3cfa39ce974..f91e4ea620e3e 100644
--- a/libc/include/stdfix.yaml
+++ b/libc/include/stdfix.yaml
@@ -573,3 +573,59 @@ functions:
- type: int
- type: fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: divilr
+ standards:
+ - stdc_ext
+ return_type: long int
+ arguments:
+ - type: long int
+ - type: long fract
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: divik
+ standards:
+ - stdc_ext
+ return_type: int
+ arguments:
+ - type: int
+ - type: accum
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: divilk
+ standards:
+ - stdc_ext
+ return_type: long int
+ arguments:
+ - type: long int
+ - type: long accum
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: diviur
+ standards:
+ - stdc_ext
+ return_type: unsigned int
+ arguments:
+ - type: unsigned int
+ - type: unsigned fract
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: diviulr
+ standards:
+ - stdc_ext
+ return_type: unsigned long int
+ arguments:
+ - type: unsigned long int
+ - type: unsigned long fract
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: diviuk
+ standards:
+ - stdc_ext
+ return_type: unsigned int
+ arguments:
+ - type: unsigned int
+ - type: unsigned accum
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
+ - name: diviulk
+ standards:
+ - stdc_ext
+ return_type: unsigned long int
+ arguments:
+ - type: unsigned long int
+ - type: unsigned long accum
+ guard: LIBC_COMPILER_HAS_FIXED_POINT
diff --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index f7b48b375cdba..b7121407e0307 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -102,7 +102,7 @@ foreach(suffix IN ITEMS r)
)
endforeach()
-foreach(suffix IN ITEMS r)
+foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
add_entrypoint_object(
divi${suffix}
HDRS
diff --git a/libc/src/stdfix/divik.cpp b/libc/src/stdfix/divik.cpp
new file mode 100644
index 0000000000000..549c091bca617
--- /dev/null
+++ b/libc/src/stdfix/divik.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of divik function ---------------------------------===//
+//
+// 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 "divik.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, divik, (int n, accum d)) {
+ return fixed_point::divifx<int, accum>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/divik.h b/libc/src/stdfix/divik.h
new file mode 100644
index 0000000000000..3ab530a018026
--- /dev/null
+++ b/libc/src/stdfix/divik.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for divik ------------------------*- 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_STDFIX_DIVIK_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int divik(int n, accum d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIK_H
diff --git a/libc/src/stdfix/divilk.cpp b/libc/src/stdfix/divilk.cpp
new file mode 100644
index 0000000000000..50a85c5f0ee29
--- /dev/null
+++ b/libc/src/stdfix/divilk.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of divilk function --------------------------------===//
+//
+// 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 "divilk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long int, divilk, (long int n, long accum d)) {
+ return fixed_point::divifx<long int, long accum>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/divilk.h b/libc/src/stdfix/divilk.h
new file mode 100644
index 0000000000000..e1ddf9b03ae67
--- /dev/null
+++ b/libc/src/stdfix/divilk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for divilk ------------------------*- 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_STDFIX_DIVILK_H
+#define LLVM_LIBC_SRC_STDFIX_DIVILK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long int divilk(long int, long accum);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVILK_H
diff --git a/libc/src/stdfix/divilr.cpp b/libc/src/stdfix/divilr.cpp
new file mode 100644
index 0000000000000..174649c4fad45
--- /dev/null
+++ b/libc/src/stdfix/divilr.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of divilr function --------------------------------===//
+//
+// 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 "divilr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long int, divilr, (long int n, long fract d)) {
+ return fixed_point::divifx<long int, long fract>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/divilr.h b/libc/src/stdfix/divilr.h
new file mode 100644
index 0000000000000..92a93ab484b33
--- /dev/null
+++ b/libc/src/stdfix/divilr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for divilr -----------------------*- 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_STDFIX_DIVILR_H
+#define LLVM_LIBC_SRC_STDFIX_DIVILR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long int divilr(long int, long fract);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVILR_H
diff --git a/libc/src/stdfix/diviuk.cpp b/libc/src/stdfix/diviuk.cpp
new file mode 100644
index 0000000000000..9b649cfd3b812
--- /dev/null
+++ b/libc/src/stdfix/diviuk.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of diviUK function --------------------------------===//
+//
+// 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 "diviuk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, diviuk, (unsigned int n, unsigned accum d)) {
+ return fixed_point::divifx<unsigned int, unsigned accum>(n, d);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/diviuk.h b/libc/src/stdfix/diviuk.h
new file mode 100644
index 0000000000000..5b3846614bf4a
--- /dev/null
+++ b/libc/src/stdfix/diviuk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for diviuk -----------------------*- 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_STDFIX_DIVIUK_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIUK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned int diviuk(unsigned int n, unsigned accum d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIUK_H
diff --git a/libc/src/stdfix/diviulk.cpp b/libc/src/stdfix/diviulk.cpp
new file mode 100644
index 0000000000000..79411a4b32834
--- /dev/null
+++ b/libc/src/stdfix/diviulk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of diviULK function -------------------------------===//
+//
+// 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 "diviulk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned long int, diviulk,
+ (unsigned long int n, unsigned long accum d)) {
+ return fixed_point::divifx<unsigned long int, unsigned long accum>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/diviulk.h b/libc/src/stdfix/diviulk.h
new file mode 100644
index 0000000000000..21ebef2394ff2
--- /dev/null
+++ b/libc/src/stdfix/diviulk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for diviulk ----------------------*- 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_STDFIX_DIVIULK_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIULK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long int diviulk(unsigned long int n, unsigned long accum d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIULK_H
diff --git a/libc/src/stdfix/diviulr.cpp b/libc/src/stdfix/diviulr.cpp
new file mode 100644
index 0000000000000..b738eb970882b
--- /dev/null
+++ b/libc/src/stdfix/diviulr.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of diviulr function -------------------------------===//
+//
+// 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 "diviulr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned long int, diviulr,
+ (unsigned long int n, unsigned long fract d)) {
+ return fixed_point::divifx<unsigned long int, unsigned long fract>(n, d);
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/diviulr.h b/libc/src/stdfix/diviulr.h
new file mode 100644
index 0000000000000..1bc78a81ab4b3
--- /dev/null
+++ b/libc/src/stdfix/diviulr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for diviulr ----------------------*- 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_STDFIX_DIVIULR_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIULR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long int diviulr(unsigned long int n, unsigned long fract d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIULR_H
diff --git a/libc/src/stdfix/diviur.cpp b/libc/src/stdfix/diviur.cpp
new file mode 100644
index 0000000000000..922c040ffacfd
--- /dev/null
+++ b/libc/src/stdfix/diviur.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of diviur function --------------------------------===//
+//
+// 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 "diviur.h"
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, diviur, (unsigned int n, unsigned fract d)) {
+ return fixed_point::divifx<unsigned int, unsigned fract>(n, d);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/diviur.h b/libc/src/stdfix/diviur.h
new file mode 100644
index 0000000000000..60e73a8e459f6
--- /dev/null
+++ b/libc/src/stdfix/diviur.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for diviur -----------------------*- 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_STDFIX_DIVIUR_H
+#define LLVM_LIBC_SRC_STDFIX_DIVIUR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned int diviur(unsigned int n, unsigned fract d);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_DIVIUR_H
diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 3bf3051c6b85a..75a98991be18d 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -147,7 +147,7 @@ foreach(suffix IN ITEMS r)
)
endforeach()
-foreach(suffix IN ITEMS r)
+foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
add_libc_test(
divi${suffix}_test
SUITE
diff --git a/libc/test/src/stdfix/DiviFxTest.h b/libc/test/src/stdfix/DiviFxTest.h
index c3e0b8ac038e9..7dd208927d7e8 100644
--- a/libc/test/src/stdfix/DiviFxTest.h
+++ b/libc/test/src/stdfix/DiviFxTest.h
@@ -19,7 +19,7 @@ class DiviFxTest : public LIBC_NAMESPACE::testing::Test {
using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<FXType>;
static constexpr FXType zero = FXRep::ZERO();
- static constexpr FXType min = FXRep::MIN();
+ static constexpr FXType max = FXRep::MAX();
static constexpr FXType one_half = FXRep::ONE_HALF();
static constexpr FXType one_fourth = FXRep::ONE_FOURTH();
@@ -28,6 +28,7 @@ class DiviFxTest : public LIBC_NAMESPACE::testing::Test {
void testBasicNumbers(DiviFxFunc func) {
constexpr bool is_signed = (FXRep::SIGN_LEN > 0);
+ constexpr bool has_integral = (FXRep::INTEGRAL_LEN > 0);
EXPECT_EQ(func(1, one_fourth), static_cast<IntType>(4));
EXPECT_EQ(func(1, one_half), static_cast<IntType>(2));
@@ -53,14 +54,38 @@ class DiviFxTest : public LIBC_NAMESPACE::testing::Test {
EXPECT_EQ(func(-2, 3 * one_fourth), static_cast<IntType>(-2));
EXPECT_EQ(func(2, -3 * one_fourth), static_cast<IntType>(-2));
} else {
- // min of unsigned type = 0
- EXPECT_EQ(func(min, one_half), static_cast<IntType>(0));
- EXPECT_EQ(func(min, one_fourth), static_cast<IntType>(0));
+ EXPECT_EQ(func(0, one_half), static_cast<IntType>(0));
+ EXPECT_EQ(func(0, one_fourth), static_cast<IntType>(0));
+ }
+
+ if constexpr (has_integral) {
+ // only run these tests for accum types that can represent the operands
+ // below
+ constexpr FXType largest_positive = static_cast<FXType>(4);
+
+ if constexpr (max >= largest_positive) {
+ EXPECT_EQ(func(3, 2.5), static_cast<IntType>(1));
+ EXPECT_EQ(func(2, 3.5), static_cast<IntType>(0));
+ EXPECT_EQ(func(3, 1.5), static_cast<IntType>(2));
+ EXPECT_EQ(func(4, 2.0), static_cast<IntType>(2));
+
+ if constexpr (is_signed) {
+ EXPECT_EQ(func(2, -3.5), static_cast<IntType>(0));
+ EXPECT_EQ(func(-3, 2.5), static_cast<IntType>(-1));
+ EXPECT_EQ(func(-3, 1.5), static_cast<IntType>(-2));
+ EXPECT_EQ(func(-3, -2.5), static_cast<IntType>(1));
+ }
+ }
}
}
void testInvalidNumbers(DiviFxFunc func) {
+ constexpr bool has_integral = (FXRep::INTEGRAL_LEN > 0);
+
EXPECT_DEATH([func] { func(1, zero); }, WITH_SIGNAL(-1));
+ if constexpr (has_integral) {
+ EXPECT_DEATH([func] { func(2, zero); }, WITH_SIGNAL(-1));
+ }
}
};
diff --git a/libc/test/src/stdfix/divik_test.cpp b/libc/test/src/stdfix/divik_test.cpp
new file mode 100644
index 0000000000000..1287d5d1a8d48
--- /dev/null
+++ b/libc/test/src/stdfix/divik_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for divik -----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/divik.h"
+
+LIST_DIVIFX_TESTS(k, int, accum, LIBC_NAMESPACE::divik);
diff --git a/libc/test/src/stdfix/divilk_test.cpp b/libc/test/src/stdfix/divilk_test.cpp
new file mode 100644
index 0000000000000..ebc6941139ca7
--- /dev/null
+++ b/libc/test/src/stdfix/divilk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for divilk ----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/divilk.h"
+
+LIST_DIVIFX_TESTS(lk, long int, long accum, LIBC_NAMESPACE::divilk);
diff --git a/libc/test/src/stdfix/divilr_test.cpp b/libc/test/src/stdfix/divilr_test.cpp
new file mode 100644
index 0000000000000..99567836f27b6
--- /dev/null
+++ b/libc/test/src/stdfix/divilr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for divilr ----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/divilr.h"
+
+LIST_DIVIFX_TESTS(lr, long int, long fract, LIBC_NAMESPACE::divilr);
diff --git a/libc/test/src/stdfix/divir_test.cpp b/libc/test/src/stdfix/divir_test.cpp
index 97f8dab63afba..e8b055561014b 100644
--- a/libc/test/src/stdfix/divir_test.cpp
+++ b/libc/test/src/stdfix/divir_test.cpp
@@ -8,7 +8,7 @@
#include "DiviFxTest.h"
-#include "llvm-libc-macros/stdfix-macros.h" // fract
+#include "llvm-libc-macros/stdfix-macros.h"
#include "src/stdfix/divir.h"
LIST_DIVIFX_TESTS(r, int, fract, LIBC_NAMESPACE::divir);
diff --git a/libc/test/src/stdfix/diviuk_test.cpp b/libc/test/src/stdfix/diviuk_test.cpp
new file mode 100644
index 0000000000000..a7d632a661502
--- /dev/null
+++ b/libc/test/src/stdfix/diviuk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for diviuk ----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/diviuk.h"
+
+LIST_DIVIFX_TESTS(uk, unsigned int, unsigned accum, LIBC_NAMESPACE::diviuk);
diff --git a/libc/test/src/stdfix/diviulk_test.cpp b/libc/test/src/stdfix/diviulk_test.cpp
new file mode 100644
index 0000000000000..4709e5728fe32
--- /dev/null
+++ b/libc/test/src/stdfix/diviulk_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for diviulk ---------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/diviulk.h"
+
+LIST_DIVIFX_TESTS(ulk, unsigned long int, unsigned long accum,
+ LIBC_NAMESPACE::diviulk);
diff --git a/libc/test/src/stdfix/diviulr_test.cpp b/libc/test/src/stdfix/diviulr_test.cpp
new file mode 100644
index 0000000000000..48cc1f288c919
--- /dev/null
+++ b/libc/test/src/stdfix/diviulr_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for diviulr ---------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/diviulr.h"
+
+LIST_DIVIFX_TESTS(ulr, unsigned long int, unsigned long fract,
+ LIBC_NAMESPACE::diviulr);
diff --git a/libc/test/src/stdfix/diviur_test.cpp b/libc/test/src/stdfix/diviur_test.cpp
new file mode 100644
index 0000000000000..6fd1c17d3cd10
--- /dev/null
+++ b/libc/test/src/stdfix/diviur_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for diviur ----------------------------------------------===//
+//
+// 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 "DiviFxTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h"
+#include "src/stdfix/diviur.h"
+
+LIST_DIVIFX_TESTS(ur, unsigned int, unsigned fract, LIBC_NAMESPACE::diviur);
>From ff62827a99520b42eaf0af582118e25a4d168c68 Mon Sep 17 00:00:00 2001
From: sohail <sohailraj.satapathy at gmail.com>
Date: Sat, 27 Jun 2026 20:25:22 +0530
Subject: [PATCH 3/3] fix formatting
Co-authored-by: Zorojuro <sawantsukumar at gmail.com>
---
libc/src/stdfix/diviuk.cpp | 1 +
libc/src/stdfix/diviulr.cpp | 1 +
2 files changed, 2 insertions(+)
diff --git a/libc/src/stdfix/diviuk.cpp b/libc/src/stdfix/diviuk.cpp
index 9b649cfd3b812..b77de93f9c3d8 100644
--- a/libc/src/stdfix/diviuk.cpp
+++ b/libc/src/stdfix/diviuk.cpp
@@ -17,4 +17,5 @@ namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(unsigned int, diviuk, (unsigned int n, unsigned accum d)) {
return fixed_point::divifx<unsigned int, unsigned accum>(n, d);
}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/diviulr.cpp b/libc/src/stdfix/diviulr.cpp
index b738eb970882b..a5e85a7b2d8f1 100644
--- a/libc/src/stdfix/diviulr.cpp
+++ b/libc/src/stdfix/diviulr.cpp
@@ -18,4 +18,5 @@ LLVM_LIBC_FUNCTION(unsigned long int, diviulr,
(unsigned long int n, unsigned long fract d)) {
return fixed_point::divifx<unsigned long int, unsigned long fract>(n, d);
}
+
} // namespace LIBC_NAMESPACE_DECL
More information about the libc-commits
mailing list