diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -83,6 +83,10 @@ return uint32_t(uint64_t(*this)); } + constexpr explicit operator int32_t() const { + return int32_t(uint64_t(*this)); + } + constexpr explicit operator uint16_t() const { return uint16_t(uint64_t(*this)); } @@ -91,6 +95,8 @@ return uint8_t(uint64_t(*this)); } + constexpr explicit operator long double() const { return uint64_t(*this); } + constexpr explicit operator bool() const { return !is_zero(); } UInt &operator=(const UInt &other) = default; @@ -108,7 +114,7 @@ constexpr uint64_t add(const UInt &x) { SumCarry s{0, 0}; for (size_t i = 0; i < WORDCOUNT; ++i) { - s = add_with_carry(val[i], x.val[i], s.carry); + s = add_with_carry_const(val[i], x.val[i], s.carry); val[i] = s.sum; } return s.carry; @@ -146,7 +152,7 @@ constexpr uint64_t sub(const UInt &x) { DiffBorrow d{0, 0}; for (size_t i = 0; i < WORDCOUNT; ++i) { - d = sub_with_borrow(val[i], x.val[i], d.borrow); + d = sub_with_borrow_const(val[i], x.val[i], d.borrow); val[i] = d.diff; } return d.borrow; diff --git a/libc/src/__support/builtin_wrappers.h b/libc/src/__support/builtin_wrappers.h --- a/libc/src/__support/builtin_wrappers.h +++ b/libc/src/__support/builtin_wrappers.h @@ -31,14 +31,16 @@ } template LIBC_INLINE int clz(T val); -template <> LIBC_INLINE int clz(unsigned int val) { +template <> LIBC_INLINE constexpr int clz(unsigned int val) { return __builtin_clz(val); } -template <> LIBC_INLINE int clz(unsigned long int val) { +template <> +LIBC_INLINE constexpr int clz(unsigned long int val) { return __builtin_clzl(val); } template <> -LIBC_INLINE int clz(unsigned long long int val) { +LIBC_INLINE constexpr int +clz(unsigned long long int val) { return __builtin_clzll(val); } @@ -67,7 +69,7 @@ return __internal::correct_zero(val, __internal::clz(val)); } -template LIBC_INLINE int unsafe_clz(T val) { +template LIBC_INLINE constexpr int unsafe_clz(T val) { return __internal::clz(val); } diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h --- a/libc/test/src/math/FmaTest.h +++ b/libc/test/src/math/FmaTest.h @@ -83,7 +83,8 @@ void test_normal_range(Func func) { constexpr UIntType COUNT = 1000001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; v += STEP, w -= STEP) { diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h --- a/libc/test/src/math/HypotTest.h +++ b/libc/test/src/math/HypotTest.h @@ -85,7 +85,8 @@ void test_normal_range(Func func) { constexpr UIntType COUNT = 100001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (int signs = 0; signs < 4; ++signs) { for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h --- a/libc/test/src/math/ILogbTest.h +++ b/libc/test/src/math/ILogbTest.h @@ -77,7 +77,8 @@ using UIntType = typename FPBits::UIntType; constexpr UIntType COUNT = 1000001; constexpr UIntType STEP = - (FPBits::MAX_SUBNORMAL - FPBits::MIN_SUBNORMAL) / COUNT; + (UIntType(FPBits::MAX_SUBNORMAL) - UIntType(FPBits::MIN_SUBNORMAL)) / + COUNT; for (UIntType v = FPBits::MIN_SUBNORMAL; v <= FPBits::MAX_SUBNORMAL; v += STEP) { T x = T(FPBits(v)); @@ -95,7 +96,8 @@ using FPBits = __llvm_libc::fputil::FPBits; using UIntType = typename FPBits::UIntType; constexpr UIntType COUNT = 1000001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (UIntType v = FPBits::MIN_NORMAL; v <= FPBits::MAX_NORMAL; v += STEP) { T x = T(FPBits(v)); if (isnan(x) || isinf(x) || x == 0.0) diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h --- a/libc/test/src/math/LdExpTest.h +++ b/libc/test/src/math/LdExpTest.h @@ -70,7 +70,7 @@ void testUnderflowToZeroOnNormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + MANTISSA_WIDTH; + int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; @@ -83,7 +83,7 @@ void testUnderflowToZeroOnSubnormal(LdExpFunc func) { // In this test, we pass a normal nubmer to func and expect zero // to be returned due to underflow. - int32_t base_exponent = FPBits::EXPONENT_BIAS + MANTISSA_WIDTH; + int32_t base_exponent = FPBits::EXPONENT_BIAS + int32_t(MANTISSA_WIDTH); int32_t exp_array[] = {base_exponent + 5, base_exponent + 4, base_exponent + 3, base_exponent + 2, base_exponent + 1}; @@ -105,13 +105,14 @@ for (T x : val_array) { // We compare the result of ldexp with the result // of the native multiplication/division instruction. - ASSERT_FP_EQ(func(x, exp), x * (UIntType(1) << exp)); - ASSERT_FP_EQ(func(x, -exp), x / (UIntType(1) << exp)); + ASSERT_FP_EQ(func(x, exp), x * static_cast(UIntType(1) << exp)); + ASSERT_FP_EQ(func(x, -exp), x / static_cast(UIntType(1) << exp)); } } // Normal which trigger mantissa overflow. - T x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, 2 * NormalFloat::ONE - 1, 0); + T x = NormalFloat(-FPBits::EXPONENT_BIAS + 1, + 2 * int32_t(NormalFloat::ONE) - 1, 0); ASSERT_FP_EQ(func(x, -1), x / 2); ASSERT_FP_EQ(func(-x, -1), -x / 2); diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -109,7 +109,8 @@ void testNormalRange(RIntFunc func) { constexpr UIntType COUNT = 1000001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (UIntType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; i += STEP) { T x = T(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h --- a/libc/test/src/math/RemQuoTest.h +++ b/libc/test/src/math/RemQuoTest.h @@ -111,7 +111,8 @@ void testNormalRange(RemQuoFunc func) { constexpr UIntType COUNT = 1000001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (UIntType v = FPBits::MIN_NORMAL, w = FPBits::MAX_NORMAL; v <= FPBits::MAX_NORMAL && w >= FPBits::MIN_NORMAL; v += STEP, w -= STEP) { diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -259,7 +259,8 @@ return; constexpr UIntType COUNT = 1000001; - constexpr UIntType STEP = (FPBits::MAX_NORMAL - FPBits::MIN_NORMAL) / COUNT; + constexpr UIntType STEP = + (UIntType(FPBits::MAX_NORMAL) - UIntType(FPBits::MIN_NORMAL)) / COUNT; for (UIntType i = FPBits::MIN_NORMAL; i <= FPBits::MAX_NORMAL; i += STEP) { F x = F(FPBits(i)); // In normal range on x86 platforms, the long double implicit 1 bit can be