[libc-commits] [libc] [libc] Add handling for long double=double double (PR #113235)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Mon Oct 21 17:02:51 PDT 2024


https://github.com/michaelrj-google created https://github.com/llvm/llvm-project/pull/113235

For Hand-In-Hand we need float to string to support a wider set of
architectures, specifically the ones that libc++ supports. This includes
powerpc, which apparently uses "double double" as its long double type.
Since Hand-In-Hand isn't currently using long double, this just opts
them out.


>From c6bb99b4007a043acf8069d8443e075d71a84d2a Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Mon, 21 Oct 2024 16:55:39 -0700
Subject: [PATCH] [libc] Add handling for long double=double double

For Hand-In-Hand we need float to string to support a wider set of
architectures, specifically the ones that libc++ supports. This includes
powerpc, which apparently uses "double double" as its long double type.
Since Hand-In-Hand isn't currently using long double, this just opts
them out.
---
 libc/src/__support/macros/properties/types.h |  2 ++
 libc/src/__support/str_to_float.h            | 20 ++++++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index 3ede8a6503d771..5ea54a4f9ef9dd 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -27,6 +27,8 @@
 #define LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
 #elif (LDBL_MANT_DIG == 113)
 #define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
+#elif (LDBL_MANT_DIG == 103)
+#define LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE
 #endif
 
 // int64 / uint64 support
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index 91569af5cb7679..a1f4eef03fc3ce 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -195,7 +195,10 @@ eisel_lemire(ExpandedFloat<T> init_num,
   return output;
 }
 
-#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+// TODO: Re-enable eisel-lemire for long double is double double once it's
+// properly supported.
+#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) &&                             \
+    !defined(LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE)
 template <>
 LIBC_INLINE cpp::optional<ExpandedFloat<long double>>
 eisel_lemire<long double>(ExpandedFloat<long double> init_num,
@@ -316,7 +319,8 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
   output.exponent = exp2;
   return output;
 }
-#endif // !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+#endif // !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64) &&
+       // !defined(LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE)
 
 // The nth item in POWERS_OF_TWO represents the greatest power of two less than
 // 10^n. This tells us how much we can safely shift without overshooting.
@@ -518,6 +522,18 @@ template <> class ClingerConsts<long double> {
   static constexpr long double MAX_EXACT_INT =
       10384593717069655257060992658440191.0L;
 };
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE)
+// TODO: Add proper double double type support here, currently using constants
+// for double since it should be safe.
+template <> class ClingerConsts<long double> {
+public:
+  static constexpr double POWERS_OF_TEN_ARRAY[] = {
+      1e0,  1e1,  1e2,  1e3,  1e4,  1e5,  1e6,  1e7,  1e8,  1e9,  1e10, 1e11,
+      1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
+  static constexpr int32_t EXACT_POWERS_OF_TEN = 22;
+  static constexpr int32_t DIGITS_IN_MANTISSA = 15;
+  static constexpr double MAX_EXACT_INT = 9007199254740991.0;
+};
 #else
 #error "Unknown long double type"
 #endif



More information about the libc-commits mailing list