Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions libc/src/__support/FPUtil/FPBits.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ template <> struct FPLayout<FPType::IEEE754_Binary128> {
};

template <> struct FPLayout<FPType::X86_Binary80> {
#if __SIZEOF_LONG_DOUBLE__ == 12
using StorageType = UInt<__SIZEOF_LONG_DOUBLE__ * CHAR_BIT>;
#else
using StorageType = UInt128;
#endif
LIBC_INLINE_VAR static constexpr int SIGN_LEN = 1;
LIBC_INLINE_VAR static constexpr int EXP_LEN = 15;
LIBC_INLINE_VAR static constexpr int SIG_LEN = 64;
Expand Down
3 changes: 2 additions & 1 deletion libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace LIBC_NAMESPACE_DECL {
namespace fputil {
namespace x86 {

LIBC_INLINE void normalize(int &exponent, UInt128 &mantissa) {
LIBC_INLINE void normalize(int &exponent,
FPBits<long double>::StorageType &mantissa) {
const unsigned int shift = static_cast<unsigned int>(
cpp::countl_zero(static_cast<uint64_t>(mantissa)) -
(8 * sizeof(uint64_t) - 1 - FPBits<long double>::FRACTION_LEN));
Expand Down
10 changes: 9 additions & 1 deletion libc/src/__support/big_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ struct BigInt {
!cpp::is_same_v<T, bool>>>
LIBC_INLINE constexpr BigInt(T v) {
constexpr size_t T_SIZE = sizeof(T) * CHAR_BIT;
const bool is_neg = Signed && (v < 0);
const bool is_neg = v < 0;
for (size_t i = 0; i < WORD_COUNT; ++i) {
if (v == 0) {
extend(i, is_neg);
Expand Down Expand Up @@ -504,6 +504,12 @@ struct BigInt {
// TODO: Reuse the Sign type.
LIBC_INLINE constexpr bool is_neg() const { return SIGNED && get_msb(); }

template <size_t OtherBits, bool OtherSigned, typename OtherWordType>
LIBC_INLINE constexpr explicit
operator BigInt<OtherBits, OtherSigned, OtherWordType>() const {
return BigInt<OtherBits, OtherSigned, OtherWordType>(this);
}

template <typename T> LIBC_INLINE constexpr explicit operator T() const {
return to<T>();
}
Expand Down Expand Up @@ -1058,6 +1064,8 @@ struct WordTypeSelector : cpp::type_identity<
// 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 <> struct WordTypeSelector<96> : cpp::type_identity<uint32_t> {};

template <size_t Bits>
using WordTypeSelectorT = typename WordTypeSelector<Bits>::type;
} // namespace internal
Expand Down
17 changes: 3 additions & 14 deletions libc/src/__support/float_to_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,23 +373,12 @@ LIBC_INLINE UInt<MID_INT_SIZE> get_table_negative_df(int exponent, size_t i) {
return result;
}

LIBC_INLINE uint32_t fast_uint_mod_1e9(const UInt<MID_INT_SIZE> &val) {
// The formula for mult_const is:
// 1 + floor((2^(bits in target integer size + log_2(divider))) / divider)
// Where divider is 10^9 and target integer size is 128.
const UInt<MID_INT_SIZE> mult_const(
{0x31680A88F8953031u, 0x89705F4136B4A597u, 0});
const auto middle = (mult_const * val);
const uint64_t result = static_cast<uint64_t>(middle[2]);
const uint64_t shifted = result >> 29;
return static_cast<uint32_t>(static_cast<uint32_t>(val) -
(EXP10_9 * shifted));
}

LIBC_INLINE uint32_t mul_shift_mod_1e9(const FPBits::StorageType mantissa,
const UInt<MID_INT_SIZE> &large,
const int32_t shift_amount) {
UInt<MID_INT_SIZE + FPBits::STORAGE_LEN> val(large);
// make sure the number of bits is always divisible by 64
UInt<internal::div_ceil(MID_INT_SIZE + FPBits::STORAGE_LEN, 64) * 64> val(
large);
val = (val * mantissa) >> shift_amount;
return static_cast<uint32_t>(
val.div_uint_half_times_pow_2(static_cast<uint32_t>(EXP10_9), 0).value());
Expand Down
4 changes: 4 additions & 0 deletions libc/src/__support/integer_literals.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ LIBC_INLINE constexpr T parse_with_prefix(const char *ptr) {

} // namespace internal

LIBC_INLINE constexpr UInt<96> operator""_u96(const char *x) {
return internal::parse_with_prefix<UInt<96>>(x);
}

LIBC_INLINE constexpr UInt128 operator""_u128(const char *x) {
return internal::parse_with_prefix<UInt128>(x);
}
Expand Down
14 changes: 7 additions & 7 deletions libc/src/__support/str_to_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
using FPBits = typename fputil::FPBits<long double>;
using StorageType = typename FPBits::StorageType;

StorageType mantissa = init_num.mantissa;
UInt128 mantissa = init_num.mantissa;
int32_t exp10 = init_num.exponent;

// Exp10 Range
Expand All @@ -225,7 +225,8 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
}

// Normalization
uint32_t clz = cpp::countl_zero<StorageType>(mantissa);
uint32_t clz = cpp::countl_zero(mantissa) -
((sizeof(UInt128) - sizeof(StorageType)) * CHAR_BIT);
mantissa <<= clz;

int32_t exp2 =
Expand Down Expand Up @@ -276,9 +277,8 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
// Shifting to 65 bits for 80 bit floats and 113 bits for 128 bit floats
uint32_t msb =
static_cast<uint32_t>(final_approx_upper >> (FPBits::STORAGE_LEN - 1));
StorageType final_mantissa =
final_approx_upper >>
(msb + FPBits::STORAGE_LEN - (FPBits::FRACTION_LEN + 3));
UInt128 final_mantissa = final_approx_upper >> (msb + FPBits::STORAGE_LEN -
(FPBits::FRACTION_LEN + 3));
exp2 -= static_cast<uint32_t>(1 ^ msb); // same as !msb

if (round == RoundDirection::Nearest) {
Expand Down Expand Up @@ -315,7 +315,7 @@ eisel_lemire<long double>(ExpandedFloat<long double> init_num,
}

ExpandedFloat<long double> output;
output.mantissa = final_mantissa;
output.mantissa = static_cast<StorageType>(final_mantissa);
output.exponent = exp2;
return output;
}
Expand Down Expand Up @@ -558,7 +558,7 @@ clinger_fast_path(ExpandedFloat<T> init_num,

FPBits result;
T float_mantissa;
if constexpr (cpp::is_same_v<StorageType, UInt<128>>) {
if constexpr (is_big_int_v<StorageType> || sizeof(T) > sizeof(uint64_t)) {
float_mantissa =
(static_cast<T>(uint64_t(mantissa >> 64)) * static_cast<T>(0x1.0p64)) +
static_cast<T>(uint64_t(mantissa));
Expand Down
2 changes: 1 addition & 1 deletion libc/test/UnitTest/LibcTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ cpp::enable_if_t<(cpp::is_integral_v<T> && (sizeof(T) > sizeof(uint64_t))) ||
is_big_int_v<T>,
cpp::string>
describeValue(T Value) {
static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt");
const IntegerToString<T, radix::Hex::WithPrefix> buffer(Value);
return buffer.view();
}
Expand Down Expand Up @@ -242,6 +241,7 @@ TEST_SPECIALIZATION(__uint128_t);

TEST_SPECIALIZATION(LIBC_NAMESPACE::Int<128>);

TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<96>);
TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<128>);
TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<192>);
TEST_SPECIALIZATION(LIBC_NAMESPACE::UInt<256>);
Expand Down
Loading
Loading