[libc] [llvm] [reland][libc][NFC] Refactor FPBits and remove LongDoubleBits specialization (PR #78447)
Clement Courbet via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 17 06:48:12 PST 2024
================
@@ -171,68 +171,98 @@ struct FPRepBase : public internal::FPLayout<fp_type> {
return StorageType(1) << position;
}
+ template <typename T> struct Opaque {
+ using value_type = T;
+ LIBC_INLINE constexpr explicit Opaque(T value) : value(value) {}
+ LIBC_INLINE constexpr Opaque(const Opaque &value) = default;
+
+ LIBC_INLINE constexpr explicit operator T() const { return value; }
+
+ private:
+ T value;
+ };
+
// An opaque type to store a floating point exponent.
// We define special values but it is valid to create arbitrary values as long
// as they are in the range [MIN, MAX].
- enum class Exponent : int32_t {
- MIN = 1 - EXP_BIAS,
- ZERO = 0,
- MAX = EXP_BIAS,
+ struct Exponent : public Opaque<int32_t> {
+ using UP = Opaque<int32_t>;
+ using UP::UP;
+ LIBC_INLINE
+ static constexpr auto MIN() { return Exponent{1 - EXP_BIAS}; }
+ LIBC_INLINE static constexpr auto ZERO() { return Exponent{0}; }
+ LIBC_INLINE static constexpr auto MAX() { return Exponent{EXP_BIAS}; }
};
// An opaque type to store a floating point biased exponent.
// We define special values but it is valid to create arbitrary values as long
// as they are in the range [BITS_ALL_ZEROES, BITS_ALL_ONES].
// Values greater than BITS_ALL_ONES are truncated.
- enum class BiasedExponent : uint32_t {
+ struct BiasedExponent : public Opaque<uint32_t> {
+ using UP = Opaque<uint32_t>;
+ using UP::UP;
+
+ LIBC_INLINE constexpr BiasedExponent(Exponent exp)
+ : UP(static_cast<int32_t>(exp) + EXP_BIAS) {}
// The exponent value for denormal numbers.
- BITS_ALL_ZEROES = 0,
+ LIBC_INLINE static constexpr auto BITS_ALL_ZEROES() {
+ return BiasedExponent{uint32_t(0)};
+ }
// The exponent value for infinity.
- BITS_ALL_ONES = 2 * EXP_BIAS + 1,
+ LIBC_INLINE static constexpr auto BITS_ALL_ONES() {
+ return BiasedExponent{uint32_t(2 * EXP_BIAS + 1)};
+ }
};
- LIBC_INLINE static constexpr BiasedExponent biased(Exponent value) {
- return static_cast<BiasedExponent>(static_cast<int32_t>(value) + EXP_BIAS);
- }
-
// An opaque type to store a floating point significand.
// We define special values but it is valid to create arbitrary values as long
// as they are in the range [BITS_ALL_ZEROES, BITS_ALL_ONES].
// Note that the semantics of the Significand are implementation dependent.
// Values greater than BITS_ALL_ONES are truncated.
- enum class Significand : StorageType {
- ZERO = 0,
- LSB = 1,
- MSB = bit_at(SIG_LEN - 1),
+ struct Significand : public Opaque<StorageType> {
+ using UP = Opaque<StorageType>;
+ using UP::UP;
+
+ LIBC_INLINE static constexpr auto ZERO() {
+ return Significand{StorageType(0)};
+ }
+ LIBC_INLINE static constexpr auto LSB() {
+ return Significand{StorageType(1)};
+ }
+ LIBC_INLINE static constexpr auto MSB() {
+ return Significand{StorageType(bit_at(SIG_LEN - 1))};
+ }
// Aliases
- BITS_ALL_ZEROES = ZERO,
- BITS_ALL_ONES = SIG_MASK,
+ LIBC_INLINE static constexpr auto BITS_ALL_ZEROES() { return ZERO(); }
+ LIBC_INLINE static constexpr auto BITS_ALL_ONES() {
+ return Significand{SIG_MASK};
+ }
};
- template <typename T>
- LIBC_INLINE static constexpr auto storage_cast(T value) {
- return static_cast<StorageType>(value);
+ template <typename To, typename T>
+ LIBC_INLINE static constexpr To as(Opaque<T> opaque) {
+ return To(static_cast<T>(opaque));
}
LIBC_INLINE friend constexpr Significand operator|(const Significand a,
const Significand b) {
- return Significand{storage_cast(storage_cast(a) | storage_cast(b))};
+ return Significand{StorageType(as<StorageType>(a) | as<StorageType>(b))};
}
LIBC_INLINE friend constexpr Significand operator^(const Significand a,
const Significand b) {
- return Significand{storage_cast(storage_cast(a) ^ storage_cast(b))};
+ return Significand{StorageType(as<StorageType>(a) ^ as<StorageType>(b))};
}
LIBC_INLINE friend constexpr Significand operator>>(const Significand a,
int shift) {
- return Significand{storage_cast(storage_cast(a) >> shift)};
+ return Significand{StorageType(as<StorageType>(a) >> shift)};
}
----------------
legrosbuffle wrote:
Operations can now be friend function in `Significand`.
https://github.com/llvm/llvm-project/pull/78447
More information about the llvm-commits
mailing list