Loading libc/src/__support/FPUtil/FPBits.h +20 −18 Original line number Diff line number Diff line Loading @@ -51,23 +51,23 @@ template <typename T> struct FPBits { UIntType bits; LIBC_INLINE void set_mantissa(UIntType mantVal) { LIBC_INLINE constexpr void set_mantissa(UIntType mantVal) { mantVal &= (FloatProp::MANTISSA_MASK); bits &= ~(FloatProp::MANTISSA_MASK); bits |= mantVal; } LIBC_INLINE UIntType get_mantissa() const { LIBC_INLINE constexpr UIntType get_mantissa() const { return bits & FloatProp::MANTISSA_MASK; } LIBC_INLINE void set_unbiased_exponent(UIntType expVal) { LIBC_INLINE constexpr void set_unbiased_exponent(UIntType expVal) { expVal = (expVal << (FloatProp::MANTISSA_WIDTH)) & FloatProp::EXPONENT_MASK; bits &= ~(FloatProp::EXPONENT_MASK); bits |= expVal; } LIBC_INLINE uint16_t get_unbiased_exponent() const { LIBC_INLINE constexpr uint16_t get_unbiased_exponent() const { return uint16_t((bits & FloatProp::EXPONENT_MASK) >> (FloatProp::MANTISSA_WIDTH)); } Loading @@ -81,13 +81,13 @@ template <typename T> struct FPBits { (FloatProp::MANTISSA_MASK & bits); } LIBC_INLINE void set_sign(bool signVal) { LIBC_INLINE constexpr void set_sign(bool signVal) { bits |= FloatProp::SIGN_MASK; if (!signVal) bits -= FloatProp::SIGN_MASK; } LIBC_INLINE bool get_sign() const { LIBC_INLINE constexpr bool get_sign() const { return (bits & FloatProp::SIGN_MASK) != 0; } Loading Loading @@ -118,13 +118,15 @@ template <typename T> struct FPBits { LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast<T>(bits); } LIBC_INLINE void set_val(T value) { bits = cpp::bit_cast<UIntType>(value); } LIBC_INLINE constexpr void set_val(T value) { bits = cpp::bit_cast<UIntType>(value); } LIBC_INLINE explicit operator T() const { return get_val(); } LIBC_INLINE constexpr explicit operator T() const { return get_val(); } LIBC_INLINE UIntType uintval() const { return bits; } LIBC_INLINE constexpr UIntType uintval() const { return bits; } LIBC_INLINE int get_exponent() const { LIBC_INLINE constexpr int get_exponent() const { return int(get_unbiased_exponent()) - EXPONENT_BIAS; } Loading @@ -134,7 +136,7 @@ template <typename T> struct FPBits { // values are calculated from the exponent, since just subtracting the bias // will give a slightly incorrect result. Additionally, zero has an exponent // of zero, and that should actually be treated as zero. LIBC_INLINE int get_explicit_exponent() const { LIBC_INLINE constexpr int get_explicit_exponent() const { const int unbiased_exp = int(get_unbiased_exponent()); if (is_zero()) { return 0; Loading @@ -145,25 +147,25 @@ template <typename T> struct FPBits { } } LIBC_INLINE bool is_zero() const { LIBC_INLINE constexpr bool is_zero() const { // Remove sign bit by shift return (bits << 1) == 0; } LIBC_INLINE bool is_inf() const { LIBC_INLINE constexpr bool is_inf() const { return (bits & FloatProp::EXP_MANT_MASK) == FloatProp::EXPONENT_MASK; } LIBC_INLINE bool is_nan() const { LIBC_INLINE constexpr bool is_nan() const { return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK; } LIBC_INLINE bool is_quiet_nan() const { LIBC_INLINE constexpr bool is_quiet_nan() const { return (bits & FloatProp::EXP_MANT_MASK) == (FloatProp::EXPONENT_MASK | FloatProp::QUIET_NAN_MASK); } LIBC_INLINE bool is_inf_or_nan() const { LIBC_INLINE constexpr bool is_inf_or_nan() const { return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK; } Loading Loading @@ -226,8 +228,8 @@ template <typename T> struct FPBits { return result; } LIBC_INLINE static FPBits<T> create_value(bool sign, UIntType unbiased_exp, UIntType mantissa) { LIBC_INLINE static constexpr FPBits<T> create_value(bool sign, UIntType unbiased_exp, UIntType mantissa) { FPBits<T> result; result.set_sign(sign); result.set_unbiased_exponent(unbiased_exp); Loading libc/test/UnitTest/FPMatcher.h +10 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,16 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) { return FPMatcher<T, C>(expectedValue); } template <typename T> struct FPTest : public Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using UIntType = typename FPBits::UIntType; static constexpr T zero = T(FPBits::zero()); static constexpr T neg_zero = T(FPBits::neg_zero()); static constexpr T aNaN = T(FPBits::build_quiet_nan(1)); static constexpr T inf = T(FPBits::inf()); static constexpr T neg_inf = T(FPBits::neg_inf()); }; } // namespace testing } // namespace LIBC_NAMESPACE Loading libc/test/src/math/acosf_test.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ #include <errno.h> #include <stdint.h> using FPBits = LIBC_NAMESPACE::fputil::FPBits<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>; TEST(LlvmLibcAcosfTest, SpecialNumbers) { TEST_F(LlvmLibcAcosfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN)); Loading @@ -45,7 +43,7 @@ TEST(LlvmLibcAcosfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAcosfTest, InFloatRange) { TEST_F(LlvmLibcAcosfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { Loading @@ -57,7 +55,7 @@ TEST(LlvmLibcAcosfTest, InFloatRange) { } } TEST(LlvmLibcAcosfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAcosfTest, SpecificBitPatterns) { constexpr int N = 13; constexpr uint32_t INPUTS[N] = { 0x3f000000, // x = 0.5f Loading libc/test/src/math/acoshf_test.cpp +6 −8 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ #include <errno.h> #include <stdint.h> using FPBits_t = LIBC_NAMESPACE::fputil::FPBits<float>; using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) TEST(LlvmLibcAcoshfTest, SpecialNumbers) { TEST_F(LlvmLibcAcoshfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf(aNaN)); Loading @@ -42,11 +40,11 @@ TEST(LlvmLibcAcoshfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAcoshfTest, InFloatRange) { TEST_F(LlvmLibcAcoshfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { float x = float(FPBits_t(v)); float x = float(FPBits(v)); if (isnan(x) || isinf(x)) continue; ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x, Loading @@ -54,7 +52,7 @@ TEST(LlvmLibcAcoshfTest, InFloatRange) { } } TEST(LlvmLibcAcoshfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAcoshfTest, SpecificBitPatterns) { constexpr int N = 12; constexpr uint32_t INPUTS[N] = { 0x3f800000, // x = 1.0f Loading @@ -72,7 +70,7 @@ TEST(LlvmLibcAcoshfTest, SpecificBitPatterns) { }; for (int i = 0; i < N; ++i) { float x = float(FPBits_t(INPUTS[i])); float x = float(FPBits(INPUTS[i])); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x, LIBC_NAMESPACE::acoshf(x), 0.5); } Loading libc/test/src/math/asinf_test.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -18,13 +18,11 @@ #include <errno.h> #include <stdint.h> using FPBits = LIBC_NAMESPACE::fputil::FPBits<float>; using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) TEST(LlvmLibcAsinfTest, SpecialNumbers) { TEST_F(LlvmLibcAsinfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinf(aNaN)); Loading @@ -43,7 +41,7 @@ TEST(LlvmLibcAsinfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAsinfTest, InFloatRange) { TEST_F(LlvmLibcAsinfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { Loading @@ -55,7 +53,7 @@ TEST(LlvmLibcAsinfTest, InFloatRange) { } } TEST(LlvmLibcAsinfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAsinfTest, SpecificBitPatterns) { constexpr int N = 11; constexpr uint32_t INPUTS[N] = { 0x3f000000, // x = 0.5f Loading Loading
libc/src/__support/FPUtil/FPBits.h +20 −18 Original line number Diff line number Diff line Loading @@ -51,23 +51,23 @@ template <typename T> struct FPBits { UIntType bits; LIBC_INLINE void set_mantissa(UIntType mantVal) { LIBC_INLINE constexpr void set_mantissa(UIntType mantVal) { mantVal &= (FloatProp::MANTISSA_MASK); bits &= ~(FloatProp::MANTISSA_MASK); bits |= mantVal; } LIBC_INLINE UIntType get_mantissa() const { LIBC_INLINE constexpr UIntType get_mantissa() const { return bits & FloatProp::MANTISSA_MASK; } LIBC_INLINE void set_unbiased_exponent(UIntType expVal) { LIBC_INLINE constexpr void set_unbiased_exponent(UIntType expVal) { expVal = (expVal << (FloatProp::MANTISSA_WIDTH)) & FloatProp::EXPONENT_MASK; bits &= ~(FloatProp::EXPONENT_MASK); bits |= expVal; } LIBC_INLINE uint16_t get_unbiased_exponent() const { LIBC_INLINE constexpr uint16_t get_unbiased_exponent() const { return uint16_t((bits & FloatProp::EXPONENT_MASK) >> (FloatProp::MANTISSA_WIDTH)); } Loading @@ -81,13 +81,13 @@ template <typename T> struct FPBits { (FloatProp::MANTISSA_MASK & bits); } LIBC_INLINE void set_sign(bool signVal) { LIBC_INLINE constexpr void set_sign(bool signVal) { bits |= FloatProp::SIGN_MASK; if (!signVal) bits -= FloatProp::SIGN_MASK; } LIBC_INLINE bool get_sign() const { LIBC_INLINE constexpr bool get_sign() const { return (bits & FloatProp::SIGN_MASK) != 0; } Loading Loading @@ -118,13 +118,15 @@ template <typename T> struct FPBits { LIBC_INLINE constexpr T get_val() const { return cpp::bit_cast<T>(bits); } LIBC_INLINE void set_val(T value) { bits = cpp::bit_cast<UIntType>(value); } LIBC_INLINE constexpr void set_val(T value) { bits = cpp::bit_cast<UIntType>(value); } LIBC_INLINE explicit operator T() const { return get_val(); } LIBC_INLINE constexpr explicit operator T() const { return get_val(); } LIBC_INLINE UIntType uintval() const { return bits; } LIBC_INLINE constexpr UIntType uintval() const { return bits; } LIBC_INLINE int get_exponent() const { LIBC_INLINE constexpr int get_exponent() const { return int(get_unbiased_exponent()) - EXPONENT_BIAS; } Loading @@ -134,7 +136,7 @@ template <typename T> struct FPBits { // values are calculated from the exponent, since just subtracting the bias // will give a slightly incorrect result. Additionally, zero has an exponent // of zero, and that should actually be treated as zero. LIBC_INLINE int get_explicit_exponent() const { LIBC_INLINE constexpr int get_explicit_exponent() const { const int unbiased_exp = int(get_unbiased_exponent()); if (is_zero()) { return 0; Loading @@ -145,25 +147,25 @@ template <typename T> struct FPBits { } } LIBC_INLINE bool is_zero() const { LIBC_INLINE constexpr bool is_zero() const { // Remove sign bit by shift return (bits << 1) == 0; } LIBC_INLINE bool is_inf() const { LIBC_INLINE constexpr bool is_inf() const { return (bits & FloatProp::EXP_MANT_MASK) == FloatProp::EXPONENT_MASK; } LIBC_INLINE bool is_nan() const { LIBC_INLINE constexpr bool is_nan() const { return (bits & FloatProp::EXP_MANT_MASK) > FloatProp::EXPONENT_MASK; } LIBC_INLINE bool is_quiet_nan() const { LIBC_INLINE constexpr bool is_quiet_nan() const { return (bits & FloatProp::EXP_MANT_MASK) == (FloatProp::EXPONENT_MASK | FloatProp::QUIET_NAN_MASK); } LIBC_INLINE bool is_inf_or_nan() const { LIBC_INLINE constexpr bool is_inf_or_nan() const { return (bits & FloatProp::EXPONENT_MASK) == FloatProp::EXPONENT_MASK; } Loading Loading @@ -226,8 +228,8 @@ template <typename T> struct FPBits { return result; } LIBC_INLINE static FPBits<T> create_value(bool sign, UIntType unbiased_exp, UIntType mantissa) { LIBC_INLINE static constexpr FPBits<T> create_value(bool sign, UIntType unbiased_exp, UIntType mantissa) { FPBits<T> result; result.set_sign(sign); result.set_unbiased_exponent(unbiased_exp); Loading
libc/test/UnitTest/FPMatcher.h +10 −0 Original line number Diff line number Diff line Loading @@ -59,6 +59,16 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) { return FPMatcher<T, C>(expectedValue); } template <typename T> struct FPTest : public Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; using UIntType = typename FPBits::UIntType; static constexpr T zero = T(FPBits::zero()); static constexpr T neg_zero = T(FPBits::neg_zero()); static constexpr T aNaN = T(FPBits::build_quiet_nan(1)); static constexpr T inf = T(FPBits::inf()); static constexpr T neg_inf = T(FPBits::neg_inf()); }; } // namespace testing } // namespace LIBC_NAMESPACE Loading
libc/test/src/math/acosf_test.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ #include <errno.h> #include <stdint.h> using FPBits = LIBC_NAMESPACE::fputil::FPBits<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) using LlvmLibcAcosfTest = LIBC_NAMESPACE::testing::FPTest<float>; TEST(LlvmLibcAcosfTest, SpecialNumbers) { TEST_F(LlvmLibcAcosfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acosf(aNaN)); Loading @@ -45,7 +43,7 @@ TEST(LlvmLibcAcosfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAcosfTest, InFloatRange) { TEST_F(LlvmLibcAcosfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { Loading @@ -57,7 +55,7 @@ TEST(LlvmLibcAcosfTest, InFloatRange) { } } TEST(LlvmLibcAcosfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAcosfTest, SpecificBitPatterns) { constexpr int N = 13; constexpr uint32_t INPUTS[N] = { 0x3f000000, // x = 0.5f Loading
libc/test/src/math/acoshf_test.cpp +6 −8 Original line number Diff line number Diff line Loading @@ -17,13 +17,11 @@ #include <errno.h> #include <stdint.h> using FPBits_t = LIBC_NAMESPACE::fputil::FPBits<float>; using LlvmLibcAcoshfTest = LIBC_NAMESPACE::testing::FPTest<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) TEST(LlvmLibcAcoshfTest, SpecialNumbers) { TEST_F(LlvmLibcAcoshfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf(aNaN)); Loading @@ -42,11 +40,11 @@ TEST(LlvmLibcAcoshfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAcoshfTest, InFloatRange) { TEST_F(LlvmLibcAcoshfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { float x = float(FPBits_t(v)); float x = float(FPBits(v)); if (isnan(x) || isinf(x)) continue; ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x, Loading @@ -54,7 +52,7 @@ TEST(LlvmLibcAcoshfTest, InFloatRange) { } } TEST(LlvmLibcAcoshfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAcoshfTest, SpecificBitPatterns) { constexpr int N = 12; constexpr uint32_t INPUTS[N] = { 0x3f800000, // x = 1.0f Loading @@ -72,7 +70,7 @@ TEST(LlvmLibcAcoshfTest, SpecificBitPatterns) { }; for (int i = 0; i < N; ++i) { float x = float(FPBits_t(INPUTS[i])); float x = float(FPBits(INPUTS[i])); EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x, LIBC_NAMESPACE::acoshf(x), 0.5); } Loading
libc/test/src/math/asinf_test.cpp +4 −6 Original line number Diff line number Diff line Loading @@ -18,13 +18,11 @@ #include <errno.h> #include <stdint.h> using FPBits = LIBC_NAMESPACE::fputil::FPBits<float>; using LlvmLibcAsinfTest = LIBC_NAMESPACE::testing::FPTest<float>; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; DECLARE_SPECIAL_CONSTANTS(float) TEST(LlvmLibcAsinfTest, SpecialNumbers) { TEST_F(LlvmLibcAsinfTest, SpecialNumbers) { libc_errno = 0; EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::asinf(aNaN)); Loading @@ -43,7 +41,7 @@ TEST(LlvmLibcAsinfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); } TEST(LlvmLibcAsinfTest, InFloatRange) { TEST_F(LlvmLibcAsinfTest, InFloatRange) { constexpr uint32_t COUNT = 100'000; constexpr uint32_t STEP = UINT32_MAX / COUNT; for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { Loading @@ -55,7 +53,7 @@ TEST(LlvmLibcAsinfTest, InFloatRange) { } } TEST(LlvmLibcAsinfTest, SpecificBitPatterns) { TEST_F(LlvmLibcAsinfTest, SpecificBitPatterns) { constexpr int N = 11; constexpr uint32_t INPUTS[N] = { 0x3f000000, // x = 0.5f Loading