From 7eb326441356f9e9aafa6d9f982c3c19ac6cad22 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Mon, 21 Oct 2024 17:07:58 -0700 Subject: [PATCH] [libc] Add handling for long double=double double (#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. --- 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 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> eisel_lemire(ExpandedFloat init_num, @@ -316,7 +319,8 @@ eisel_lemire(ExpandedFloat 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 { 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 { +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