[libc] Add WordTypeSelector<16> specialization (#94979)

This commit is contained in:
OverMighty
2024-06-10 15:56:02 +02:00
committed by GitHub
parent 88ff2463ea
commit 6b21e17049
6 changed files with 25 additions and 6 deletions

View File

@@ -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

View File

@@ -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>::T_MAX;
}
DyadicFloat<cpp::max(FPBits<U>::STORAGE_LEN, 32)> normal(bits.get_val());
DyadicFloat<FPBits<U>::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<T>::inf().get_val();
}
DyadicFloat<cpp::max(FPBits<T>::STORAGE_LEN, 32)> normal(bits.get_val());
DyadicFloat<FPBits<T>::STORAGE_LEN> normal(bits.get_val());
return static_cast<T>(normal.get_unbiased_exponent());
}

View File

@@ -299,7 +299,8 @@ LIBC_INLINE constexpr cpp::array<word, N> shift(cpp::array<word, N> 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<word>((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<uint16_t> {};
template <> struct WordTypeSelector<32> : cpp::type_identity<uint32_t> {};
template <size_t Bits>
using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;

View File

@@ -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"

View File

@@ -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

View File

@@ -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<LL_UInt16>::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<LL_UInt16>(value);
float16 forth = cpp::bit_cast<float16>(back);
EXPECT_TRUE(value == forth);
}
}
#endif // LIBC_TYPES_HAS_FLOAT16
TEST(LlvmLibcUIntClassTest, BasicInit) {
LL_UInt128 half_val(12345);
LL_UInt128 full_val({12345, 67890});