[libc-commits] [libc] [libc] Float128 Emulation in LLVM libc (PR #200565)

via libc-commits libc-commits at lists.llvm.org
Wed Jun 3 01:11:09 PDT 2026


https://github.com/Sukumarsawant updated https://github.com/llvm/llvm-project/pull/200565

>From d076a3641e67df6580c2ea767f2545e35ccb9ee8 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Sat, 30 May 2026 02:08:42 +0530
Subject: [PATCH 1/9] test: float128 skeleton

---
 libc/src/__support/FPUtil/CMakeLists.txt | 11 ++++++
 libc/src/__support/FPUtil/float128.h     | 45 ++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 libc/src/__support/FPUtil/float128.h

diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index d45dd82560788..a88986b4992f8 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -294,4 +294,15 @@ add_header_library(
     libc.src.__support.macros.properties.types
 )
 
+add_header_library(
+  float128
+  HDRS
+    float128.h
+  DEPENDS
+    .fp_bits
+    libc.hdr.fenv_macros
+    libc.src.__support.CPP.bit
+    libc.src.__support.uint128
+)
+
 add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
new file mode 100644
index 0000000000000..73f450f1d41a8
--- /dev/null
+++ b/libc/src/__support/FPUtil/float128.h
@@ -0,0 +1,45 @@
+//===-- Utilities for Float128 data type  -----------------------*- 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___SUPPORT_FPUTIL_FLOAT128_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
+
+#include "FPBits.h"
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float128 {
+  UInt128 bits;
+  // Testing
+  constexpr Float128() = default;
+  /* TODO: precision
+     TODO: explicit so it does not convert without warn ( Done )
+     VERIFY :   template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
+                                 fputil::FPType::IEEE754_Binary64,
+                             int> = 0>
+  */
+  constexpr explicit Float128(double x) {
+    FPBits<double> x_bits(x);
+    uint64_t val = x_bits.uintval();
+    bits = static_cast<UInt128>(val) << 64;
+  }
+
+  constexpr explicit operator double() const {
+    uint64_t val = static_cast<uint64_t>(bits >> 64U);
+    return cpp::bit_cast<double>(val);
+  }
+};
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H

>From 098b0dec5ed583a29ffae25729b21d360beeface Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:00:26 +0530
Subject: [PATCH 2/9] Add small smoke test

---
 .../CPP/type_traits/is_floating_point.h       |  2 +-
 libc/src/__support/FPUtil/CMakeLists.txt      |  4 +-
 libc/src/__support/FPUtil/FPBits.h            | 13 +++++-
 libc/src/__support/FPUtil/float128.h          | 41 +++++++++++--------
 libc/src/__support/macros/properties/types.h  |  8 ++++
 libc/test/src/math/smoke/CMakeLists.txt       | 10 +++++
 libc/test/src/math/smoke/float128_test.cpp    | 25 +++++++++++
 7 files changed, 81 insertions(+), 22 deletions(-)
 create mode 100644 libc/test/src/math/smoke/float128_test.cpp

diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index 9dc77ad7ee0ea..ab4191868517e 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -37,7 +37,7 @@ template <typename T> struct is_floating_point {
                               float128
 #endif
                               ,
-                              bfloat16>();
+                              bfloat16, fputil::Float128>();
 };
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index a88986b4992f8..20e1c01bb8ca1 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -299,9 +299,9 @@ add_header_library(
   HDRS
     float128.h
   DEPENDS
-    .fp_bits
-    libc.hdr.fenv_macros
     libc.src.__support.CPP.bit
+    libc.src.__support.macros.attributes
+    libc.src.__support.macros.config
     libc.src.__support.uint128
 )
 
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index c52699e17e225..5b7461a44cff5 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -37,7 +37,8 @@ enum class FPType {
   IEEE754_Binary64,
   IEEE754_Binary128,
   X86_Binary80,
-  BFloat16
+  BFloat16,
+  Float128
 };
 
 // The classes hierarchy is as follows:
@@ -146,6 +147,14 @@ template <> struct FPLayout<FPType::BFloat16> {
   LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
 };
 
+template <> struct FPLayout<FPType::Float128> {
+  using StorageType = UInt128;
+  LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
+  LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
+  LIBC_INLINE_VAR static constexpr int SIG_LEN = 112;
+  LIBC_INLINE_VAR static constexpr int FRACTION_LEN = SIG_LEN;
+};
+
 // FPStorage derives useful constants from the FPLayout above.
 template <FPType fp_type> struct FPStorage : public FPLayout<fp_type> {
   using UP = FPLayout<fp_type>;
@@ -813,6 +822,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
 #endif
   else if constexpr (cpp::is_same_v<UnqualT, bfloat16>)
     return FPType::BFloat16;
+  else if constexpr (cpp::is_same_v<UnqualT, Float128>)
+    return FPType::Float128;
   else
     static_assert(cpp::always_false<UnqualT>, "Unsupported type");
 }
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index 73f450f1d41a8..ca5c49ddf11d7 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
 //===-- Utilities for Float128 data type  -----------------------*- C++ -*-===//
+=======
+//===-- Definition for Float128 data type -----------------------*- C++ -*-===//
+>>>>>>> f128-test
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -9,33 +13,34 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 
-#include "FPBits.h"
-#include "hdr/fenv_macros.h"
-#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/bit.h" // cpp::bit_cast
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
 #include "src/__support/uint128.h"
+#include <stdint.h>
 
 namespace LIBC_NAMESPACE_DECL {
 namespace fputil {
 
 struct Float128 {
   UInt128 bits;
-  // Testing
-  constexpr Float128() = default;
-  /* TODO: precision
-     TODO: explicit so it does not convert without warn ( Done )
-     VERIFY :   template <cpp::enable_if_t<fputil::get_fp_type<Double>() ==
-                                 fputil::FPType::IEEE754_Binary64,
-                             int> = 0>
-  */
-  constexpr explicit Float128(double x) {
-    FPBits<double> x_bits(x);
-    uint64_t val = x_bits.uintval();
-    bits = static_cast<UInt128>(val) << 64;
+
+  LIBC_INLINE Float128() = default;
+
+  LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
+    uint64_t d = cpp::bit_cast<uint64_t>(x);
+    bits = static_cast<UInt128>(d) << 64U;
   }
 
-  constexpr explicit operator double() const {
-    uint64_t val = static_cast<uint64_t>(bits >> 64U);
-    return cpp::bit_cast<double>(val);
+  LIBC_INLINE constexpr explicit operator double() const {
+    return cpp::bit_cast<double>(static_cast<uint64_t>(bits >> 64U));
+  }
+
+  LIBC_INLINE constexpr bool operator==(Float128 other) const {
+    return bits == other.bits;
+  }
+  LIBC_INLINE constexpr bool operator!=(Float128 other) const {
+    return bits != other.bits;
   }
 };
 
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 3259c8a6a1d12..d94f6068984df 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -58,6 +58,14 @@ using float16 = _Float16;
 // LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
 // "include/llvm-libc-types/float128.h"
 
+// -- Emulated float128 support ------------------------------------------------
+// Float128 is always available regardless of native __float128 support.
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float128;
+}
+} // namespace LIBC_NAMESPACE_DECL
+
 // -- bfloat16 support ---------------------------------------------------------
 
 namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index bb462afb71b91..bc911ea8a798f 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1,6 +1,16 @@
 add_custom_target(libc-math-smoke-tests)
 add_dependencies(libc-math-unittests libc-math-smoke-tests)
 
+add_libc_unittest(
+  float128_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    float128_test.cpp
+  DEPENDS
+    libc.src.__support.FPUtil.float128
+)
+
 add_fp_unittest(
   cosf_test
   SUITE
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
new file mode 100644
index 0000000000000..738e5ec703f00
--- /dev/null
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -0,0 +1,25 @@
+//===-- Unittests for Float128 emulated type -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/FPUtil/float128.h"
+#include "src/__support/uint128.h"
+#include "test/UnitTest/Test.h"
+
+using LIBC_NAMESPACE::fputil::Float128;
+
+TEST(LlvmLibcFloat128Test, DefaultConstructor) {
+  Float128 x;
+  (void)x;
+}
+
+TEST(LlvmLibcFloat128Test, Equality) {
+  Float128 a(1.0), b(1.0), c(2.0);
+  ASSERT_TRUE(a == b);
+  ASSERT_TRUE(a != c);
+  ASSERT_TRUE(b != c);
+}

>From 2f45df239d2aa24e748d40d64e9898f74449c41d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 14:06:05 +0530
Subject: [PATCH 3/9] nit

---
 libc/src/__support/FPUtil/float128.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index ca5c49ddf11d7..c7835d7376853 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -1,8 +1,4 @@
-<<<<<<< HEAD
-//===-- Utilities for Float128 data type  -----------------------*- C++ -*-===//
-=======
 //===-- Definition for Float128 data type -----------------------*- C++ -*-===//
->>>>>>> f128-test
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 680c1664cef2d8ddc1e8422b7f02d2e87f07f846 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 15:13:25 +0530
Subject: [PATCH 4/9] nit

---
 libc/src/__support/FPUtil/float128.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index c7835d7376853..cc72692e8a22f 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 
-#include "src/__support/CPP/bit.h" // cpp::bit_cast
+#include "src/__support/CPP/bit.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/uint128.h"
@@ -24,8 +24,8 @@ struct Float128 {
   LIBC_INLINE Float128() = default;
 
   LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
-    uint64_t d = cpp::bit_cast<uint64_t>(x);
-    bits = static_cast<UInt128>(d) << 64U;
+    uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
+    bits = static_cast<UInt128>(x_bits) << 64U;
   }
 
   LIBC_INLINE constexpr explicit operator double() const {

>From f25b345a636cca7028b67ea84e95e5cd05be3a96 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 20:52:36 +0530
Subject: [PATCH 5/9] temp commit for rebase

---
 libc/src/__support/CPP/type_traits/is_floating_point.h | 5 ++++-
 libc/src/__support/FPUtil/cast.h                       | 4 +++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index ab4191868517e..d53dcd4961ab6 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -37,7 +37,10 @@ template <typename T> struct is_floating_point {
                               float128
 #endif
                               ,
-                              bfloat16, fputil::Float128>();
+                              bfloat16
+
+                              ,
+                              fputil::Float128>();
 };
 template <typename T>
 LIBC_INLINE_VAR constexpr bool is_floating_point_v =
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index 54c80e862523a..4fc5ea0893ebe 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -31,7 +31,9 @@ cast(InType x) {
     return x;
   } else {
     if constexpr (cpp::is_same_v<OutType, bfloat16> ||
-                  cpp::is_same_v<InType, bfloat16>
+                  cpp::is_same_v<InType, bfloat16> ||
+                  cpp::is_same_v<OutType, Float128> ||
+                  cpp::is_same_v<InType, Float128>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<OutType, float16> ||
                   cpp::is_same_v<InType, float16>

>From 5f6770ff2a60d83c7d3b87c4e5800c8c6544f1e2 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Tue, 2 Jun 2026 22:24:48 +0530
Subject: [PATCH 6/9] feat: comparison operator overload

---
 libc/src/__support/FPUtil/CMakeLists.txt     |  2 ++
 libc/src/__support/FPUtil/cast.h             |  4 ++--
 libc/src/__support/FPUtil/dyadic_float.h     |  2 +-
 libc/src/__support/FPUtil/float128.h         | 23 ++++++++++++++++++--
 libc/src/__support/macros/properties/types.h |  3 +++
 libc/test/src/math/smoke/float128_test.cpp   |  8 ++++++-
 6 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 20e1c01bb8ca1..c49d873b026e2 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -303,6 +303,8 @@ add_header_library(
     libc.src.__support.macros.attributes
     libc.src.__support.macros.config
     libc.src.__support.uint128
+    libc.src.__support.CPP.type_traits
+    .comparison_operations
 )
 
 add_subdirectory(generic)
diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index 4fc5ea0893ebe..e7b2caf92fe4a 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -32,8 +32,8 @@ cast(InType x) {
   } else {
     if constexpr (cpp::is_same_v<OutType, bfloat16> ||
                   cpp::is_same_v<InType, bfloat16> ||
-                  cpp::is_same_v<OutType, Float128> ||
-                  cpp::is_same_v<InType, Float128>
+                  cpp::is_same_v<OutType, float128> ||
+                  cpp::is_same_v<InType, float128>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<OutType, float16> ||
                   cpp::is_same_v<InType, float16>
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 7e4ea2f1a81be..661e3e517f556 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -412,7 +412,7 @@ template <size_t Bits> struct DyadicFloat {
                                             (FPBits<T>::FRACTION_LEN < Bits),
                                         void>>
   LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
-    if constexpr (cpp::is_same_v<T, bfloat16>
+    if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, float128>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<T, float16>
 #endif
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index cc72692e8a22f..d887153f58afb 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -10,6 +10,8 @@
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 
 #include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/comparison_operations.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/uint128.h"
@@ -33,10 +35,27 @@ struct Float128 {
   }
 
   LIBC_INLINE constexpr bool operator==(Float128 other) const {
-    return bits == other.bits;
+    return fputil::equals(*this, other);
   }
+
   LIBC_INLINE constexpr bool operator!=(Float128 other) const {
-    return bits != other.bits;
+    return !fputil::equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<(Float128 other) const {
+    return fputil::less_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator<=(Float128 other) const {
+    return fputil::less_than_or_equals(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>(Float128 other) const {
+    return fputil::greater_than(*this, other);
+  }
+
+  LIBC_INLINE constexpr bool operator>=(Float128 other) const {
+    return fputil::greater_than_or_equals(*this, other);
   }
 };
 
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index d94f6068984df..02d08867a4c9f 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -66,6 +66,9 @@ struct Float128;
 }
 } // namespace LIBC_NAMESPACE_DECL
 
+#ifndef LIBC_TYPES_HAS_FLOAT128
+using float128 = LIBC_NAMESPACE::fputil::Float128;
+#endif // LIBC_TYPES_HAS_FLOAT128
 // -- bfloat16 support ---------------------------------------------------------
 
 namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/test/src/math/smoke/float128_test.cpp b/libc/test/src/math/smoke/float128_test.cpp
index 738e5ec703f00..29fcc73384fd5 100644
--- a/libc/test/src/math/smoke/float128_test.cpp
+++ b/libc/test/src/math/smoke/float128_test.cpp
@@ -17,9 +17,15 @@ TEST(LlvmLibcFloat128Test, DefaultConstructor) {
   (void)x;
 }
 
-TEST(LlvmLibcFloat128Test, Equality) {
+TEST(LlvmLibcFloat128Test, operators) {
   Float128 a(1.0), b(1.0), c(2.0);
+
+  // comparison operators
   ASSERT_TRUE(a == b);
   ASSERT_TRUE(a != c);
   ASSERT_TRUE(b != c);
+  ASSERT_TRUE(c > b);
+  ASSERT_TRUE(a >= b);
+  ASSERT_TRUE(b <= c);
+  ASSERT_TRUE(a < c);
 }

>From c080d73e1d4dbc9fd352c064569b83f0ce74181d Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 00:02:22 +0530
Subject: [PATCH 7/9] marking default const , constexpr

---
 libc/src/__support/FPUtil/float128.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index d887153f58afb..c9db7fd683bd1 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,7 +23,7 @@ namespace fputil {
 struct Float128 {
   UInt128 bits;
 
-  LIBC_INLINE Float128() = default;
+  LIBC_INLINE constexpr Float128() = default;
 
   LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
     uint64_t x_bits = cpp::bit_cast<uint64_t>(x);

>From a38794948f7c924436ba4a9b41a178ef1b85eaec Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 01:02:42 +0530
Subject: [PATCH 8/9] testing alias + removed constexpr for def const

---
 libc/src/__support/FPUtil/cast.h             | 4 ++--
 libc/src/__support/FPUtil/dyadic_float.h     | 2 +-
 libc/src/__support/FPUtil/float128.h         | 2 +-
 libc/src/__support/macros/properties/types.h | 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/FPUtil/cast.h b/libc/src/__support/FPUtil/cast.h
index e7b2caf92fe4a..4fc5ea0893ebe 100644
--- a/libc/src/__support/FPUtil/cast.h
+++ b/libc/src/__support/FPUtil/cast.h
@@ -32,8 +32,8 @@ cast(InType x) {
   } else {
     if constexpr (cpp::is_same_v<OutType, bfloat16> ||
                   cpp::is_same_v<InType, bfloat16> ||
-                  cpp::is_same_v<OutType, float128> ||
-                  cpp::is_same_v<InType, float128>
+                  cpp::is_same_v<OutType, Float128> ||
+                  cpp::is_same_v<InType, Float128>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<OutType, float16> ||
                   cpp::is_same_v<InType, float16>
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 661e3e517f556..3fe427f70b2ab 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -412,7 +412,7 @@ template <size_t Bits> struct DyadicFloat {
                                             (FPBits<T>::FRACTION_LEN < Bits),
                                         void>>
   LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
-    if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, float128>
+    if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128>
 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
                   || cpp::is_same_v<T, float16>
 #endif
diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index c9db7fd683bd1..d887153f58afb 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -23,7 +23,7 @@ namespace fputil {
 struct Float128 {
   UInt128 bits;
 
-  LIBC_INLINE constexpr Float128() = default;
+  LIBC_INLINE Float128() = default;
 
   LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
     uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 02d08867a4c9f..7b861640c785d 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -66,9 +66,9 @@ struct Float128;
 }
 } // namespace LIBC_NAMESPACE_DECL
 
-#ifndef LIBC_TYPES_HAS_FLOAT128
-using float128 = LIBC_NAMESPACE::fputil::Float128;
-#endif // LIBC_TYPES_HAS_FLOAT128
+// #ifndef LIBC_TYPES_HAS_FLOAT128
+// using float128 = LIBC_NAMESPACE::fputil::Float128;
+// #endif // LIBC_TYPES_HAS_FLOAT128
 // -- bfloat16 support ---------------------------------------------------------
 
 namespace LIBC_NAMESPACE_DECL {

>From 844462a5715eeb29bfd3c298c95420e6f63cd735 Mon Sep 17 00:00:00 2001
From: Sukumarsawant <sawantsukumar at gmail.com>
Date: Wed, 3 Jun 2026 13:40:43 +0530
Subject: [PATCH 9/9] template + LIBC_CONSTEXPR_DEFAULT

---
 libc/src/__support/FPUtil/float128.h | 30 ++++++++++++++++------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/libc/src/__support/FPUtil/float128.h b/libc/src/__support/FPUtil/float128.h
index d887153f58afb..97c0daf79c546 100644
--- a/libc/src/__support/FPUtil/float128.h
+++ b/libc/src/__support/FPUtil/float128.h
@@ -9,8 +9,8 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
 
-#include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/cast.h"
 #include "src/__support/FPUtil/comparison_operations.h"
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
@@ -25,36 +25,40 @@ struct Float128 {
 
   LIBC_INLINE Float128() = default;
 
-  LIBC_INLINE constexpr explicit Float128(double x) : bits(0) {
-    uint64_t x_bits = cpp::bit_cast<uint64_t>(x);
-    bits = static_cast<UInt128>(x_bits) << 64U;
+  template <typename T> LIBC_INLINE constexpr explicit Float128(T x) : bits(0) {
+    if constexpr (cpp::is_floating_point_v<T>) {
+      bits = fputil::cast<Float128>(x).bits;
+    }
+    // TODO: add rem after testing
   }
 
-  LIBC_INLINE constexpr explicit operator double() const {
-    return cpp::bit_cast<double>(static_cast<uint64_t>(bits >> 64U));
+  template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T> &&
+                                             !cpp::is_same_v<T, Float128>,
+                                         int> = 0>
+  LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
+    return fputil::cast<T>(*this);
   }
-
-  LIBC_INLINE constexpr bool operator==(Float128 other) const {
+  LIBC_INLINE constexpr bool operator==(Float128 &other) const {
     return fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator!=(Float128 other) const {
+  LIBC_INLINE constexpr bool operator!=(Float128 &other) const {
     return !fputil::equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<(Float128 other) const {
+  LIBC_INLINE constexpr bool operator<(Float128 &other) const {
     return fputil::less_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator<=(Float128 other) const {
+  LIBC_INLINE constexpr bool operator<=(Float128 &other) const {
     return fputil::less_than_or_equals(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>(Float128 other) const {
+  LIBC_INLINE constexpr bool operator>(Float128 &other) const {
     return fputil::greater_than(*this, other);
   }
 
-  LIBC_INLINE constexpr bool operator>=(Float128 other) const {
+  LIBC_INLINE constexpr bool operator>=(Float128 &other) const {
     return fputil::greater_than_or_equals(*this, other);
   }
 };



More information about the libc-commits mailing list