diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake index 3a9e1e3b1cf8b4..17806588550eb6 100644 --- a/libc/cmake/modules/CheckCompilerFeatures.cmake +++ b/libc/cmake/modules/CheckCompilerFeatures.cmake @@ -2,7 +2,7 @@ # Compiler features definition and flags # ------------------------------------------------------------------------------ -set(ALL_COMPILER_FEATURES "float128" "fixed_point") +set(ALL_COMPILER_FEATURES "float16" "float128" "fixed_point") # Making sure ALL_COMPILER_FEATURES is sorted. list(SORT ALL_COMPILER_FEATURES) @@ -54,7 +54,9 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES) ) if(has_feature) list(APPEND AVAILABLE_COMPILER_FEATURES ${feature}) - if(${feature} STREQUAL "float128") + if(${feature} STREQUAL "float16") + set(LIBC_TYPES_HAS_FLOAT16 TRUE) + elseif(${feature} STREQUAL "float128") set(LIBC_TYPES_HAS_FLOAT128 TRUE) elseif(${feature} STREQUAL "fixed_point") set(LIBC_COMPILER_HAS_FIXED_POINT TRUE) diff --git a/libc/cmake/modules/compiler_features/check_float16.cpp b/libc/cmake/modules/compiler_features/check_float16.cpp new file mode 100644 index 00000000000000..c091824bf2b08d --- /dev/null +++ b/libc/cmake/modules/compiler_features/check_float16.cpp @@ -0,0 +1,5 @@ +#include "include/llvm-libc-macros/float16-macros.h" + +#ifndef LIBC_TYPES_HAS_FLOAT16 +#error unsupported +#endif diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index ad50b6f59cdcce..ca0418c3618ae0 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -496,6 +496,13 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.ufromfpxl ) +if(LIBC_TYPES_HAS_FLOAT16) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C23 _Float16 entrypoints + libc.src.math.fabsf16 + ) +endif() + if(LIBC_TYPES_HAS_FLOAT128) list(APPEND TARGET_LIBM_ENTRYPOINTS # math.h C23 _Float128 entrypoints diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 5e3ddd34fb4dcb..03cd17a8090cb6 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -528,6 +528,13 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.math.ufromfpxl ) +if(LIBC_TYPES_HAS_FLOAT16) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # math.h C23 _Float16 entrypoints + libc.src.math.fabsf16 + ) +endif() + if(LIBC_TYPES_HAS_FLOAT128) list(APPEND TARGET_LIBM_ENTRYPOINTS # math.h C23 _Float128 entrypoints diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index 28503e1d13ab5a..cd90b6ae85769b 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -124,7 +124,7 @@ Basic Operations +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | dsub | N/A | N/A | | N/A | | 7.12.14.2 | F.10.11 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| fabs | |check| | |check| | |check| | | |check| | 7.12.7.3 | F.10.4.3 | +| fabs | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | fadd | N/A | | | N/A | | 7.12.14.1 | F.10.11 | +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index be876c9090d33a..2a41ec46abdab8 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -111,6 +111,7 @@ add_gen_header( GEN_HDR math.h DEPENDS .llvm_libc_common_h + .llvm-libc-macros.float16_macros .llvm-libc-macros.math_macros .llvm-libc-types.double_t .llvm-libc-types.float_t diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index 961830ef97668c..a4c2ca0df74d35 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -91,6 +91,12 @@ add_macro_header( float-macros.h ) +add_macro_header( + float16_macros + HDR + float16-macros.h +) + add_macro_header( limits_macros HDR diff --git a/libc/include/llvm-libc-macros/float16-macros.h b/libc/include/llvm-libc-macros/float16-macros.h new file mode 100644 index 00000000000000..9f17503d85130c --- /dev/null +++ b/libc/include/llvm-libc-macros/float16-macros.h @@ -0,0 +1,17 @@ +//===-- Detection of _Float16 compiler builtin 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_MACROS_FLOAT16_MACROS_H +#define LLVM_LIBC_MACROS_FLOAT16_MACROS_H + +#if defined(__FLT16_MANT_DIG__) && \ + (!defined(__GNUC__) || __GNUC__ >= 13 || defined(__clang__)) +#define LIBC_TYPES_HAS_FLOAT16 +#endif + +#endif // LLVM_LIBC_MACROS_FLOAT16_MACROS_H diff --git a/libc/include/math.h.def b/libc/include/math.h.def index cd2fe76f40bf2c..454b8f29805145 100644 --- a/libc/include/math.h.def +++ b/libc/include/math.h.def @@ -10,6 +10,7 @@ #define LLVM_LIBC_MATH_H #include "__llvm-libc-common.h" +#include "llvm-libc-macros/float16-macros.h" #include "llvm-libc-macros/math-macros.h" #include "llvm-libc-types/float128.h" diff --git a/libc/spec/spec.td b/libc/spec/spec.td index ea8fa4cd373cf3..056a3143c5a714 100644 --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -53,6 +53,7 @@ def UnsignedCharType : NamedType<"unsigned char">; def UnsignedShortType : NamedType<"unsigned short">; def BoolType : NamedType<"bool">; +def Float16Type : NamedType<"_Float16">; def Float128Type : NamedType<"float128">; // Common types diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index eb67c9b0b009ba..ff700255144e68 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -395,6 +395,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"fabs", RetValSpec, [ArgSpec], [ConstAttr]>, FunctionSpec<"fabsf", RetValSpec, [ArgSpec]>, FunctionSpec<"fabsl", RetValSpec, [ArgSpec]>, + GuardedFunctionSpec<"fabsf16", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT16">, GuardedFunctionSpec<"fabsf128", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT128">, FunctionSpec<"fdim", RetValSpec, [ArgSpec, ArgSpec]>, 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 4c8f50f4e91f97..49b51dc83ea0a7 100644 --- a/libc/src/__support/CPP/type_traits/is_floating_point.h +++ b/libc/src/__support/CPP/type_traits/is_floating_point.h @@ -24,13 +24,17 @@ template struct is_floating_point { } public: -#if defined(LIBC_TYPES_HAS_FLOAT128) LIBC_INLINE_VAR static constexpr bool value = - __is_unqualified_any_of(); -#else - LIBC_INLINE_VAR static constexpr bool value = - __is_unqualified_any_of(); -#endif // LIBC_TYPES_HAS_FLOAT128 + __is_unqualified_any_of(); }; template LIBC_INLINE_VAR constexpr bool is_floating_point_v = diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h index ab050360c353b0..d3c96d2d613d6f 100644 --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -651,7 +651,7 @@ struct FPRepImpl : public FPRepSem { // Modifiers LIBC_INLINE constexpr RetT abs() const { - return RetT(bits & UP::EXP_SIG_MASK); + return RetT(static_cast(bits & UP::EXP_SIG_MASK)); } // Observers diff --git a/libc/src/__support/macros/properties/CMakeLists.txt b/libc/src/__support/macros/properties/CMakeLists.txt index 7718aeaa3de5af..c69f3a85d7287a 100644 --- a/libc/src/__support/macros/properties/CMakeLists.txt +++ b/libc/src/__support/macros/properties/CMakeLists.txt @@ -34,5 +34,6 @@ add_header_library( .cpu_features .os libc.hdr.float_macros + libc.include.llvm-libc-macros.float16_macros libc.include.llvm-libc-types.float128 ) diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h index 781cf1b7a2b627..69ddc912238e74 100644 --- a/libc/src/__support/macros/properties/types.h +++ b/libc/src/__support/macros/properties/types.h @@ -11,7 +11,8 @@ #define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H #include "hdr/float_macros.h" // LDBL_MANT_DIG -#include "include/llvm-libc-types/float128.h" // float128 +#include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16 +#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" @@ -39,28 +40,12 @@ #endif // defined(__SIZEOF_INT128__) // -- float16 support --------------------------------------------------------- -// TODO: move this logic to "llvm-libc-types/float16.h" -#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2) -#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1500)) || \ - (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1201)) -#define LIBC_TYPES_HAS_FLOAT16 +// LIBC_TYPES_HAS_FLOAT16 is provided by +// "include/llvm-libc-macros/float16-macros.h" +#ifdef LIBC_TYPES_HAS_FLOAT16 +// Type alias for internal use. using float16 = _Float16; -#endif -#endif -#if defined(LIBC_TARGET_ARCH_IS_AARCH64) -#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 900)) || \ - (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301)) -#define LIBC_TYPES_HAS_FLOAT16 -using float16 = _Float16; -#endif -#endif -#if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV) -#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1300)) || \ - (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301)) -#define LIBC_TYPES_HAS_FLOAT16 -using float16 = _Float16; -#endif -#endif +#endif // LIBC_TYPES_HAS_FLOAT16 // -- float128 support -------------------------------------------------------- // LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index c34c58575441d3..31df5d0ab88098 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -99,6 +99,7 @@ add_math_entrypoint_object(expm1f) add_math_entrypoint_object(fabs) add_math_entrypoint_object(fabsf) add_math_entrypoint_object(fabsl) +add_math_entrypoint_object(fabsf16) add_math_entrypoint_object(fabsf128) add_math_entrypoint_object(fdim) diff --git a/libc/src/math/fabsf16.h b/libc/src/math/fabsf16.h new file mode 100644 index 00000000000000..532662a77e9a64 --- /dev/null +++ b/libc/src/math/fabsf16.h @@ -0,0 +1,20 @@ +//===-- Implementation header for fabsf16 -----------------------*- 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_MATH_FABSF16_H +#define LLVM_LIBC_SRC_MATH_FABSF16_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +float16 fabsf16(float16 x); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_FABSF16_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 269bc6be5d8343..04656e3186181d 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -241,6 +241,19 @@ add_entrypoint_object( -O2 ) +add_entrypoint_object( + fabsf16 + SRCS + fabsf16.cpp + HDRS + ../fabsf16.h + DEPENDS + libc.src.__support.macros.properties.types + libc.src.__support.FPUtil.basic_operations + COMPILE_OPTIONS + -O3 +) + add_entrypoint_object( fabsf128 SRCS diff --git a/libc/src/math/generic/fabsf16.cpp b/libc/src/math/generic/fabsf16.cpp new file mode 100644 index 00000000000000..4de84f35da3024 --- /dev/null +++ b/libc/src/math/generic/fabsf16.cpp @@ -0,0 +1,17 @@ +//===-- Implementation of fabsf16 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 "src/math/fabsf16.h" +#include "src/__support/FPUtil/BasicOperations.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float16, fabsf16, (float16 x)) { return fputil::abs(x); } + +} // namespace LIBC_NAMESPACE diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 112b2985829ca3..b46fe5e902c67f 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -92,6 +92,18 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) +add_fp_unittest( + fabsf16_test + SUITE + libc-math-smoke-tests + SRCS + fabsf16_test.cpp + HDRS + FAbsTest.h + DEPENDS + libc.src.math.fabsf16 +) + add_fp_unittest( fabsf128_test SUITE diff --git a/libc/test/src/math/smoke/fabsf16_test.cpp b/libc/test/src/math/smoke/fabsf16_test.cpp new file mode 100644 index 00000000000000..c43bd5090f90b9 --- /dev/null +++ b/libc/test/src/math/smoke/fabsf16_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for fabsf16 ---------------------------------------------===// +// +// 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 "FAbsTest.h" + +#include "src/math/fabsf16.h" + +LIST_FABS_TESTS(float16, LIBC_NAMESPACE::fabsf16)