diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt index 1744f8cf626f3..01ca4254c7996 100644 --- a/libc/src/__support/FPUtil/CMakeLists.txt +++ b/libc/src/__support/FPUtil/CMakeLists.txt @@ -217,7 +217,6 @@ add_header_library( .nearest_integer_operations .normal_float libc.hdr.math_macros - libc.src.__support.CPP.algorithm libc.src.__support.CPP.bit libc.src.__support.CPP.limits libc.src.__support.CPP.type_traits diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index f695b83fb0b0b..a289c2ef70467 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -16,7 +16,6 @@ #include "rounding_mode.h" #include "hdr/math_macros.h" -#include "src/__support/CPP/algorithm.h" #include "src/__support/CPP/bit.h" #include "src/__support/CPP/limits.h" // INT_MAX, INT_MIN #include "src/__support/CPP/type_traits.h" @@ -103,7 +102,7 @@ intlogb(U x) { return IntLogbConstants::T_MAX; } - DyadicFloat::STORAGE_LEN, 32)> normal(bits.get_val()); + DyadicFloat::STORAGE_LEN> normal(bits.get_val()); int exponent = normal.get_unbiased_exponent(); // The C standard does not specify the return value when an exponent is // out of int range. However, XSI conformance required that INT_MAX or @@ -139,7 +138,7 @@ LIBC_INLINE constexpr T logb(T x) { return FPBits::inf().get_val(); } - DyadicFloat::STORAGE_LEN, 32)> normal(bits.get_val()); + DyadicFloat::STORAGE_LEN> normal(bits.get_val()); return static_cast(normal.get_unbiased_exponent()); } diff --git a/libc/src/__support/big_int.h b/libc/src/__support/big_int.h index e2061c4300702..40ad6eeed7ac2 100644 --- a/libc/src/__support/big_int.h +++ b/libc/src/__support/big_int.h @@ -299,7 +299,8 @@ LIBC_INLINE constexpr cpp::array shift(cpp::array array, if (bit_offset == 0) dst = part1; // no crosstalk between parts. else if constexpr (direction == LEFT) - dst = (part1 << bit_offset) | (part2 >> (WORD_BITS - bit_offset)); + dst = static_cast((part1 << bit_offset) | + (part2 >> (WORD_BITS - bit_offset))); else dst = (part1 >> bit_offset) | (part2 << (WORD_BITS - bit_offset)); } @@ -969,7 +970,8 @@ struct WordTypeSelector : cpp::type_identity< #endif // LIBC_TYPES_HAS_INT64 > { }; -// Except if we request 32 bits explicitly. +// Except if we request 16 or 32 bits explicitly. +template <> struct WordTypeSelector<16> : cpp::type_identity {}; template <> struct WordTypeSelector<32> : cpp::type_identity {}; template using WordTypeSelectorT = typename WordTypeSelector::type; diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt index 1cbeec0cc4eb0..22fbd2664b546 100644 --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -9,6 +9,7 @@ add_fp_unittest( dyadic_float_test.cpp DEPENDS libc.src.__support.FPUtil.dyadic_float + libc.src.__support.macros.properties.types COMPILE_OPTIONS # Prevent constant folding with a default rounding mode. "-frounding-math" diff --git a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp index 809381ed47b59..3b1f9deb64ac8 100644 --- a/libc/test/src/__support/FPUtil/dyadic_float_test.cpp +++ b/libc/test/src/__support/FPUtil/dyadic_float_test.cpp @@ -8,6 +8,7 @@ #include "src/__support/FPUtil/dyadic_float.h" #include "src/__support/big_int.h" +#include "src/__support/macros/properties/types.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" #include "utils/MPFRWrapper/MPFRUtils.h" @@ -89,3 +90,6 @@ TEST(LlvmLibcDyadicFloatTest, QuickMul) { TEST_EDGE_RANGES(Float, float); TEST_EDGE_RANGES(Double, double); TEST_EDGE_RANGES(LongDouble, long double); +#ifdef LIBC_TYPES_HAS_FLOAT16 +TEST_EDGE_RANGES(Float16, float16); +#endif diff --git a/libc/test/src/__support/big_int_test.cpp b/libc/test/src/__support/big_int_test.cpp index 1c4f0ac29171f..84cd206b3273c 100644 --- a/libc/test/src/__support/big_int_test.cpp +++ b/libc/test/src/__support/big_int_test.cpp @@ -205,6 +205,7 @@ TYPED_TEST(LlvmLibcUIntClassTest, CountBits, Types) { } } +using LL_UInt16 = UInt<16>; using LL_UInt64 = UInt<64>; // We want to test UInt<128> explicitly. So, for // convenience, we use a sugar which does not conflict with the UInt128 type @@ -258,6 +259,19 @@ TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat128) { } #endif // LIBC_TYPES_HAS_FLOAT128 +#ifdef LIBC_TYPES_HAS_FLOAT16 +TEST(LlvmLibcUIntClassTest, BitCastToFromNativeFloat16) { + static_assert(cpp::is_trivially_copyable::value); + static_assert(sizeof(LL_UInt16) == sizeof(float16)); + const float16 array[] = {0, 0.1, 1}; + for (float16 value : array) { + LL_UInt16 back = cpp::bit_cast(value); + float16 forth = cpp::bit_cast(back); + EXPECT_TRUE(value == forth); + } +} +#endif // LIBC_TYPES_HAS_FLOAT16 + TEST(LlvmLibcUIntClassTest, BasicInit) { LL_UInt128 half_val(12345); LL_UInt128 full_val({12345, 67890});