diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index c8e12ff8d71bc..12c535174435c 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -379,8 +379,7 @@ set(TARGET_LIBM_ENTRYPOINTS if(LIBC_COMPILER_HAS_FLOAT128) list(APPEND TARGET_LIBM_ENTRYPOINTS # math.h C23 _Float128 entrypoints - # Temporarily disabled since float128 isn't working on the aarch64 buildbot - # libc.src.math.fabsf128 + libc.src.math.fabsf128 ) endif() diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td index b8fe16cc0c79e..c1f052e1bfa3c 100644 --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -55,7 +55,7 @@ def IntTypesAPI : PublicAPI<"inttypes.h"> { } def MathAPI : PublicAPI<"math.h"> { - let Types = ["double_t", "float_t"]; + let Types = ["double_t", "float_t", "float128"]; } def FenvAPI: PublicAPI<"fenv.h"> { diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index e3151140374a6..4f4d8434757d7 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -100,6 +100,7 @@ add_gen_header( .llvm-libc-macros.math_macros .llvm-libc-types.double_t .llvm-libc-types.float_t + .llvm-libc-types.float128 ) # TODO: This should be conditional on POSIX networking being included. diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 6f004d2d64697..e4f23b2a78130 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -98,3 +98,10 @@ add_header(ENTRY HDR ENTRY.h) add_header(struct_hsearch_data HDR struct_hsearch_data.h) add_header(struct_epoll_event HDR struct_epoll_event.h) add_header(struct_epoll_data HDR struct_epoll_data.h) +add_header( + float128 + HDR + float128.h + DEPENDS + libc.include.llvm-libc-macros.float_macros +) diff --git a/libc/include/llvm-libc-types/float128.h b/libc/include/llvm-libc-types/float128.h new file mode 100644 index 0000000000000..61a094fdb96b1 --- /dev/null +++ b/libc/include/llvm-libc-types/float128.h @@ -0,0 +1,37 @@ +//===-- Definition of float128 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_TYPES_FLOAT128_H__ +#define __LLVM_LIBC_TYPES_FLOAT128_H__ + +#include // LDBL_MANT_DIG + +// Currently, C23 `_Float128` type is only defined as a built-in type in GCC 7 +// or later, and only for C. For C++, or for clang, `__float128` is defined +// instead, and only on x86-64 targets. +// +// TODO: Update C23 `_Float128` type detection again when clang supports it. +// https://github.com/llvm/llvm-project/issues/80195 +#if defined(__STDC_IEC_60559_BFP__) && !defined(__clang__) && \ + !defined(__cplusplus) +// Use _Float128 C23 type. +#define LIBC_COMPILER_HAS_C23_FLOAT128 +typedef _Float128 float128; +#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__) +// Use __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__ to +// notify the availability of __float128. +// clang also uses __FLOAT128__ macro to notify the availability of __float128 +// type: https://reviews.llvm.org/D15120 +#define LIBC_COMPILER_HAS_FLOAT128_EXTENSION +typedef __float128 float128; +#elif (LDBL_MANT_DIG == 113) +// Use long double. +typedef long double float128; +#endif + +#endif // __LLVM_LIBC_TYPES_FLOAT128_H__ diff --git a/libc/spec/spec.td b/libc/spec/spec.td index 16abf97bf0b1c..0b557c807a546 100644 --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -53,7 +53,7 @@ def UnsignedCharType : NamedType<"unsigned char">; def UnsignedShortType : NamedType<"unsigned short">; // TODO: Add compatibility layer to use C23 type _Float128 if possible. -def Float128Type : NamedType<"__float128">; +def Float128Type : NamedType<"float128">; // Common types def VoidPtr : PtrType; diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index 6ff2c7c613696..2f9e25807021b 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -352,6 +352,7 @@ def StdC : StandardSpec<"stdc"> { [ NamedType<"float_t">, NamedType<"double_t">, + NamedType<"float128">, ], [], // Enumerations [ diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h index 9e8ed305eeca5..d0c639f4c53e0 100644 --- a/libc/src/__support/FPUtil/generic/sqrt.h +++ b/libc/src/__support/FPUtil/generic/sqrt.h @@ -36,8 +36,9 @@ template <> struct SpecialLongDouble { template LIBC_INLINE void normalize(int &exponent, typename FPBits::StorageType &mantissa) { - const int shift = cpp::countl_zero(mantissa) - - (8 * sizeof(mantissa) - 1 - FPBits::FRACTION_LEN); + const int shift = + cpp::countl_zero(mantissa) - + (8 * static_cast(sizeof(mantissa)) - 1 - FPBits::FRACTION_LEN); exponent -= shift; mantissa <<= shift; } diff --git a/libc/src/__support/macros/properties/CMakeLists.txt b/libc/src/__support/macros/properties/CMakeLists.txt index ee87ce68c9da3..3c492ab55a90c 100644 --- a/libc/src/__support/macros/properties/CMakeLists.txt +++ b/libc/src/__support/macros/properties/CMakeLists.txt @@ -33,4 +33,6 @@ add_header_library( .compiler .cpu_features .os + libc.include.llvm-libc-macros.float_macros + libc.include.llvm-libc-types.float128 ) diff --git a/libc/src/__support/macros/properties/float.h b/libc/src/__support/macros/properties/float.h index 98ca2a5d4bc46..08a1ab726cbde 100644 --- a/libc/src/__support/macros/properties/float.h +++ b/libc/src/__support/macros/properties/float.h @@ -11,13 +11,13 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FLOAT_H #define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_FLOAT_H +#include "include/llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG +#include "include/llvm-libc-types/float128.h" // float128 #include "src/__support/macros/properties/architectures.h" #include "src/__support/macros/properties/compiler.h" #include "src/__support/macros/properties/cpu_features.h" #include "src/__support/macros/properties/os.h" -#include // LDBL_MANT_DIG - // 'long double' properties. #if (LDBL_MANT_DIG == 53) #define LIBC_LONG_DOUBLE_IS_FLOAT64 @@ -53,26 +53,6 @@ using float16 = _Float16; #endif // float128 support. -#if (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301)) && \ - (defined(LIBC_TARGET_ARCH_IS_AARCH64) || \ - defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) || \ - defined(LIBC_TARGET_ARCH_IS_X86_64)) -#define LIBC_COMPILER_HAS_C23_FLOAT128 -#endif -#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 600)) && \ - (defined(LIBC_TARGET_ARCH_IS_X86_64) && \ - defined(LIBC_TARGET_OS_IS_LINUX) && !defined(LIBC_TARGET_OS_IS_FUCHSIA)) -#define LIBC_COMPILER_HAS_FLOAT128_EXTENSION -#endif - -#if defined(LIBC_COMPILER_HAS_C23_FLOAT128) -using float128 = _Float128; -#elif defined(LIBC_COMPILER_HAS_FLOAT128_EXTENSION) -using float128 = __float128; -#elif defined(LIBC_LONG_DOUBLE_IS_FLOAT128) -using float128 = long double; -#endif - #if defined(LIBC_COMPILER_HAS_C23_FLOAT128) || \ defined(LIBC_COMPILER_HAS_FLOAT128_EXTENSION) || \ defined(LIBC_LONG_DOUBLE_IS_FLOAT128)