[libc] Add Operator Overloads for Float80 (#214493) stacked on https://github.com/llvm/llvm-project/pull/214447 GitOrigin-RevId: 46c5d02a90f43d42139053c2ccdc46ceb1de59b9
diff --git a/src/__support/FPUtil/CMakeLists.txt b/src/__support/FPUtil/CMakeLists.txt index 96fbb6d..a32244e 100644 --- a/src/__support/FPUtil/CMakeLists.txt +++ b/src/__support/FPUtil/CMakeLists.txt
@@ -321,6 +321,7 @@ .cast .comparison_operations .dyadic_float + .float128 libc.hdr.stdint_proxy libc.src.__support.CPP.type_traits libc.src.__support.FPUtil.generic.add_sub
diff --git a/src/__support/FPUtil/float80.h b/src/__support/FPUtil/float80.h index 4529fe3..25c7ba9 100644 --- a/src/__support/FPUtil/float80.h +++ b/src/__support/FPUtil/float80.h
@@ -14,6 +14,7 @@ #include "src/__support/FPUtil/cast.h" #include "src/__support/FPUtil/comparison_operations.h" #include "src/__support/FPUtil/dyadic_float.h" +#include "src/__support/FPUtil/float128.h" #include "src/__support/FPUtil/generic/add_sub.h" #include "src/__support/FPUtil/generic/div.h" #include "src/__support/FPUtil/generic/mul.h" @@ -95,6 +96,58 @@ x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa()); return static_cast<T>(xd.as_mantissa_type()); } + + // unary operator + LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float80 operator-() const { + fputil::FPBits<Float80> result(*this); + result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS); + return result.get_val(); + } + + LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const { + return fputil::generic::add<Float80>(fputil::cast<Float128>(*this), + fputil::cast<Float128>(other)); + } + + LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const { + return fputil::generic::sub<Float80>(fputil::cast<Float128>(*this), + fputil::cast<Float128>(other)); + } + + LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const { + return fputil::generic::mul<Float80>(fputil::cast<Float128>(*this), + fputil::cast<Float128>(other)); + } + + LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const { + return fputil::generic::div<Float80>(fputil::cast<Float128>(*this), + fputil::cast<Float128>(other)); + } + + // Comparison operators + LIBC_INLINE constexpr bool operator==(const Float80 &other) const { + return fputil::equals(*this, other); + } + + LIBC_INLINE constexpr bool operator!=(const Float80 &other) const { + return !fputil::equals(*this, other); + } + + LIBC_INLINE constexpr bool operator<(const Float80 &other) const { + return fputil::less_than(*this, other); + } + + LIBC_INLINE constexpr bool operator<=(const Float80 &other) const { + return fputil::less_than_or_equals(*this, other); + } + + LIBC_INLINE constexpr bool operator>(const Float80 &other) const { + return fputil::greater_than(*this, other); + } + + LIBC_INLINE constexpr bool operator>=(const Float80 &other) const { + return fputil::greater_than_or_equals(*this, other); + } }; } // namespace fputil
diff --git a/test/src/__support/FPUtil/float80_test.cpp b/test/src/__support/FPUtil/float80_test.cpp index 72c1155..c59be71 100644 --- a/test/src/__support/FPUtil/float80_test.cpp +++ b/test/src/__support/FPUtil/float80_test.cpp
@@ -16,10 +16,53 @@ using LIBC_NAMESPACE::fputil::Float80; using FPBits = LIBC_NAMESPACE::fputil::FPBits<Float80>; +TEST(LlvmLibcFloat80Test, Operators) { + Float80 a(1.0f), b(1.0f), c(2.0f), d(3.0f), pa(1.0f), na(-1.0f); + + // comparison operators + ASSERT_TRUE(a == b); + ASSERT_TRUE(a == Float80(1.0)); + ASSERT_TRUE(a != c); + ASSERT_TRUE(b != c); + ASSERT_TRUE(c > b); + ASSERT_TRUE(a >= b); + ASSERT_TRUE(b <= c); + ASSERT_TRUE(a < c); + + // Unary operators + ASSERT_TRUE(-pa == na); + ASSERT_TRUE(-(-pa) == pa); + + // Binary operators + ASSERT_TRUE((a + b) == c); + ASSERT_TRUE((a - b) == Float80(0.0f)); + ASSERT_TRUE((c * d) == Float80(6.0f)); + ASSERT_TRUE((Float80(6.0f) / d) == Float80(2.0f)); +} + +TEST(LlvmLibcFloat80Test, SpecialValues) { + Float80 inf = FPBits::inf(Sign::POS).get_val(); + Float80 neg_inf = FPBits::inf(Sign::NEG).get_val(); + Float80 nan = FPBits::quiet_nan().get_val(); + + // checking operators with special values + ASSERT_TRUE(Float80(0.0f) == Float80(-0.0f)); // +0.0 == -0.0 is true + ASSERT_TRUE(Float80(0.0f) == Float80(0.0f)); + ASSERT_TRUE(inf == inf); + ASSERT_TRUE(-inf == neg_inf); + ASSERT_TRUE((inf + Float80(1.0f)) == inf); + ASSERT_TRUE(inf + inf == inf); + ASSERT_TRUE(nan != nan); + ASSERT_TRUE(!(nan == nan)); + ASSERT_TRUE(nan != Float80(0.0f)); +} + TEST(LlvmLibcFloat80Test, IntegerConversion) { // Float80 to Integer conversion test ASSERT_EQ(static_cast<int>(Float80(0.0f)), 0); + ASSERT_EQ(static_cast<int>(Float80(-0.0f)), 0); ASSERT_EQ(static_cast<int>(Float80(1.0f)), 1); + ASSERT_EQ(static_cast<int>(Float80(-1.0f)), -1); ASSERT_EQ(static_cast<long long>(Float80(1000000000.0)), static_cast<long long>(1000000000)); ASSERT_EQ(static_cast<unsigned>(Float80(7.0f)), 7U);