[libc-commits] [libc] [libc][stdfix] Implement `idivfx` functions in LLVM libc (PR #133005)

Krishna Pandey via libc-commits libc-commits at lists.llvm.org
Fri Mar 28 12:18:25 PDT 2025


https://github.com/krishna2803 updated https://github.com/llvm/llvm-project/pull/133005

>From b97496808214639ad6b54cafbdf1c4f8e1f4634b Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Tue, 25 Mar 2025 20:49:39 +0530
Subject: [PATCH 01/27] feat: implement generic idivfx

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>
---
 libc/src/__support/fixed_point/fx_bits.h | 28 ++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index b05f46bd34660..44f2225b91862 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -201,6 +201,34 @@ bitsfx(T f) {
   return cpp::bit_cast<XType, T>(f);
 }
 
+// divide the two fixed-point types and return an integer result
+template <typename T, typename XType>
+LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
+idivfx(T x, T y) {
+  using FXBits = FXBits<T>;
+  using FXRep = FXRep<T>;
+  using StorageType = typename FXRep::StorageType;
+
+  if (y == FXRep::ZERO()) {
+    // TODO: handle this case
+  }
+
+  constexpr FXBits x_bits(x);
+  constexpr FXBits y_bits(y);
+
+  bool out_s = x_bits.get_sign() ^ y_bits.get_sign();
+
+  x_bits.set_sign(0);
+  y_bits.set_sign(0);
+
+  XType x_int = x_bits.get_bits();
+  XType y_int = y_bits.get_bits();
+
+  // TODO: handle overflow
+  XType result = x_int / y_int;
+  return result;
+}
+
 } // namespace fixed_point
 } // namespace LIBC_NAMESPACE_DECL
 

>From f9b0de4d66c3c2c687a9a6474e837c7171749993 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Tue, 25 Mar 2025 20:50:17 +0530
Subject: [PATCH 02/27] feat: implement idivr

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>
---
 libc/src/stdfix/idivr.cpp | 21 +++++++++++++++++++++
 libc/src/stdfix/idivr.h   | 21 +++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 libc/src/stdfix/idivr.cpp
 create mode 100644 libc/src/stdfix/idivr.h

diff --git a/libc/src/stdfix/idivr.cpp b/libc/src/stdfix/idivr.cpp
new file mode 100644
index 0000000000000..079945dce8643
--- /dev/null
+++ b/libc/src/stdfix/idivr.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivr 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 "idivr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // fract
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, idivr, (fract x, fract y)) {
+  return fixed_point::idivfx<fract, int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivr.h b/libc/src/stdfix/idivr.h
new file mode 100644
index 0000000000000..f3a95e2d516c3
--- /dev/null
+++ b/libc/src/stdfix/idivr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivr ------------------------*- 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_IDIVR_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // fract
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int idivr(fract x, fract y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVR_H

>From ec355dfc4fef0feb817bde0496396434bfd6373a Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Tue, 25 Mar 2025 20:50:36 +0530
Subject: [PATCH 03/27] chore: update CMakeLists.txt

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>
---
 libc/src/stdfix/CMakeLists.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index 362af0bf0d55c..843111e3f80b1 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -75,6 +75,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
   )
 endforeach()
 
+foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
+  add_entrypoint_object(
+    idiv${suffix}
+    HDRS
+      idiv${suffix}.h
+    SRCS
+      idiv${suffix}.cpp
+    COMPILE_OPTIONS
+      ${libc_opt_high_flag}
+    DEPENDS
+      libc.src.__support.fixed_point.fx_bits
+  )
+endforeach()
+
 add_entrypoint_object(
   uhksqrtus
   HDRS

>From fc30ed0d9afea2b39fb74eab9ae32405a14f5b27 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Tue, 25 Mar 2025 20:50:49 +0530
Subject: [PATCH 04/27] chore: update entrypoints

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>
---
 libc/config/baremetal/arm/entrypoints.txt   | 1 +
 libc/config/baremetal/riscv/entrypoints.txt | 1 +
 libc/config/linux/x86_64/entrypoints.txt    | 1 +
 3 files changed, 3 insertions(+)

diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 511d9d22f1450..1a8952d8f68d2 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -537,6 +537,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuhk
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
+    libc.src.stdfix.idivr
   )
 endif()
 
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index bbefb75ee16b5..e0306f23d9f68 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -532,6 +532,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuhk
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
+    libc.src.stdfix.idivr
   )
 endif()
 
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 124b80d03d846..8a9cf7580aa31 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -905,6 +905,7 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuhk
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
+    libc.src.stdfix.idivr
   )
 endif()
 

>From 6a3c052315bc17207f3299756a7a840f2f760c18 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Tue, 25 Mar 2025 20:52:46 +0530
Subject: [PATCH 05/27] chore: implement sanity check tests for idivr

---
 libc/test/src/stdfix/CMakeLists.txt | 15 ++++++++++++
 libc/test/src/stdfix/IdivTest.h     | 38 +++++++++++++++++++++++++++++
 libc/test/src/stdfix/idivr_test.cpp | 14 +++++++++++
 3 files changed, 67 insertions(+)
 create mode 100644 libc/test/src/stdfix/IdivTest.h
 create mode 100644 libc/test/src/stdfix/idivr_test.cpp

diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index a3dc25762f549..e881b82c2a742 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -104,6 +104,21 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
   )
 endforeach()
 
+foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
+  add_libc_test(
+    idiv${suffix}_test
+    SUITE
+      libc-stdfix-tests
+    HDRS
+      IdivTest.h
+    SRCS
+      idiv${suffix}_test.cpp
+    DEPENDS
+      libc.src.stdfix.idiv${suffix}
+      libc.src.__support.fixed_point.fx_bits
+  )
+endforeach()
+
 add_libc_test(
   uhksqrtus_test
   SUITE
diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
new file mode 100644
index 0000000000000..9d9a54c5dc90c
--- /dev/null
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -0,0 +1,38 @@
+//===-- Utility class to test idivfx 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 "src/__support/fixed_point/fx_rep.h"
+
+template <typename T, typename XType>
+class IDivTest : public LIBC_NAMESPACE::testing::Test {
+
+  using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
+  // static constexpr T zero = FXRep::ZERO();
+  // static constexpr T max = FXRep::MAX();
+  // static constexpr T min = FXRep::MIN();
+  // static constexpr T one_half = FXRep::ONE_HALF();
+  // static constexpr T one_fourth = FXRep::ONE_FOURTH();
+  // static constexpr T eps = FXRep::EPS();
+
+public:
+  typedef XType (*IdivFunc)(T, T);
+
+  void testSpecialNumbers(IdivFunc func) {
+    EXPECT_EQ(1, 1);
+    EXPECT_EQ(1 + 1, 2);
+  }
+};
+
+#define LIST_IDIV_TESTS(Name, T, XType, func)                                  \
+  using LlvmLibcIdiv##Name##Test = IdivTest<T, XType>;                         \
+  TEST_F(LlvmLibcIdiv##Name##Test, SpecialNumbers) {                           \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  static_assert(true, "Require semicolon.")
diff --git a/libc/test/src/stdfix/idivr_test.cpp b/libc/test/src/stdfix/idivr_test.cpp
new file mode 100644
index 0000000000000..87aea37389315
--- /dev/null
+++ b/libc/test/src/stdfix/idivr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivr -----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // fract
+#include "src/stdfix/idivr.h"
+
+LIST_IDIV_TESTS(r, fract, int, LIBC_NAMESPACE::bitsr);

>From 6bcec0123f174c204db51eb9479f31eee1494888 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:10:21 +0530
Subject: [PATCH 06/27] fix: SIGFPE

---
 libc/src/__support/fixed_point/fx_bits.h | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 44f2225b91862..46603286788ed 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -207,26 +207,22 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
 idivfx(T x, T y) {
   using FXBits = FXBits<T>;
   using FXRep = FXRep<T>;
-  using StorageType = typename FXRep::StorageType;
+  using BitType = typename FXRep::StorageType;
+
+  // TODO: add negative check
 
   if (y == FXRep::ZERO()) {
-    // TODO: handle this case
+    // TODO: handle divide by zero
   }
 
-  constexpr FXBits x_bits(x);
-  constexpr FXBits y_bits(y);
-
-  bool out_s = x_bits.get_sign() ^ y_bits.get_sign();
+  FXBits x_bits(x);
+  FXBits y_bits(y);
 
-  x_bits.set_sign(0);
-  y_bits.set_sign(0);
+  BitType result = x_bits.get_bits() / y_bits.get_bits();
 
-  XType x_int = x_bits.get_bits();
-  XType y_int = y_bits.get_bits();
+  // TODO: handle integer overflow
 
-  // TODO: handle overflow
-  XType result = x_int / y_int;
-  return result;
+  return static_cast<XType>(result);
 }
 
 } // namespace fixed_point

>From 078e5582afdc9846ab99c74f59f770c2a8a019c1 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:10:33 +0530
Subject: [PATCH 07/27] fix: update test

---
 libc/test/src/stdfix/IdivTest.h     | 18 +++++++++---------
 libc/test/src/stdfix/idivr_test.cpp |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
index 9d9a54c5dc90c..98cecd403cbf1 100644
--- a/libc/test/src/stdfix/IdivTest.h
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -11,22 +11,22 @@
 #include "src/__support/fixed_point/fx_rep.h"
 
 template <typename T, typename XType>
-class IDivTest : public LIBC_NAMESPACE::testing::Test {
+class IdivTest : public LIBC_NAMESPACE::testing::Test {
 
   using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>;
-  // static constexpr T zero = FXRep::ZERO();
-  // static constexpr T max = FXRep::MAX();
-  // static constexpr T min = FXRep::MIN();
-  // static constexpr T one_half = FXRep::ONE_HALF();
-  // static constexpr T one_fourth = FXRep::ONE_FOURTH();
-  // static constexpr T eps = FXRep::EPS();
+
+  static constexpr T zero = FXRep::ZERO();
+  static constexpr T max = FXRep::MAX();
+  static constexpr T min = FXRep::MIN();
+  static constexpr T one_half = FXRep::ONE_HALF();
+  static constexpr T one_fourth = FXRep::ONE_FOURTH();
+  static constexpr T eps = FXRep::EPS();
 
 public:
   typedef XType (*IdivFunc)(T, T);
 
   void testSpecialNumbers(IdivFunc func) {
-    EXPECT_EQ(1, 1);
-    EXPECT_EQ(1 + 1, 2);
+    EXPECT_EQ(func(one_half, one_fourth), 2);
   }
 };
 
diff --git a/libc/test/src/stdfix/idivr_test.cpp b/libc/test/src/stdfix/idivr_test.cpp
index 87aea37389315..82bec5c7be069 100644
--- a/libc/test/src/stdfix/idivr_test.cpp
+++ b/libc/test/src/stdfix/idivr_test.cpp
@@ -11,4 +11,4 @@
 #include "llvm-libc-macros/stdfix-macros.h" // fract
 #include "src/stdfix/idivr.h"
 
-LIST_IDIV_TESTS(r, fract, int, LIBC_NAMESPACE::bitsr);
+LIST_IDIV_TESTS(r, fract, int, LIBC_NAMESPACE::idivr);

>From 7b545721383512164899b321e295af3bc84f3263 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:23:34 +0530
Subject: [PATCH 08/27] feat: implement idivlr

---
 libc/src/stdfix/idivlr.cpp | 21 +++++++++++++++++++++
 libc/src/stdfix/idivlr.h   | 21 +++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 libc/src/stdfix/idivlr.cpp
 create mode 100644 libc/src/stdfix/idivlr.h

diff --git a/libc/src/stdfix/idivlr.cpp b/libc/src/stdfix/idivlr.cpp
new file mode 100644
index 0000000000000..fffb31615102f
--- /dev/null
+++ b/libc/src/stdfix/idivlr.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivlr 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 "idivlr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(long int, idivr, (long fract x, long fract y)) {
+  return fixed_point::idivfx<long fract, long int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivlr.h b/libc/src/stdfix/idivlr.h
new file mode 100644
index 0000000000000..de36035f289a4
--- /dev/null
+++ b/libc/src/stdfix/idivlr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivlr -----------------------*- 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_IDIVLR_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVLR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+long int idivlr(long fract x, long fract y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVLR_H

>From 65eb2ea6b494d10e136f03900c85b08fedc4c907 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:23:51 +0530
Subject: [PATCH 09/27] feat: implement idivk

---
 libc/src/stdfix/idivk.cpp | 21 +++++++++++++++++++++
 libc/src/stdfix/idivk.h   | 21 +++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 libc/src/stdfix/idivk.cpp
 create mode 100644 libc/src/stdfix/idivk.h

diff --git a/libc/src/stdfix/idivk.cpp b/libc/src/stdfix/idivk.cpp
new file mode 100644
index 0000000000000..dcdf96b80430e
--- /dev/null
+++ b/libc/src/stdfix/idivk.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivk 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 "idivk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // accum
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, idivk, (accum x, accum y)) {
+  return fixed_point::idivfx<accum, int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivk.h b/libc/src/stdfix/idivk.h
new file mode 100644
index 0000000000000..a84bd0da2d533
--- /dev/null
+++ b/libc/src/stdfix/idivk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivk ------------------------*- 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_IDIVK_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // accum
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+int idivk(accum x, accum y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVK_H

>From 693ce400c22397015918816dcdf29480db8e5222 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:24:00 +0530
Subject: [PATCH 10/27] feat: implement idivlk

---
 libc/src/stdfix/idivlk.cpp | 21 +++++++++++++++++++++
 libc/src/stdfix/idivlk.h   | 21 +++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 libc/src/stdfix/idivlk.cpp
 create mode 100644 libc/src/stdfix/idivlk.h

diff --git a/libc/src/stdfix/idivlk.cpp b/libc/src/stdfix/idivlk.cpp
new file mode 100644
index 0000000000000..960b89c935a47
--- /dev/null
+++ b/libc/src/stdfix/idivlk.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivlk 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 "idivlk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, idivlk, (long accum x, long accum y)) {
+  return fixed_point::idivfx<long accum, int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivlk.h b/libc/src/stdfix/idivlk.h
new file mode 100644
index 0000000000000..274a61a9d82c3
--- /dev/null
+++ b/libc/src/stdfix/idivlk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivlk -----------------------*- 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_IDIVLK_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVLK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+long int idivlk(long accum x, long accum y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVLK_H

>From e59067d5a984b16a0ce1c591e4558cc0e3843837 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:24:19 +0530
Subject: [PATCH 11/27] chore: update entrypoints

---
 libc/config/baremetal/arm/entrypoints.txt   | 3 +++
 libc/config/baremetal/riscv/entrypoints.txt | 3 +++
 libc/config/linux/riscv/entrypoints.txt     | 4 ++++
 libc/config/linux/x86_64/entrypoints.txt    | 3 +++
 4 files changed, 13 insertions(+)

diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 1a8952d8f68d2..b5b99ead32afe 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -538,6 +538,9 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
     libc.src.stdfix.idivr
+    libc.src.stdfix.idivlr
+    libc.src.stdfix.idivk
+    libc.src.stdfix.idivlk
   )
 endif()
 
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index e0306f23d9f68..1c9c2c30eb97a 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -533,6 +533,9 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
     libc.src.stdfix.idivr
+    libc.src.stdfix.idivlr
+    libc.src.stdfix.idivk
+    libc.src.stdfix.idivlk
   )
 endif()
 
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 9cf05ef6d5a61..398d640107422 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -773,6 +773,10 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuhk
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
+    libc.src.stdfix.idivr
+    libc.src.stdfix.idivlr
+    libc.src.stdfix.idivk
+    libc.src.stdfix.idivlk
   )
 endif()
 
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 8a9cf7580aa31..c0d4b47430226 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -906,6 +906,9 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.countlsuk
     libc.src.stdfix.countlsulk
     libc.src.stdfix.idivr
+    libc.src.stdfix.idivlr
+    libc.src.stdfix.idivk
+    libc.src.stdfix.idivlk
   )
 endif()
 

>From 05ba8d361ec542d51784386275e8e6f83eae5a2b Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:24:33 +0530
Subject: [PATCH 12/27] chore: add more tests

---
 libc/test/src/stdfix/idivk_test.cpp  | 14 ++++++++++++++
 libc/test/src/stdfix/idivlk_test.cpp | 14 ++++++++++++++
 libc/test/src/stdfix/idivlr_test.cpp | 14 ++++++++++++++
 3 files changed, 42 insertions(+)
 create mode 100644 libc/test/src/stdfix/idivk_test.cpp
 create mode 100644 libc/test/src/stdfix/idivlk_test.cpp
 create mode 100644 libc/test/src/stdfix/idivlr_test.cpp

diff --git a/libc/test/src/stdfix/idivk_test.cpp b/libc/test/src/stdfix/idivk_test.cpp
new file mode 100644
index 0000000000000..b10a43ed6135a
--- /dev/null
+++ b/libc/test/src/stdfix/idivk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivk -----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // accum
+#include "src/stdfix/idivk.h"
+
+LIST_IDIV_TESTS(k, accum, int, LIBC_NAMESPACE::idivk);
diff --git a/libc/test/src/stdfix/idivlk_test.cpp b/libc/test/src/stdfix/idivlk_test.cpp
new file mode 100644
index 0000000000000..dcd4ccbcc4a78
--- /dev/null
+++ b/libc/test/src/stdfix/idivlk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivlk ----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // long accum
+#include "src/stdfix/idivlk.h"
+
+LIST_IDIV_TESTS(lk, long accum, long int, LIBC_NAMESPACE::idivlk);
diff --git a/libc/test/src/stdfix/idivlr_test.cpp b/libc/test/src/stdfix/idivlr_test.cpp
new file mode 100644
index 0000000000000..0fdb1e3a19e8f
--- /dev/null
+++ b/libc/test/src/stdfix/idivlr_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivlr ----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // long fract
+#include "src/stdfix/idivlr.h"
+
+LIST_IDIV_TESTS(lr, long fract, long int, LIBC_NAMESPACE::idivlr);

>From c245ea5396e3039ce9b296d2856f6142e83aa821 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:34:00 +0530
Subject: [PATCH 13/27] fix: idivlk typo

---
 libc/src/stdfix/idivlk.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libc/src/stdfix/idivlk.cpp b/libc/src/stdfix/idivlk.cpp
index 960b89c935a47..5e7052c3e8f2e 100644
--- a/libc/src/stdfix/idivlk.cpp
+++ b/libc/src/stdfix/idivlk.cpp
@@ -14,8 +14,8 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(int, idivlk, (long accum x, long accum y)) {
-  return fixed_point::idivfx<long accum, int>(x, y);
+LLVM_LIBC_FUNCTION(long int, idivlk, (long accum x, long accum y)) {
+  return fixed_point::idivfx<long accum, long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From 85ee5ed364acc3b3daf115e8ad0f8eba6420d8d1 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:34:09 +0530
Subject: [PATCH 14/27] fix: idivlr typo

---
 libc/src/stdfix/idivlr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/stdfix/idivlr.cpp b/libc/src/stdfix/idivlr.cpp
index fffb31615102f..701da719cdda6 100644
--- a/libc/src/stdfix/idivlr.cpp
+++ b/libc/src/stdfix/idivlr.cpp
@@ -14,7 +14,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(long int, idivr, (long fract x, long fract y)) {
+LLVM_LIBC_FUNCTION(long int, idivlr, (long fract x, long fract y)) {
   return fixed_point::idivfx<long fract, long int>(x, y);
 }
 

>From aebbcc7184e6adb6be04492bcd8116c08447d1f9 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:34:35 +0530
Subject: [PATCH 15/27] feat: implement idivu{r,lr,k,lk}

---
 libc/src/stdfix/idivuk.cpp  | 21 +++++++++++++++++++++
 libc/src/stdfix/idivuk.h    | 21 +++++++++++++++++++++
 libc/src/stdfix/idivulk.cpp | 22 ++++++++++++++++++++++
 libc/src/stdfix/idivulk.h   | 21 +++++++++++++++++++++
 libc/src/stdfix/idivulr.cpp | 22 ++++++++++++++++++++++
 libc/src/stdfix/idivulr.h   | 21 +++++++++++++++++++++
 6 files changed, 128 insertions(+)
 create mode 100644 libc/src/stdfix/idivuk.cpp
 create mode 100644 libc/src/stdfix/idivuk.h
 create mode 100644 libc/src/stdfix/idivulk.cpp
 create mode 100644 libc/src/stdfix/idivulk.h
 create mode 100644 libc/src/stdfix/idivulr.cpp
 create mode 100644 libc/src/stdfix/idivulr.h

diff --git a/libc/src/stdfix/idivuk.cpp b/libc/src/stdfix/idivuk.cpp
new file mode 100644
index 0000000000000..c1230c21794ed
--- /dev/null
+++ b/libc/src/stdfix/idivuk.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivuk 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 "idivuk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, idivuk, (unsigned accum x, unsigned accum y)) {
+  return fixed_point::idivfx<unsigned accum, unsigned int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivuk.h b/libc/src/stdfix/idivuk.h
new file mode 100644
index 0000000000000..a8dce0a0b4c8b
--- /dev/null
+++ b/libc/src/stdfix/idivuk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivuk ------------------------*- 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_IDIVUK_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVUK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned int idivuk(unsigned accum x, unsigned accum y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVUK_H
diff --git a/libc/src/stdfix/idivulk.cpp b/libc/src/stdfix/idivulk.cpp
new file mode 100644
index 0000000000000..f7dbba28b4e77
--- /dev/null
+++ b/libc/src/stdfix/idivulk.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of idivulk 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 "idivulk.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long accum
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, idivulk,
+                   (unsigned long accum x, unsigned long accum y)) {
+  return fixed_point::idivfx<unsigned long accum, unsigned int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivulk.h b/libc/src/stdfix/idivulk.h
new file mode 100644
index 0000000000000..ac2f6ea120e66
--- /dev/null
+++ b/libc/src/stdfix/idivulk.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivlk -----------------------*- 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_IDIVULK_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVULK_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long accum
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long int idivlk(unsigned long accum x, unsigned long accum y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVULK_H
diff --git a/libc/src/stdfix/idivulr.cpp b/libc/src/stdfix/idivulr.cpp
new file mode 100644
index 0000000000000..3a33da1b3b8c3
--- /dev/null
+++ b/libc/src/stdfix/idivulr.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of idivulr 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 "idivulr.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long fract
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned long int, idivulr,
+                   (unsigned long fract x, unsigned long fract y)) {
+  return fixed_point::idivfx<unsigned long fract, unsigned long int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivulr.h b/libc/src/stdfix/idivulr.h
new file mode 100644
index 0000000000000..c2f6a1911bd37
--- /dev/null
+++ b/libc/src/stdfix/idivulr.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivulr ----------------------*- 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_IDIVULR_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVULR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned long fract
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned long int idivulr(unsigned long fract x, unsigned long fract y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVULR_H

>From 276793bf3072bcf92d00c5aa3a9bf3cfa9a19b24 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 01:40:10 +0530
Subject: [PATCH 16/27] chore: update entrypoints

---
 libc/config/baremetal/arm/entrypoints.txt   | 4 ++++
 libc/config/baremetal/riscv/entrypoints.txt | 4 ++++
 libc/config/linux/riscv/entrypoints.txt     | 6 +++++-
 libc/config/linux/x86_64/entrypoints.txt    | 4 ++++
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index b5b99ead32afe..e9a2c7fc77bbe 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -541,6 +541,10 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.idivlr
     libc.src.stdfix.idivk
     libc.src.stdfix.idivlk
+    libc.src.stdfix.idivur
+    libc.src.stdfix.idivulr
+    libc.src.stdfix.idivuk
+    libc.src.stdfix.idivulk
   )
 endif()
 
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 1c9c2c30eb97a..9a3db5ffad000 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -536,6 +536,10 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.idivlr
     libc.src.stdfix.idivk
     libc.src.stdfix.idivlk
+    libc.src.stdfix.idivur
+    libc.src.stdfix.idivulr
+    libc.src.stdfix.idivuk
+    libc.src.stdfix.idivulk
   )
 endif()
 
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 398d640107422..b2aa3300d0f67 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -776,7 +776,11 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.idivr
     libc.src.stdfix.idivlr
     libc.src.stdfix.idivk
-    libc.src.stdfix.idivlk
+    libc.src.stdfix.idivulk
+    libc.src.stdfix.idivur
+    libc.src.stdfix.idivulr
+    libc.src.stdfix.idivuk
+    libc.src.stdfix.idivulk
   )
 endif()
 
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index c0d4b47430226..a387f62fe009e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -909,6 +909,10 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.idivlr
     libc.src.stdfix.idivk
     libc.src.stdfix.idivlk
+    libc.src.stdfix.idivur
+    libc.src.stdfix.idivulr
+    libc.src.stdfix.idivuk
+    libc.src.stdfix.idivulk
   )
 endif()
 

>From 3e3c403a5e93b4de85bc6136c24109dcf2997005 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 02:04:57 +0530
Subject: [PATCH 17/27] fix: idivulk typo

---
 libc/src/stdfix/idivulk.cpp | 4 ++--
 libc/src/stdfix/idivulk.h   | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/stdfix/idivulk.cpp b/libc/src/stdfix/idivulk.cpp
index f7dbba28b4e77..e298a354172e0 100644
--- a/libc/src/stdfix/idivulk.cpp
+++ b/libc/src/stdfix/idivulk.cpp
@@ -14,9 +14,9 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-LLVM_LIBC_FUNCTION(unsigned int, idivulk,
+LLVM_LIBC_FUNCTION(unsigned long int, idivulk,
                    (unsigned long accum x, unsigned long accum y)) {
-  return fixed_point::idivfx<unsigned long accum, unsigned int>(x, y);
+  return fixed_point::idivfx<unsigned long accum, unsigned long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivulk.h b/libc/src/stdfix/idivulk.h
index ac2f6ea120e66..b463e76b98f5e 100644
--- a/libc/src/stdfix/idivulk.h
+++ b/libc/src/stdfix/idivulk.h
@@ -14,7 +14,7 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-unsigned long int idivlk(unsigned long accum x, unsigned long accum y);
+unsigned long int idivulk(unsigned long accum x, unsigned long accum y);
 
 } // namespace LIBC_NAMESPACE_DECL
 

>From b1145cf8f02cd27bfe6f2a998da49919c24a55d5 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 02:05:56 +0530
Subject: [PATCH 18/27] fix: add cast to tests

---
 libc/test/src/stdfix/IdivTest.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
index 98cecd403cbf1..e7411278da7bc 100644
--- a/libc/test/src/stdfix/IdivTest.h
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -26,7 +26,7 @@ class IdivTest : public LIBC_NAMESPACE::testing::Test {
   typedef XType (*IdivFunc)(T, T);
 
   void testSpecialNumbers(IdivFunc func) {
-    EXPECT_EQ(func(one_half, one_fourth), 2);
+    EXPECT_EQ(func(one_half, one_fourth), static_cast<XType>(2));
   }
 };
 

>From d30de6950fb69cdaaa64cf5bb768a5644cedac1c Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 02:06:51 +0530
Subject: [PATCH 19/27] chore: add idiv{ur,uk,ulk,ulr} tests

---
 libc/src/stdfix/idivur.cpp            | 21 +++++++++++++++++++++
 libc/src/stdfix/idivur.h              | 21 +++++++++++++++++++++
 libc/test/src/stdfix/idivuk_test.cpp  | 14 ++++++++++++++
 libc/test/src/stdfix/idivulk_test.cpp | 15 +++++++++++++++
 libc/test/src/stdfix/idivulr_test.cpp | 15 +++++++++++++++
 libc/test/src/stdfix/idivur_test.cpp  | 14 ++++++++++++++
 6 files changed, 100 insertions(+)
 create mode 100644 libc/src/stdfix/idivur.cpp
 create mode 100644 libc/src/stdfix/idivur.h
 create mode 100644 libc/test/src/stdfix/idivuk_test.cpp
 create mode 100644 libc/test/src/stdfix/idivulk_test.cpp
 create mode 100644 libc/test/src/stdfix/idivulr_test.cpp
 create mode 100644 libc/test/src/stdfix/idivur_test.cpp

diff --git a/libc/src/stdfix/idivur.cpp b/libc/src/stdfix/idivur.cpp
new file mode 100644
index 0000000000000..5a01f3850c915
--- /dev/null
+++ b/libc/src/stdfix/idivur.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of idivur 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 "idivur.h"
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract
+#include "src/__support/common.h"                   // LLVM_LIBC_FUNCTION
+#include "src/__support/fixed_point/fx_bits.h"      // fixed_point
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(unsigned int, idivur, (unsigned fract x, unsigned fract y)) {
+  return fixed_point::idivfx<unsigned fract, unsigned int>(x, y);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivur.h b/libc/src/stdfix/idivur.h
new file mode 100644
index 0000000000000..f69db20bcf512
--- /dev/null
+++ b/libc/src/stdfix/idivur.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for idivur -----------------------*- 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_IDIVUR_H
+#define LLVM_LIBC_SRC_STDFIX_IDIVUR_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h" // unsigned fract
+#include "src/__support/macros/config.h"            // LIBC_NAMESPACE_DECL
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned int idivur(unsigned fract x, unsigned fract y);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_IDIVUR_H
diff --git a/libc/test/src/stdfix/idivuk_test.cpp b/libc/test/src/stdfix/idivuk_test.cpp
new file mode 100644
index 0000000000000..2bfd93da3ed4a
--- /dev/null
+++ b/libc/test/src/stdfix/idivuk_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivuk ----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // unsigned accum
+#include "src/stdfix/idivuk.h"
+
+LIST_IDIV_TESTS(uk, unsigned accum, unsigned int, LIBC_NAMESPACE::idivuk);
diff --git a/libc/test/src/stdfix/idivulk_test.cpp b/libc/test/src/stdfix/idivulk_test.cpp
new file mode 100644
index 0000000000000..31eb96114a0ce
--- /dev/null
+++ b/libc/test/src/stdfix/idivulk_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for idivulk ---------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // unsigned long accum
+#include "src/stdfix/idivulk.h"
+
+LIST_IDIV_TESTS(ulk, unsigned long accum, unsigned long int,
+                LIBC_NAMESPACE::idivulk);
diff --git a/libc/test/src/stdfix/idivulr_test.cpp b/libc/test/src/stdfix/idivulr_test.cpp
new file mode 100644
index 0000000000000..6f43df149a127
--- /dev/null
+++ b/libc/test/src/stdfix/idivulr_test.cpp
@@ -0,0 +1,15 @@
+//===-- Unittests for idivulr ---------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // unsigned long fract
+#include "src/stdfix/idivulr.h"
+
+LIST_IDIV_TESTS(ulr, unsigned long fract, unsigned long int,
+                LIBC_NAMESPACE::idivulr);
diff --git a/libc/test/src/stdfix/idivur_test.cpp b/libc/test/src/stdfix/idivur_test.cpp
new file mode 100644
index 0000000000000..c2d2f9caf19d9
--- /dev/null
+++ b/libc/test/src/stdfix/idivur_test.cpp
@@ -0,0 +1,14 @@
+//===-- Unittests for idivur ----------------------------------------------===//
+//
+// 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 "IdivTest.h"
+
+#include "llvm-libc-macros/stdfix-macros.h" // unsigned fract
+#include "src/stdfix/idivur.h"
+
+LIST_IDIV_TESTS(ur, unsigned fract, unsigned int, LIBC_NAMESPACE::idivur);

>From cce18216fbad12e269e16fde59ad27c72d4c4ae1 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 02:33:43 +0530
Subject: [PATCH 20/27] refactor: rename fixed_point::idivfx to
 fixed_point::idiv

---
 libc/src/__support/fixed_point/fx_bits.h | 2 +-
 libc/src/stdfix/idivk.cpp                | 2 +-
 libc/src/stdfix/idivlk.cpp               | 2 +-
 libc/src/stdfix/idivlr.cpp               | 2 +-
 libc/src/stdfix/idivr.cpp                | 2 +-
 libc/src/stdfix/idivuk.cpp               | 2 +-
 libc/src/stdfix/idivulk.cpp              | 2 +-
 libc/src/stdfix/idivulr.cpp              | 2 +-
 libc/src/stdfix/idivur.cpp               | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 46603286788ed..be6d761937ac6 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -204,7 +204,7 @@ bitsfx(T f) {
 // divide the two fixed-point types and return an integer result
 template <typename T, typename XType>
 LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
-idivfx(T x, T y) {
+idiv(T x, T y) {
   using FXBits = FXBits<T>;
   using FXRep = FXRep<T>;
   using BitType = typename FXRep::StorageType;
diff --git a/libc/src/stdfix/idivk.cpp b/libc/src/stdfix/idivk.cpp
index dcdf96b80430e..d1d758dc56995 100644
--- a/libc/src/stdfix/idivk.cpp
+++ b/libc/src/stdfix/idivk.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, idivk, (accum x, accum y)) {
-  return fixed_point::idivfx<accum, int>(x, y);
+  return fixed_point::idiv<accum, int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivlk.cpp b/libc/src/stdfix/idivlk.cpp
index 5e7052c3e8f2e..36e1df6cc58fb 100644
--- a/libc/src/stdfix/idivlk.cpp
+++ b/libc/src/stdfix/idivlk.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(long int, idivlk, (long accum x, long accum y)) {
-  return fixed_point::idivfx<long accum, long int>(x, y);
+  return fixed_point::idiv<long accum, long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivlr.cpp b/libc/src/stdfix/idivlr.cpp
index 701da719cdda6..1c9d62d196a29 100644
--- a/libc/src/stdfix/idivlr.cpp
+++ b/libc/src/stdfix/idivlr.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(long int, idivlr, (long fract x, long fract y)) {
-  return fixed_point::idivfx<long fract, long int>(x, y);
+  return fixed_point::idiv<long fract, long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivr.cpp b/libc/src/stdfix/idivr.cpp
index 079945dce8643..80dd1b2107272 100644
--- a/libc/src/stdfix/idivr.cpp
+++ b/libc/src/stdfix/idivr.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, idivr, (fract x, fract y)) {
-  return fixed_point::idivfx<fract, int>(x, y);
+  return fixed_point::idiv<fract, int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivuk.cpp b/libc/src/stdfix/idivuk.cpp
index c1230c21794ed..27bf8edd80927 100644
--- a/libc/src/stdfix/idivuk.cpp
+++ b/libc/src/stdfix/idivuk.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(unsigned int, idivuk, (unsigned accum x, unsigned accum y)) {
-  return fixed_point::idivfx<unsigned accum, unsigned int>(x, y);
+  return fixed_point::idiv<unsigned accum, unsigned int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivulk.cpp b/libc/src/stdfix/idivulk.cpp
index e298a354172e0..8b4e63c1b78fb 100644
--- a/libc/src/stdfix/idivulk.cpp
+++ b/libc/src/stdfix/idivulk.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(unsigned long int, idivulk,
                    (unsigned long accum x, unsigned long accum y)) {
-  return fixed_point::idivfx<unsigned long accum, unsigned long int>(x, y);
+  return fixed_point::idiv<unsigned long accum, unsigned long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivulr.cpp b/libc/src/stdfix/idivulr.cpp
index 3a33da1b3b8c3..6e6a780c1b8c5 100644
--- a/libc/src/stdfix/idivulr.cpp
+++ b/libc/src/stdfix/idivulr.cpp
@@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(unsigned long int, idivulr,
                    (unsigned long fract x, unsigned long fract y)) {
-  return fixed_point::idivfx<unsigned long fract, unsigned long int>(x, y);
+  return fixed_point::idiv<unsigned long fract, unsigned long int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/idivur.cpp b/libc/src/stdfix/idivur.cpp
index 5a01f3850c915..319817b9662d3 100644
--- a/libc/src/stdfix/idivur.cpp
+++ b/libc/src/stdfix/idivur.cpp
@@ -15,7 +15,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(unsigned int, idivur, (unsigned fract x, unsigned fract y)) {
-  return fixed_point::idivfx<unsigned fract, unsigned int>(x, y);
+  return fixed_point::idiv<unsigned fract, unsigned int>(x, y);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From dc7713c0272731d74c928450dce5e1f32b9ce592 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 02:34:10 +0530
Subject: [PATCH 21/27] chore: add type generic macros

---
 libc/include/llvm-libc-macros/stdfix-macros.h | 11 +++++++
 libc/test/src/stdfix/CMakeLists.txt           | 13 +++++++--
 libc/test/src/stdfix/macros_test.cpp          | 29 +++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/libc/include/llvm-libc-macros/stdfix-macros.h b/libc/include/llvm-libc-macros/stdfix-macros.h
index 04097e14e9747..9c04e9e3b459f 100644
--- a/libc/include/llvm-libc-macros/stdfix-macros.h
+++ b/libc/include/llvm-libc-macros/stdfix-macros.h
@@ -362,6 +362,17 @@
       unsigned short accum: rounduhk,                                          \
       unsigned long accum: roundulk)(x, y)
 
+#define idivfx(x, y)                                                           \
+  _Generic((x),                                                                \
+      fract: idivr,                                                            \
+      long fract: idivlr,                                                      \
+      accum: idivk,                                                            \
+      long accum: idivlk,                                                      \
+      unsigned fract: idivur,                                                  \
+      unsigned long fract: idivulr,                                            \
+      unsigned accum: idivuk,                                                  \
+      unsigned long accum: idivulk)(x, y)
+
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 #endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index e881b82c2a742..968fbe8859f5b 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -205,10 +205,19 @@ foreach(s IN ITEMS r hr lr k hk lk)
   )
 endforeach()
 
+foreach(suffix IN ITEMS r lr k lk)
+  list(APPEND macros_depends
+    libc.src.stdfix.idiv${suffix}
+    libc.src.stdfix.idivu${suffix}
+  )
+endforeach()
+
 add_libc_test(
   macros_test
-  SUITE libc-stdfix-tests
-  SRCS macros_test.cpp
+  SUITE
+    libc-stdfix-tests
+  SRCS
+    macros_test.cpp
   DEPENDS
     libc.include.stdfix
     ${macros_depends}
diff --git a/libc/test/src/stdfix/macros_test.cpp b/libc/test/src/stdfix/macros_test.cpp
index b52abf3f07999..372f10e97f305 100644
--- a/libc/test/src/stdfix/macros_test.cpp
+++ b/libc/test/src/stdfix/macros_test.cpp
@@ -40,6 +40,15 @@
 #include "src/stdfix/roundulr.h"
 #include "src/stdfix/roundur.h"
 
+#include "src/stdfix/idivk.h"
+#include "src/stdfix/idivlk.h"
+#include "src/stdfix/idivlr.h"
+#include "src/stdfix/idivr.h"
+#include "src/stdfix/idivuk.h"
+#include "src/stdfix/idivulk.h"
+#include "src/stdfix/idivulr.h"
+#include "src/stdfix/idivur.h"
+
 using LIBC_NAMESPACE::abshk;
 using LIBC_NAMESPACE::abshr;
 using LIBC_NAMESPACE::absk;
@@ -58,6 +67,14 @@ using LIBC_NAMESPACE::countlsuk;
 using LIBC_NAMESPACE::countlsulk;
 using LIBC_NAMESPACE::countlsulr;
 using LIBC_NAMESPACE::countlsur;
+using LIBC_NAMESPACE::idivk;
+using LIBC_NAMESPACE::idivlk;
+using LIBC_NAMESPACE::idivlr;
+using LIBC_NAMESPACE::idivr;
+using LIBC_NAMESPACE::idivuk;
+using LIBC_NAMESPACE::idivulk;
+using LIBC_NAMESPACE::idivulr;
+using LIBC_NAMESPACE::idivur;
 using LIBC_NAMESPACE::roundhk;
 using LIBC_NAMESPACE::roundhr;
 using LIBC_NAMESPACE::roundk;
@@ -111,3 +128,15 @@ TEST(LlvmLibcCountlsfxTest, Basic) {
   ASSERT_EQ(countlsfx(0.5uhk), countlsuhk(0.5uhk));
   ASSERT_EQ(countlsfx(0.5ulk), countlsulk(0.5ulk));
 }
+
+TEST(LlvmLibcIdivfxTest, Basic) {
+  ASSERT_EQ(idivfx(0.5r, 0.25r), idivr(0.5r, 0.25r));
+  ASSERT_EQ(idivfx(0.5lr, 0.25lr), idivlr(0.5lr, 0.25lr));
+  ASSERT_EQ(idivfx(0.5k, 0.25k), idivk(0.5k, 0.25k));
+  ASSERT_EQ(idivfx(0.5lk, 0.25lk), idivlk(0.5lk, 0.25lk));
+
+  ASSERT_EQ(idivfx(0.5ur, 0.25ur), idivur(0.5ur, 0.25ur));
+  ASSERT_EQ(idivfx(0.5ulr, 0.25ulr), idivulr(0.5ulr, 0.25ulr));
+  ASSERT_EQ(idivfx(0.5uk, 0.25uk), idivuk(0.5uk, 0.25uk));
+  ASSERT_EQ(idivfx(0.5ulk, 0.25ulk), idivulk(0.5ulk, 0.25ulk));
+}

>From c31a661ef7d91401804e7674f7a45734e0ea74d3 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 03:23:06 +0530
Subject: [PATCH 22/27] fix: fixed_point::div function for negative values

---
 libc/src/__support/fixed_point/fx_bits.h | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index be6d761937ac6..e2ef722cfde79 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -207,20 +207,20 @@ LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
 idiv(T x, T y) {
   using FXBits = FXBits<T>;
   using FXRep = FXRep<T>;
-  using BitType = typename FXRep::StorageType;
-
-  // TODO: add negative check
+  using CompType = typename FXRep::CompType;
 
   if (y == FXRep::ZERO()) {
-    // TODO: handle divide by zero
+    // If the value of the second operand of the / operator is zero, the
+    // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
+    return static_cast<XType>(0);
   }
 
-  FXBits x_bits(x);
-  FXBits y_bits(y);
-
-  BitType result = x_bits.get_bits() / y_bits.get_bits();
+  CompType x_comp = static_cast<CompType>(FXBits(x).get_bits());
+  CompType y_comp = static_cast<CompType>(FXBits(y).get_bits());
 
-  // TODO: handle integer overflow
+  // If an integer result of one of these functions overflows, the behavior is
+  // undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
+  CompType result = x_comp / y_comp;
 
   return static_cast<XType>(result);
 }

>From 2d341ee2f5c2d8302c3abff309191bfbc612f61b Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 03:23:32 +0530
Subject: [PATCH 23/27] feat: improve and add more tests

---
 libc/test/src/stdfix/IdivTest.h | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
index e7411278da7bc..2515703ebf84b 100644
--- a/libc/test/src/stdfix/IdivTest.h
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -20,13 +20,38 @@ class IdivTest : public LIBC_NAMESPACE::testing::Test {
   static constexpr T min = FXRep::MIN();
   static constexpr T one_half = FXRep::ONE_HALF();
   static constexpr T one_fourth = FXRep::ONE_FOURTH();
-  static constexpr T eps = FXRep::EPS();
 
 public:
   typedef XType (*IdivFunc)(T, T);
 
   void testSpecialNumbers(IdivFunc func) {
+    constexpr bool is_signed = (FXRep::SIGN_LEN > 0);
+    constexpr bool has_integral = (FXRep::INTEGRAL_LEN > 0);
+
     EXPECT_EQ(func(one_half, one_fourth), static_cast<XType>(2));
+    EXPECT_EQ(func(one_half, one_half), static_cast<XType>(1));
+    EXPECT_EQ(func(one_fourth, one_half), static_cast<XType>(0));
+    EXPECT_EQ(func(0.75, 0.25), static_cast<XType>(3));
+    EXPECT_EQ(func(0.625, 0.125), static_cast<XType>(5));
+
+    if constexpr (is_signed) {
+      EXPECT_EQ(func(min, one_half), static_cast<XType>(min) * 2);
+    } else {
+      EXPECT_EQ(func(min, one_half), static_cast<XType>(0));
+    }
+
+    if constexpr (has_integral && min <= 7 && max >= 5) {
+      EXPECT_EQ(func(6.9, 4.2), static_cast<XType>(1));
+      EXPECT_EQ(func(4.2, 6.9), static_cast<XType>(0));
+      EXPECT_EQ(func(4.5, 2.2), static_cast<XType>(2));
+      EXPECT_EQ(func(2.2, 1.1), static_cast<XType>(2));
+
+      if constexpr (is_signed) {
+        EXPECT_EQ(func(4.2, -6.9), static_cast<XType>(0));
+        EXPECT_EQ(func(-6.9, 4.2), static_cast<XType>(-1));
+        EXPECT_EQ(func(-2.5, 1.25), static_cast<XType>(-2));
+      }
+    }
   }
 };
 

>From 44bb0980f8b540e426287c802578f90335df7430 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Wed, 26 Mar 2025 03:54:57 +0530
Subject: [PATCH 24/27] docs: update idivfx

---
 libc/docs/headers/stdfix.rst |  2 +-
 libc/include/stdfix.yaml     | 64 ++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/libc/docs/headers/stdfix.rst b/libc/docs/headers/stdfix.rst
index 20f68b4a1ed35..a2f5e94774798 100644
--- a/libc/docs/headers/stdfix.rst
+++ b/libc/docs/headers/stdfix.rst
@@ -77,7 +77,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
 | divi\*        |                |             |               |            |                |             |                |             |               |            |                |             |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
-| idiv\*        |                |             |               |            |                |             |                |             |               |            |                |             |
+| idiv\*        | |check|        | |check|     | |check|       | |check|    | |check|        | |check|     | |check|        | |check|     | |check|       | |check|    | |check|        | |check|     |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
 | muli          |                |             |               |            |                |             |                |             |               |            |                |             |
 +---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
diff --git a/libc/include/stdfix.yaml b/libc/include/stdfix.yaml
index 29c4d8b5c8960..5b385124eb63d 100644
--- a/libc/include/stdfix.yaml
+++ b/libc/include/stdfix.yaml
@@ -238,6 +238,70 @@ functions:
     arguments:
       - type: unsigned long accum
     guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivr
+    standards:
+      - stdc_ext
+    return_type: int
+    arguments:
+      - type: fract
+      - type: fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivlr
+    standards:
+      - stdc_ext
+    return_type: long int
+    arguments:
+      - type: long fract
+      - type: long fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivk
+    standards:
+      - stdc_ext
+    return_type: int
+    arguments:
+      - type: accum
+      - type: accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivlk
+    standards:
+      - stdc_ext
+    return_type: long int
+    arguments:
+      - type: long accum
+      - type: long accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivur
+    standards:
+      - stdc_ext
+    return_type: unsigned int
+    arguments:
+      - type: unsigned fract
+      - type: unsigned fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivulr
+    standards:
+      - stdc_ext
+    return_type: unsigned long int
+    arguments:
+      - type: unsigned long fract
+      - type: unsigned long fract
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivuk
+    standards:
+      - stdc_ext
+    return_type: unsigned int
+    arguments:
+      - type: unsigned accum
+      - type: unsigned accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: idivulk
+    standards:
+      - stdc_ext
+    return_type: unsigned long int
+    arguments:
+      - type: unsigned long accum
+      - type: unsigned long accum
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
   - name: roundhk
     standards:
       - stdc_ext

>From 01cacf56b24e697eea826b7af19ecbd99e60d3d6 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Thu, 27 Mar 2025 23:50:39 +0530
Subject: [PATCH 25/27] revert: "chore: add type generic macros"

This reverts commit dc7713c0272731d74c928450dce5e1f32b9ce592.

Signed-off-by: krishna2803 <kpandey81930 at gmail.com>
---
 libc/include/llvm-libc-macros/stdfix-macros.h | 11 -------
 libc/test/src/stdfix/CMakeLists.txt           | 13 ++-------
 libc/test/src/stdfix/macros_test.cpp          | 29 -------------------
 3 files changed, 2 insertions(+), 51 deletions(-)

diff --git a/libc/include/llvm-libc-macros/stdfix-macros.h b/libc/include/llvm-libc-macros/stdfix-macros.h
index 9c04e9e3b459f..04097e14e9747 100644
--- a/libc/include/llvm-libc-macros/stdfix-macros.h
+++ b/libc/include/llvm-libc-macros/stdfix-macros.h
@@ -362,17 +362,6 @@
       unsigned short accum: rounduhk,                                          \
       unsigned long accum: roundulk)(x, y)
 
-#define idivfx(x, y)                                                           \
-  _Generic((x),                                                                \
-      fract: idivr,                                                            \
-      long fract: idivlr,                                                      \
-      accum: idivk,                                                            \
-      long accum: idivlk,                                                      \
-      unsigned fract: idivur,                                                  \
-      unsigned long fract: idivulr,                                            \
-      unsigned accum: idivuk,                                                  \
-      unsigned long accum: idivulk)(x, y)
-
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 #endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
diff --git a/libc/test/src/stdfix/CMakeLists.txt b/libc/test/src/stdfix/CMakeLists.txt
index 968fbe8859f5b..e881b82c2a742 100644
--- a/libc/test/src/stdfix/CMakeLists.txt
+++ b/libc/test/src/stdfix/CMakeLists.txt
@@ -205,19 +205,10 @@ foreach(s IN ITEMS r hr lr k hk lk)
   )
 endforeach()
 
-foreach(suffix IN ITEMS r lr k lk)
-  list(APPEND macros_depends
-    libc.src.stdfix.idiv${suffix}
-    libc.src.stdfix.idivu${suffix}
-  )
-endforeach()
-
 add_libc_test(
   macros_test
-  SUITE
-    libc-stdfix-tests
-  SRCS
-    macros_test.cpp
+  SUITE libc-stdfix-tests
+  SRCS macros_test.cpp
   DEPENDS
     libc.include.stdfix
     ${macros_depends}
diff --git a/libc/test/src/stdfix/macros_test.cpp b/libc/test/src/stdfix/macros_test.cpp
index 372f10e97f305..b52abf3f07999 100644
--- a/libc/test/src/stdfix/macros_test.cpp
+++ b/libc/test/src/stdfix/macros_test.cpp
@@ -40,15 +40,6 @@
 #include "src/stdfix/roundulr.h"
 #include "src/stdfix/roundur.h"
 
-#include "src/stdfix/idivk.h"
-#include "src/stdfix/idivlk.h"
-#include "src/stdfix/idivlr.h"
-#include "src/stdfix/idivr.h"
-#include "src/stdfix/idivuk.h"
-#include "src/stdfix/idivulk.h"
-#include "src/stdfix/idivulr.h"
-#include "src/stdfix/idivur.h"
-
 using LIBC_NAMESPACE::abshk;
 using LIBC_NAMESPACE::abshr;
 using LIBC_NAMESPACE::absk;
@@ -67,14 +58,6 @@ using LIBC_NAMESPACE::countlsuk;
 using LIBC_NAMESPACE::countlsulk;
 using LIBC_NAMESPACE::countlsulr;
 using LIBC_NAMESPACE::countlsur;
-using LIBC_NAMESPACE::idivk;
-using LIBC_NAMESPACE::idivlk;
-using LIBC_NAMESPACE::idivlr;
-using LIBC_NAMESPACE::idivr;
-using LIBC_NAMESPACE::idivuk;
-using LIBC_NAMESPACE::idivulk;
-using LIBC_NAMESPACE::idivulr;
-using LIBC_NAMESPACE::idivur;
 using LIBC_NAMESPACE::roundhk;
 using LIBC_NAMESPACE::roundhr;
 using LIBC_NAMESPACE::roundk;
@@ -128,15 +111,3 @@ TEST(LlvmLibcCountlsfxTest, Basic) {
   ASSERT_EQ(countlsfx(0.5uhk), countlsuhk(0.5uhk));
   ASSERT_EQ(countlsfx(0.5ulk), countlsulk(0.5ulk));
 }
-
-TEST(LlvmLibcIdivfxTest, Basic) {
-  ASSERT_EQ(idivfx(0.5r, 0.25r), idivr(0.5r, 0.25r));
-  ASSERT_EQ(idivfx(0.5lr, 0.25lr), idivlr(0.5lr, 0.25lr));
-  ASSERT_EQ(idivfx(0.5k, 0.25k), idivk(0.5k, 0.25k));
-  ASSERT_EQ(idivfx(0.5lk, 0.25lk), idivlk(0.5lk, 0.25lk));
-
-  ASSERT_EQ(idivfx(0.5ur, 0.25ur), idivur(0.5ur, 0.25ur));
-  ASSERT_EQ(idivfx(0.5ulr, 0.25ulr), idivulr(0.5ulr, 0.25ulr));
-  ASSERT_EQ(idivfx(0.5uk, 0.25uk), idivuk(0.5uk, 0.25uk));
-  ASSERT_EQ(idivfx(0.5ulk, 0.25ulk), idivulk(0.5ulk, 0.25ulk));
-}

>From 26baea9ded7bcf0978a97e3bfd3c8df6cf6f231c Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Sat, 29 Mar 2025 00:47:33 +0530
Subject: [PATCH 26/27] chore: add gaurd for zero denominator

---
 libc/src/__support/fixed_point/CMakeLists.txt | 1 +
 libc/src/__support/fixed_point/fx_bits.h      | 9 ++++-----
 libc/src/__support/macros/null_check.h        | 9 +++++++++
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/fixed_point/CMakeLists.txt b/libc/src/__support/fixed_point/CMakeLists.txt
index b415e2c00c488..235c03048cfa4 100644
--- a/libc/src/__support/fixed_point/CMakeLists.txt
+++ b/libc/src/__support/fixed_point/CMakeLists.txt
@@ -16,6 +16,7 @@ add_header_library(
     .fx_rep
     libc.include.llvm-libc-macros.stdfix_macros
     libc.src.__support.macros.attributes
+    libc.src.__support.macros.null_check
     libc.src.__support.macros.optimization
     libc.src.__support.CPP.type_traits
     libc.src.__support.CPP.bit
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index e2ef722cfde79..00c6119b4f353 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -15,6 +15,7 @@
 #include "src/__support/CPP/type_traits.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"
 
@@ -209,11 +210,9 @@ idiv(T x, T y) {
   using FXRep = FXRep<T>;
   using CompType = typename FXRep::CompType;
 
-  if (y == FXRep::ZERO()) {
-    // If the value of the second operand of the / operator is zero, the
-    // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
-    return static_cast<XType>(0);
-  }
+  // If the value of the second operand of the / operator is zero, the
+  // behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
+  LIBC_CRASH_ON_VALUE(y, FXRep::ZERO());
 
   CompType x_comp = static_cast<CompType>(FXBits(x).get_bits());
   CompType y_comp = static_cast<CompType>(FXBits(y).get_bits());
diff --git a/libc/src/__support/macros/null_check.h b/libc/src/__support/macros/null_check.h
index eda19f889235e..abf65c56c404b 100644
--- a/libc/src/__support/macros/null_check.h
+++ b/libc/src/__support/macros/null_check.h
@@ -19,10 +19,19 @@
     if (LIBC_UNLIKELY((ptr) == nullptr))                                       \
       __builtin_trap();                                                        \
   } while (0)
+#define LIBC_CRASH_ON_VALUE(var, value)                                        \
+  do {                                                                         \
+    if (LIBC_UNLIKELY((var) == (value)))                                       \
+      __builtin_trap();                                                        \
+  } while (0)
+
 #else
 #define LIBC_CRASH_ON_NULLPTR(ptr)                                             \
   do {                                                                         \
   } while (0)
+#define LIBC_CRASH_ON_VALUE(var, value)                                        \
+  do {                                                                         \
+  } while (0)
 #endif
 
 #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_NULL_CHECK_H

>From 832669cca9a401821e99f7e0d295782c19d0c459 Mon Sep 17 00:00:00 2001
From: krishna2803 <kpandey81930 at gmail.com>
Date: Sat, 29 Mar 2025 00:47:48 +0530
Subject: [PATCH 27/27] chore: update tests

---
 libc/test/src/stdfix/IdivTest.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/libc/test/src/stdfix/IdivTest.h b/libc/test/src/stdfix/IdivTest.h
index 2515703ebf84b..832f3dca894f4 100644
--- a/libc/test/src/stdfix/IdivTest.h
+++ b/libc/test/src/stdfix/IdivTest.h
@@ -9,6 +9,9 @@
 #include "test/UnitTest/Test.h"
 
 #include "src/__support/fixed_point/fx_rep.h"
+#include "src/__support/macros/sanitizer.h"
+
+#include <signal.h>
 
 template <typename T, typename XType>
 class IdivTest : public LIBC_NAMESPACE::testing::Test {
@@ -45,19 +48,44 @@ class IdivTest : public LIBC_NAMESPACE::testing::Test {
       EXPECT_EQ(func(4.2, 6.9), static_cast<XType>(0));
       EXPECT_EQ(func(4.5, 2.2), static_cast<XType>(2));
       EXPECT_EQ(func(2.2, 1.1), static_cast<XType>(2));
+      EXPECT_EQ(func(2.25, 1.0), static_cast<XType>(2));
+      EXPECT_EQ(func(2.25, 3.0), static_cast<XType>(0));
 
       if constexpr (is_signed) {
         EXPECT_EQ(func(4.2, -6.9), static_cast<XType>(0));
         EXPECT_EQ(func(-6.9, 4.2), static_cast<XType>(-1));
         EXPECT_EQ(func(-2.5, 1.25), static_cast<XType>(-2));
+        EXPECT_EQ(func(-2.25, 1.0), static_cast<XType>(-2));
+        EXPECT_EQ(func(2.25, -3.0), static_cast<XType>(0));
       }
     }
   }
+
+  void testInvalidNumbers(IdivFunc func) {
+    constexpr bool has_integral = (FXRep::INTEGRAL_LEN > 0);
+
+    EXPECT_DEATH([func] { func(0.5, 0.0); }, WITH_SIGNAL(SIGILL));
+    if constexpr (has_integral) {
+      EXPECT_DEATH([func] { func(2.5, 0.0); }, WITH_SIGNAL(SIGSEGV));
+    }
+  }
 };
 
+#if defined(LIBC_ADD_NULL_CHECKS) && !defined(LIBC_HAS_SANITIZER)
+#define LIST_IDIV_TESTS(Name, T, XTYpe, func)                                  \
+  using LlvmLibcIdiv##Name##Test = IdivTest<T, XType>;                         \
+  TEST_F(LlvmLibcIdiv##Name##Test, InvalidNumbers) {                           \
+    testInvalidNumbers(&func);                                                 \
+  }                                                                            \
+  TEST_F(LlvmLibcIdiv##Name##Test, SpecialNumbers) {                           \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  static_assert(true, "Require semicolon.")
+#else
 #define LIST_IDIV_TESTS(Name, T, XType, func)                                  \
   using LlvmLibcIdiv##Name##Test = IdivTest<T, XType>;                         \
   TEST_F(LlvmLibcIdiv##Name##Test, SpecialNumbers) {                           \
     testSpecialNumbers(&func);                                                 \
   }                                                                            \
   static_assert(true, "Require semicolon.")
+#endif // LIBC_HAS_ADDRESS_SANITIZER



More information about the libc-commits mailing list