diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index bd814a080c4f87..013627788940d8 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -146,6 +146,15 @@ add_header_library( libc.src.errno.errno ) +add_header_library( + integer_literals + HDRS + integer_literals.h + DEPENDS + .uint128 + libc.src.__support.CPP.limits +) + add_header_library( integer_operations HDRS diff --git a/libc/src/__support/integer_literals.h b/libc/src/__support/integer_literals.h new file mode 100644 index 00000000000000..c8e965c1a03a05 --- /dev/null +++ b/libc/src/__support/integer_literals.h @@ -0,0 +1,173 @@ +//===-- User literal for unsigned integers ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This set of user defined literals allows uniform constructions of constants +// up to 256 bits and also help with unit tests (EXPECT_EQ requires the same +// type for LHS and RHS). +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H +#define LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H + +#include "src/__support/CPP/limits.h" // CHAR_BIT +#include "src/__support/UInt128.h" // UInt128 +#include "src/__support/macros/attributes.h" // LIBC_INLINE +#include // size_t +#include // uintxx_t + +namespace LIBC_NAMESPACE { + +LIBC_INLINE constexpr uint8_t operator""_u8(unsigned long long value) { + return value; +} + +LIBC_INLINE constexpr uint16_t operator""_u16(unsigned long long value) { + return value; +} + +LIBC_INLINE constexpr uint32_t operator""_u32(unsigned long long value) { + return value; +} + +LIBC_INLINE constexpr uint64_t operator""_u64(unsigned long long value) { + return value; +} + +namespace internal { + +// Creates a T by reading digits from an array. +template +LIBC_INLINE constexpr T accumulate(int base, const uint8_t *digits, + size_t size) { + T value{}; + for (; size; ++digits, --size) { + value *= base; + value += *digits; + } + return value; +} + +// A static buffer to hold the digits for a T. +template struct DigitBuffer { + static_assert(base == 2 || base == 10 || base == 16); + // One character provides log2(base) bits. + // Base 2 and 16 provide exactly one and four bits per character respectively. + // For base 10, a character provides log2(10) ≈ 3.32... which we round to 3 + // for the purpose of buffer allocation. + LIBC_INLINE_VAR static constexpr size_t BITS_PER_DIGIT = base == 2 ? 1 + : base == 10 ? 3 + : base == 16 ? 4 + : 0; + LIBC_INLINE_VAR static constexpr size_t MAX_DIGITS = + sizeof(T) * CHAR_BIT / BITS_PER_DIGIT; + + uint8_t digits[MAX_DIGITS] = {}; + size_t size = 0; + + constexpr DigitBuffer(const char *str) { + for (; *str != '\0'; ++str) + push(*str); + } + + // Returns the digit for a particular character. + // Returns 255 if the character is invalid. + LIBC_INLINE static constexpr uint8_t get_digit_value(const char c) { + const auto to_lower = [](char c) { return c | 32; }; + const auto is_digit = [](char c) { return c >= '0' && c <= '9'; }; + const auto is_alpha = [](char c) { + return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); + }; + if (is_digit(c)) + return c - '0'; + if (base > 10 && is_alpha(c)) + return to_lower(c) - 'a' + 10; + return 255; + } + + // Adds a single character to this buffer. + LIBC_INLINE constexpr void push(char c) { + if (c == '\'') + return; // ' is valid but not taken into account. + const uint8_t value = get_digit_value(c); + if (value == 255 || size >= MAX_DIGITS) { + // During constant evaluation `__builtin_unreachable` will halt the + // compiler as it is not executable. This is preferable over `assert` that + // will only trigger in debug mode. Also we can't use `static_assert` + // because `value` and `size` are not constant. + __builtin_unreachable(); // invalid or too many characters. + } + digits[size] = value; + ++size; + } +}; + +// Generic implementation for native types (including __uint128_t or ExtInt +// where available). +template struct Parser { + template LIBC_INLINE static constexpr T parse(const char *str) { + const DigitBuffer buffer(str); + return accumulate(base, buffer.digits, buffer.size); + } +}; + +// Specialization for cpp::BigInt. +// Because this code runs at compile time we try to make it efficient. For +// binary and hexadecimal formats we read digits by chunks of 64 bits and +// produce the BigInt internal representation direcly. For decimal numbers we +// go the slow path and use slower BigInt arithmetic. +template +struct Parser> { + using UIntT = cpp::BigInt; + template static constexpr UIntT parse(const char *str) { + const DigitBuffer buffer(str); + if constexpr (base == 10) { + // Slow path, we sum and multiply BigInt for each digit. + return accumulate(base, buffer.digits, buffer.size); + } else { + // Fast path, we consume blocks of uint64_t and creates the BigInt's + // internal representation directly. + using U64ArrayT = cpp::array; + U64ArrayT array; + size_t size = buffer.size; + const uint8_t *digit_ptr = buffer.digits + size; + for (size_t i = 0; i < array.size(); ++i) { + constexpr size_t U64_DIGITS = DigitBuffer::MAX_DIGITS; + const size_t chunk = size > U64_DIGITS ? U64_DIGITS : size; + digit_ptr -= chunk; + size -= chunk; + array[i] = accumulate(base, digit_ptr, chunk); + } + return UIntT(array); + } + } +}; + +// Detects the base of the number and dispatches to the right implementation. +template +LIBC_INLINE constexpr T parse_with_prefix(const char *ptr) { + using P = Parser; + if (ptr[0] == '0' && ptr[1] == 'x') + return P::template parse<16>(ptr + 2); + else if (ptr[0] == '0' && ptr[1] == 'b') + return P::template parse<2>(ptr + 2); + else + return P::template parse<10>(ptr); +} + +} // namespace internal + +LIBC_INLINE constexpr UInt128 operator""_u128(const char *x) { + return internal::parse_with_prefix(x); +} + +LIBC_INLINE constexpr auto operator""_u256(const char *x) { + return internal::parse_with_prefix>(x); +} + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC___SUPPORT_INTEGER_LITERALS_H diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index a92e6da56096a1..231b01e0ee50a7 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -97,6 +97,17 @@ add_libc_test( libc.src.__support.CPP.optional ) +add_libc_test( + integer_literals_test + SUITE + libc-support-tests + SRCS + integer_literals_test.cpp + DEPENDS + libc.src.__support.integer_literals + libc.src.__support.CPP.optional +) + add_libc_test( fixedvector_test SUITE diff --git a/libc/test/src/__support/FPUtil/CMakeLists.txt b/libc/test/src/__support/FPUtil/CMakeLists.txt index 897434ceff6007..f1a027a514ba23 100644 --- a/libc/test/src/__support/FPUtil/CMakeLists.txt +++ b/libc/test/src/__support/FPUtil/CMakeLists.txt @@ -23,6 +23,7 @@ add_libc_test( DEPENDS libc.src.__support.FPUtil.fp_bits libc.src.__support.FPUtil.fpbits_str + libc.src.__support.integer_literals ) add_fp_unittest( diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp index b1c4b6691b6eec..1c8a1c5b9d4cee 100644 --- a/libc/test/src/__support/FPUtil/fpbits_test.cpp +++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp @@ -8,6 +8,7 @@ #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/fpbits_str.h" +#include "src/__support/integer_literals.h" #include "test/UnitTest/Test.h" using LIBC_NAMESPACE::fputil::FPBits; @@ -15,37 +16,42 @@ using LIBC_NAMESPACE::fputil::FPType; using LIBC_NAMESPACE::fputil::Sign; using LIBC_NAMESPACE::fputil::internal::FPRep; +using LIBC_NAMESPACE::operator""_u16; +using LIBC_NAMESPACE::operator""_u32; +using LIBC_NAMESPACE::operator""_u64; +using LIBC_NAMESPACE::operator""_u128; + TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) { using Rep = FPRep; using u16 = typename Rep::StorageType; - EXPECT_EQ(u16(0b0'00000'0000000000), u16(Rep::zero())); - EXPECT_EQ(u16(0b0'01111'0000000000), u16(Rep::one())); - EXPECT_EQ(u16(0b0'00000'0000000001), u16(Rep::min_subnormal())); - EXPECT_EQ(u16(0b0'00000'1111111111), u16(Rep::max_subnormal())); - EXPECT_EQ(u16(0b0'00001'0000000000), u16(Rep::min_normal())); - EXPECT_EQ(u16(0b0'11110'1111111111), u16(Rep::max_normal())); - EXPECT_EQ(u16(0b0'11111'0000000000), u16(Rep::inf())); - EXPECT_EQ(u16(0b0'11111'0100000000), u16(Rep::signaling_nan())); - EXPECT_EQ(u16(0b0'11111'1000000000), u16(Rep::quiet_nan())); + EXPECT_EQ(0b0'00000'0000000000_u16, u16(Rep::zero())); + EXPECT_EQ(0b0'01111'0000000000_u16, u16(Rep::one())); + EXPECT_EQ(0b0'00000'0000000001_u16, u16(Rep::min_subnormal())); + EXPECT_EQ(0b0'00000'1111111111_u16, u16(Rep::max_subnormal())); + EXPECT_EQ(0b0'00001'0000000000_u16, u16(Rep::min_normal())); + EXPECT_EQ(0b0'11110'1111111111_u16, u16(Rep::max_normal())); + EXPECT_EQ(0b0'11111'0000000000_u16, u16(Rep::inf())); + EXPECT_EQ(0b0'11111'0100000000_u16, u16(Rep::signaling_nan())); + EXPECT_EQ(0b0'11111'1000000000_u16, u16(Rep::quiet_nan())); } TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary32) { using Rep = FPRep; using u32 = typename Rep::StorageType; - EXPECT_EQ(u32(0b0'00000000'00000000000000000000000), u32(Rep::zero())); - EXPECT_EQ(u32(0b0'01111111'00000000000000000000000), u32(Rep::one())); - EXPECT_EQ(u32(0b0'00000000'00000000000000000000001), + EXPECT_EQ(0b0'00000000'00000000000000000000000_u32, u32(Rep::zero())); + EXPECT_EQ(0b0'01111111'00000000000000000000000_u32, u32(Rep::one())); + EXPECT_EQ(0b0'00000000'00000000000000000000001_u32, u32(Rep::min_subnormal())); - EXPECT_EQ(u32(0b0'00000000'11111111111111111111111), + EXPECT_EQ(0b0'00000000'11111111111111111111111_u32, u32(Rep::max_subnormal())); - EXPECT_EQ(u32(0b0'00000001'00000000000000000000000), u32(Rep::min_normal())); - EXPECT_EQ(u32(0b0'11111110'11111111111111111111111), u32(Rep::max_normal())); - EXPECT_EQ(u32(0b0'11111111'00000000000000000000000), u32(Rep::inf())); - EXPECT_EQ(u32(0b0'11111111'01000000000000000000000), + EXPECT_EQ(0b0'00000001'00000000000000000000000_u32, u32(Rep::min_normal())); + EXPECT_EQ(0b0'11111110'11111111111111111111111_u32, u32(Rep::max_normal())); + EXPECT_EQ(0b0'11111111'00000000000000000000000_u32, u32(Rep::inf())); + EXPECT_EQ(0b0'11111111'01000000000000000000000_u32, u32(Rep::signaling_nan())); - EXPECT_EQ(u32(0b0'11111111'10000000000000000000000), u32(Rep::quiet_nan())); + EXPECT_EQ(0b0'11111111'10000000000000000000000_u32, u32(Rep::quiet_nan())); } TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) { @@ -53,80 +59,63 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary64) { using u64 = typename Rep::StorageType; EXPECT_EQ( - u64(0b0'00000000000'0000000000000000000000000000000000000000000000000000), + 0b0'00000000000'0000000000000000000000000000000000000000000000000000_u64, u64(Rep::zero())); EXPECT_EQ( - u64(0b0'01111111111'0000000000000000000000000000000000000000000000000000), + 0b0'01111111111'0000000000000000000000000000000000000000000000000000_u64, u64(Rep::one())); EXPECT_EQ( - u64(0b0'00000000000'0000000000000000000000000000000000000000000000000001), + 0b0'00000000000'0000000000000000000000000000000000000000000000000001_u64, u64(Rep::min_subnormal())); EXPECT_EQ( - u64(0b0'00000000000'1111111111111111111111111111111111111111111111111111), + 0b0'00000000000'1111111111111111111111111111111111111111111111111111_u64, u64(Rep::max_subnormal())); EXPECT_EQ( - u64(0b0'00000000001'0000000000000000000000000000000000000000000000000000), + 0b0'00000000001'0000000000000000000000000000000000000000000000000000_u64, u64(Rep::min_normal())); EXPECT_EQ( - u64(0b0'11111111110'1111111111111111111111111111111111111111111111111111), + 0b0'11111111110'1111111111111111111111111111111111111111111111111111_u64, u64(Rep::max_normal())); EXPECT_EQ( - u64(0b0'11111111111'0000000000000000000000000000000000000000000000000000), + 0b0'11111111111'0000000000000000000000000000000000000000000000000000_u64, u64(Rep::inf())); EXPECT_EQ( - u64(0b0'11111111111'0100000000000000000000000000000000000000000000000000), + 0b0'11111111111'0100000000000000000000000000000000000000000000000000_u64, u64(Rep::signaling_nan())); EXPECT_EQ( - u64(0b0'11111111111'1000000000000000000000000000000000000000000000000000), + 0b0'11111111111'1000000000000000000000000000000000000000000000000000_u64, u64(Rep::quiet_nan())); } -static constexpr UInt128 u128(uint64_t hi, uint64_t lo) { -#if defined(__SIZEOF_INT128__) - return __uint128_t(hi) << 64 | __uint128_t(lo); -#else - return UInt128({lo, hi}); -#endif -} - TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) { using Rep = FPRep; EXPECT_EQ( - u128(0b0'000000000000000'000000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::zero())); EXPECT_EQ( - u128(0b0'011111111111111'000000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'011111111111111'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::one())); EXPECT_EQ( - u128(0b0'000000000000000'000000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000001), + 0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001_u128, UInt128(Rep::min_subnormal())); EXPECT_EQ( - u128(0b0'000000000000000'111111111111111111111111111111111111111111111111, - 0b1111111111111111111111111111111111111111111111111111111111111111), + 0b0'000000000000000'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111_u128, UInt128(Rep::max_subnormal())); EXPECT_EQ( - u128(0b0'000000000000001'000000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'000000000000001'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::min_normal())); EXPECT_EQ( - u128(0b0'111111111111110'111111111111111111111111111111111111111111111111, - 0b1111111111111111111111111111111111111111111111111111111111111111), + 0b0'111111111111110'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111_u128, UInt128(Rep::max_normal())); EXPECT_EQ( - u128(0b0'111111111111111'000000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::inf())); EXPECT_EQ( - u128(0b0'111111111111111'010000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'111111111111111'0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::signaling_nan())); EXPECT_EQ( - u128(0b0'111111111111111'100000000000000000000000000000000000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::quiet_nan())); } @@ -134,89 +123,73 @@ TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80) { using Rep = FPRep; EXPECT_EQ( - u128(0b0'000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000000), + 0b0'0000000000000000000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::zero())); EXPECT_EQ( - u128(0b0'011111111111111, - 0b1000000000000000000000000000000000000000000000000000000000000000), + 0b0'0111111111111111000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::one())); EXPECT_EQ( - u128(0b0'000000000000000, - 0b0000000000000000000000000000000000000000000000000000000000000001), + 0b0'0000000000000000000000000000000000000000000000000000000000000000000000000000001_u128, UInt128(Rep::min_subnormal())); EXPECT_EQ( - u128(0b0'000000000000000, - 0b0111111111111111111111111111111111111111111111111111111111111111), + 0b0'0000000000000000111111111111111111111111111111111111111111111111111111111111111_u128, UInt128(Rep::max_subnormal())); EXPECT_EQ( - u128(0b0'000000000000001, - 0b1000000000000000000000000000000000000000000000000000000000000000), + 0b0'0000000000000011000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::min_normal())); EXPECT_EQ( - u128(0b0'111111111111110, - 0b1111111111111111111111111111111111111111111111111111111111111111), + 0b0'1111111111111101111111111111111111111111111111111111111111111111111111111111111_u128, UInt128(Rep::max_normal())); EXPECT_EQ( - u128(0b0'111111111111111, - 0b1000000000000000000000000000000000000000000000000000000000000000), + 0b0'1111111111111111000000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::inf())); EXPECT_EQ( - u128(0b0'111111111111111, - 0b1010000000000000000000000000000000000000000000000000000000000000), + 0b0'1111111111111111010000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::signaling_nan())); EXPECT_EQ( - u128(0b0'111111111111111, - 0b1100000000000000000000000000000000000000000000000000000000000000), + 0b0'1111111111111111100000000000000000000000000000000000000000000000000000000000000_u128, UInt128(Rep::quiet_nan())); } TEST(LlvmLibcFPBitsTest, FPType_X86_Binary80_IsNan) { using Rep = FPRep; - const auto is_nan = [](uint64_t hi, uint64_t lo) { - Rep rep; - rep.set_uintval(u128(hi, lo)); - return rep.is_nan(); - }; - - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Pseudo-Infinity - 0b0000000000000000000000000000000000000000000000000000000000000000)); - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Pseudo Not a Number - 0b0000000000000000000000000000000000000000000000000000000000000001)); - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Pseudo Not a Number - 0b0100000000000000000000000000000000000000000000000000000000000000)); - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Signalling Not a Number - 0b1000000000000000000000000000000000000000000000000000000000000001)); - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Floating-point Indefinite - 0b1100000000000000000000000000000000000000000000000000000000000000)); - EXPECT_TRUE(is_nan( - 0b0'111111111111111, // NAN : Quiet Not a Number - 0b1100000000000000000000000000000000000000000000000000000000000001)); - EXPECT_TRUE(is_nan( - 0b0'111111111111110, // NAN : Unnormal - 0b0000000000000000000000000000000000000000000000000000000000000000)); - - EXPECT_FALSE(is_nan( - 0b0'000000000000000, // Zero - 0b0000000000000000000000000000000000000000000000000000000000000000)); - EXPECT_FALSE(is_nan( - 0b0'000000000000000, // Subnormal - 0b0000000000000000000000000000000000000000000000000000000000000001)); - EXPECT_FALSE(is_nan( - 0b0'000000000000000, // Pseudo Denormal - 0b1000000000000000000000000000000000000000000000000000000000000001)); - EXPECT_FALSE(is_nan( - 0b0'111111111111111, // Infinity - 0b1000000000000000000000000000000000000000000000000000000000000000)); - EXPECT_FALSE(is_nan( - 0b0'111111111111110, // Normalized - 0b1000000000000000000000000000000000000000000000000000000000000000)); + EXPECT_TRUE( // NAN : Pseudo-Infinity + Rep(0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Pseudo Not a Number + Rep(0b0'111111111111111'0000000000000000000000000000000000000000000000000000000000000001_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Pseudo Not a Number + Rep(0b0'111111111111111'0100000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Signalling Not a Number + Rep(0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000001_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Floating-point Indefinite + Rep(0b0'111111111111111'1100000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Quiet Not a Number + Rep(0b0'111111111111111'1100000000000000000000000000000000000000000000000000000000000001_u128) + .is_nan()); + EXPECT_TRUE( // NAN : Unnormal + Rep(0b0'111111111111110'0000000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_FALSE( // Zero + Rep(0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_FALSE( // Subnormal + Rep(0b0'000000000000000'0000000000000000000000000000000000000000000000000000000000000001_u128) + .is_nan()); + EXPECT_FALSE( // Pseudo Denormal + Rep(0b0'000000000000000'1000000000000000000000000000000000000000000000000000000000000001_u128) + .is_nan()); + EXPECT_FALSE( // Infinity + Rep(0b0'111111111111111'1000000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); + EXPECT_FALSE( // Normalized + Rep(0b0'111111111111110'1000000000000000000000000000000000000000000000000000000000000000_u128) + .is_nan()); } enum class FP { @@ -339,49 +312,49 @@ TEST(LlvmLibcFPBitsTest, FloatType) { FloatBits zero(0.0f); EXPECT_TRUE(zero.is_pos()); - EXPECT_EQ(zero.get_biased_exponent(), static_cast(0)); - EXPECT_EQ(zero.get_mantissa(), static_cast(0)); - EXPECT_EQ(zero.uintval(), static_cast(0x00000000)); + EXPECT_EQ(zero.get_biased_exponent(), 0_u16); + EXPECT_EQ(zero.get_mantissa(), 0_u32); + EXPECT_EQ(zero.uintval(), 0_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(), "0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)"); FloatBits negzero(-0.0f); EXPECT_TRUE(negzero.is_neg()); - EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0)); - EXPECT_EQ(negzero.get_mantissa(), static_cast(0)); - EXPECT_EQ(negzero.uintval(), static_cast(0x80000000)); + EXPECT_EQ(negzero.get_biased_exponent(), 0_u16); + EXPECT_EQ(negzero.get_mantissa(), 0_u32); + EXPECT_EQ(negzero.uintval(), 0x80000000_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(), "0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)"); FloatBits one(1.0f); EXPECT_TRUE(one.is_pos()); - EXPECT_EQ(one.get_biased_exponent(), static_cast(0x7F)); - EXPECT_EQ(one.get_mantissa(), static_cast(0)); - EXPECT_EQ(one.uintval(), static_cast(0x3F800000)); + EXPECT_EQ(one.get_biased_exponent(), 0x7F_u16); + EXPECT_EQ(one.get_mantissa(), 0_u32); + EXPECT_EQ(one.uintval(), 0x3F800000_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(), "0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)"); FloatBits negone(-1.0f); EXPECT_TRUE(negone.is_neg()); - EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x7F)); - EXPECT_EQ(negone.get_mantissa(), static_cast(0)); - EXPECT_EQ(negone.uintval(), static_cast(0xBF800000)); + EXPECT_EQ(negone.get_biased_exponent(), 0x7F_u16); + EXPECT_EQ(negone.get_mantissa(), 0_u32); + EXPECT_EQ(negone.uintval(), 0xBF800000_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(), "0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)"); FloatBits num(1.125f); EXPECT_TRUE(num.is_pos()); - EXPECT_EQ(num.get_biased_exponent(), static_cast(0x7F)); - EXPECT_EQ(num.get_mantissa(), static_cast(0x00100000)); - EXPECT_EQ(num.uintval(), static_cast(0x3F900000)); + EXPECT_EQ(num.get_biased_exponent(), 0x7F_u16); + EXPECT_EQ(num.get_mantissa(), 0x00100000_u32); + EXPECT_EQ(num.uintval(), 0x3F900000_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(), "0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)"); FloatBits negnum(-1.125f); EXPECT_TRUE(negnum.is_neg()); - EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x7F)); - EXPECT_EQ(negnum.get_mantissa(), static_cast(0x00100000)); - EXPECT_EQ(negnum.uintval(), static_cast(0xBF900000)); + EXPECT_EQ(negnum.get_biased_exponent(), 0x7F_u16); + EXPECT_EQ(negnum.get_mantissa(), 0x00100000_u32); + EXPECT_EQ(negnum.uintval(), 0xBF900000_u32); EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(), "0xBF900000 = (S: 1, E: 0x007F, M: 0x00100000)"); @@ -401,49 +374,49 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { DoubleBits zero(0.0); EXPECT_TRUE(zero.is_pos()); - EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000)); - EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000)); + EXPECT_EQ(zero.get_biased_exponent(), 0_u16); + EXPECT_EQ(zero.get_mantissa(), 0_u64); + EXPECT_EQ(zero.uintval(), 0_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(), "0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)"); DoubleBits negzero(-0.0); EXPECT_TRUE(negzero.is_neg()); - EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000)); - EXPECT_EQ(negzero.uintval(), static_cast(0x8000000000000000)); + EXPECT_EQ(negzero.get_biased_exponent(), 0_u16); + EXPECT_EQ(negzero.get_mantissa(), 0_u64); + EXPECT_EQ(negzero.uintval(), 0x8000000000000000_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(), "0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)"); DoubleBits one(1.0); EXPECT_TRUE(one.is_pos()); - EXPECT_EQ(one.get_biased_exponent(), static_cast(0x03FF)); - EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000)); - EXPECT_EQ(one.uintval(), static_cast(0x3FF0000000000000)); + EXPECT_EQ(one.get_biased_exponent(), 0x03FF_u16); + EXPECT_EQ(one.get_mantissa(), 0_u64); + EXPECT_EQ(one.uintval(), 0x3FF0000000000000_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(), "0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)"); DoubleBits negone(-1.0); EXPECT_TRUE(negone.is_neg()); - EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x03FF)); - EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000)); - EXPECT_EQ(negone.uintval(), static_cast(0xBFF0000000000000)); + EXPECT_EQ(negone.get_biased_exponent(), 0x03FF_u16); + EXPECT_EQ(negone.get_mantissa(), 0_u64); + EXPECT_EQ(negone.uintval(), 0xBFF0000000000000_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(), "0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)"); DoubleBits num(1.125); EXPECT_TRUE(num.is_pos()); - EXPECT_EQ(num.get_biased_exponent(), static_cast(0x03FF)); - EXPECT_EQ(num.get_mantissa(), static_cast(0x0002000000000000)); - EXPECT_EQ(num.uintval(), static_cast(0x3FF2000000000000)); + EXPECT_EQ(num.get_biased_exponent(), 0x03FF_u16); + EXPECT_EQ(num.get_mantissa(), 0x0002000000000000_u64); + EXPECT_EQ(num.uintval(), 0x3FF2000000000000_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(), "0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)"); DoubleBits negnum(-1.125); EXPECT_TRUE(negnum.is_neg()); - EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x03FF)); - EXPECT_EQ(negnum.get_mantissa(), static_cast(0x0002000000000000)); - EXPECT_EQ(negnum.uintval(), static_cast(0xBFF2000000000000)); + EXPECT_EQ(negnum.get_biased_exponent(), 0x03FF_u16); + EXPECT_EQ(negnum.get_mantissa(), 0x0002000000000000_u64); + EXPECT_EQ(negnum.uintval(), 0xBFF2000000000000_u64); EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(), "0xBFF2000000000000 = (S: 1, E: 0x03FF, M: 0x0002000000000000)"); @@ -467,10 +440,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits zero(0.0l); EXPECT_TRUE(zero.is_pos()); - EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000) << 64); + EXPECT_EQ(zero.get_biased_exponent(), 0_u16); + EXPECT_EQ(zero.get_mantissa(), 0_u128); + EXPECT_EQ(zero.uintval(), 0_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(zero).c_str(), "0x00000000000000000000000000000000 = " @@ -478,10 +450,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits negzero(-0.0l); EXPECT_TRUE(negzero.is_neg()); - EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negzero.uintval(), static_cast(0x1) << 79); + EXPECT_EQ(negzero.get_biased_exponent(), 0_u16); + EXPECT_EQ(negzero.get_mantissa(), 0_u128); + EXPECT_EQ(negzero.uintval(), 0x80000000000000000000_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(negzero).c_str(), "0x00000000000080000000000000000000 = " @@ -489,9 +460,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits one(1.0l); EXPECT_TRUE(one.is_pos()); - EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); - EXPECT_EQ(one.uintval(), static_cast(0x3FFF8) << 60); + EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(one.get_mantissa(), 0_u128); + EXPECT_EQ(one.uintval(), 0x3FFF8000000000000000_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(one).c_str(), "0x0000000000003FFF8000000000000000 = " @@ -499,10 +470,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits negone(-1.0l); EXPECT_TRUE(negone.is_neg()); - EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negone.uintval(), static_cast(0xBFFF8) << 60); + EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negone.get_mantissa(), 0_u128); + EXPECT_EQ(negone.uintval(), 0xBFFF8000000000000000_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(negone).c_str(), "0x000000000000BFFF8000000000000000 = " @@ -510,9 +480,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits num(1.125l); EXPECT_TRUE(num.is_pos()); - EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(num.get_mantissa(), static_cast(0x1) << 60); - EXPECT_EQ(num.uintval(), static_cast(0x3FFF9) << 60); + EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(num.get_mantissa(), 0x1000000000000000_u128); + EXPECT_EQ(num.uintval(), 0x3FFF9000000000000000_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(num).c_str(), "0x0000000000003FFF9000000000000000 = " @@ -520,9 +490,9 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { LongDoubleBits negnum(-1.125l); EXPECT_TRUE(negnum.is_neg()); - EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negnum.get_mantissa(), static_cast(0x1) << 60); - EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF9) << 60); + EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negnum.get_mantissa(), 0x1000000000000000_u128); + EXPECT_EQ(negnum.uintval(), 0xBFFF9000000000000000_u128); EXPECT_STREQ( LIBC_NAMESPACE::str(negnum).c_str(), "0x000000000000BFFF9000000000000000 = " @@ -547,57 +517,54 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { LongDoubleBits zero(0.0l); EXPECT_TRUE(zero.is_pos()); - EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000) << 64); + EXPECT_EQ(zero.get_biased_exponent(), 0_u16); + EXPECT_EQ(zero.get_mantissa(), 0_u128); + EXPECT_EQ(zero.uintval(), 0_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(), "0x00000000000000000000000000000000 = " "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)"); LongDoubleBits negzero(-0.0l); EXPECT_TRUE(negzero.is_neg()); - EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negzero.uintval(), static_cast(0x1) << 127); + EXPECT_EQ(negzero.get_biased_exponent(), 0_u16); + EXPECT_EQ(negzero.get_mantissa(), 0_u128); + EXPECT_EQ(negzero.uintval(), 0x80000000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(), "0x80000000000000000000000000000000 = " "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)"); LongDoubleBits one(1.0l); EXPECT_TRUE(one.is_pos()); - EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); - EXPECT_EQ(one.uintval(), static_cast(0x3FFF) << 112); + EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(one.get_mantissa(), 0_u128); + EXPECT_EQ(one.uintval(), 0x3FFF0000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(), "0x3FFF0000000000000000000000000000 = " "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); LongDoubleBits negone(-1.0l); EXPECT_TRUE(negone.is_neg()); - EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negone.uintval(), static_cast(0xBFFF) << 112); + EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negone.get_mantissa(), 0_u128); + EXPECT_EQ(negone.uintval(), 0xBFFF0000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(), "0xBFFF0000000000000000000000000000 = " "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); LongDoubleBits num(1.125l); EXPECT_TRUE(num.is_pos()); - EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(num.get_mantissa(), static_cast(0x2) << 108); - EXPECT_EQ(num.uintval(), static_cast(0x3FFF2) << 108); + EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(num.get_mantissa(), 0x2000000000000000000000000000_u128); + EXPECT_EQ(num.uintval(), 0x3FFF2000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(), "0x3FFF2000000000000000000000000000 = " "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); LongDoubleBits negnum(-1.125l); EXPECT_TRUE(negnum.is_neg()); - EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negnum.get_mantissa(), static_cast(0x2) << 108); - EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF2) << 108); + EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negnum.get_mantissa(), 0x2000000000000000000000000000_u128); + EXPECT_EQ(negnum.uintval(), 0xBFFF2000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(), "0xBFFF2000000000000000000000000000 = " "(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); @@ -621,57 +588,54 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { Float128Bits zero = Float128Bits::zero(Sign::POS); EXPECT_TRUE(zero.is_pos()); - EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000) << 64); + EXPECT_EQ(zero.get_biased_exponent(), 0_u16); + EXPECT_EQ(zero.get_mantissa(), 0_u128); + EXPECT_EQ(zero.uintval(), 0_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(zero).c_str(), "0x00000000000000000000000000000000 = " "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)"); Float128Bits negzero = Float128Bits::zero(Sign::NEG); EXPECT_TRUE(negzero.is_neg()); - EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); - EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negzero.uintval(), static_cast(0x1) << 127); + EXPECT_EQ(negzero.get_biased_exponent(), 0_u16); + EXPECT_EQ(negzero.get_mantissa(), 0_u128); + EXPECT_EQ(negzero.uintval(), 0x80000000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negzero).c_str(), "0x80000000000000000000000000000000 = " "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)"); Float128Bits one(float128(1.0)); EXPECT_TRUE(one.is_pos()); - EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); - EXPECT_EQ(one.uintval(), static_cast(0x3FFF) << 112); + EXPECT_EQ(one.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(one.get_mantissa(), 0_u128); + EXPECT_EQ(one.uintval(), 0x3FFF0000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(one).c_str(), "0x3FFF0000000000000000000000000000 = " "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); Float128Bits negone(float128(-1.0)); EXPECT_TRUE(negone.is_neg()); - EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) - << 64); - EXPECT_EQ(negone.uintval(), static_cast(0xBFFF) << 112); + EXPECT_EQ(negone.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negone.get_mantissa(), 0_u128); + EXPECT_EQ(negone.uintval(), 0xBFFF0000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negone).c_str(), "0xBFFF0000000000000000000000000000 = " "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); Float128Bits num(float128(1.125)); EXPECT_TRUE(num.is_pos()); - EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(num.get_mantissa(), static_cast(0x2) << 108); - EXPECT_EQ(num.uintval(), static_cast(0x3FFF2) << 108); + EXPECT_EQ(num.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(num.get_mantissa(), 0x2000000000000000000000000000_u128); + EXPECT_EQ(num.uintval(), 0x3FFF2000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(num).c_str(), "0x3FFF2000000000000000000000000000 = " "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); Float128Bits negnum(float128(-1.125)); EXPECT_TRUE(negnum.is_neg()); - EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); - EXPECT_EQ(negnum.get_mantissa(), static_cast(0x2) << 108); - EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF2) << 108); + EXPECT_EQ(negnum.get_biased_exponent(), 0x3FFF_u16); + EXPECT_EQ(negnum.get_mantissa(), 0x2000000000000000000000000000_u128); + EXPECT_EQ(negnum.uintval(), 0xBFFF2000000000000000000000000000_u128); EXPECT_STREQ(LIBC_NAMESPACE::str(negnum).c_str(), "0xBFFF2000000000000000000000000000 = " "(S: 1, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); diff --git a/libc/test/src/__support/integer_literals_test.cpp b/libc/test/src/__support/integer_literals_test.cpp new file mode 100644 index 00000000000000..10c3625a0e5a49 --- /dev/null +++ b/libc/test/src/__support/integer_literals_test.cpp @@ -0,0 +1,134 @@ + +//===-- Unittests for user defined integer literals -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/integer_literals.h" +#include "test/UnitTest/Test.h" + +using LIBC_NAMESPACE::operator""_u8; +using LIBC_NAMESPACE::operator""_u16; +using LIBC_NAMESPACE::operator""_u32; +using LIBC_NAMESPACE::operator""_u64; +using LIBC_NAMESPACE::operator""_u128; +using LIBC_NAMESPACE::operator""_u256; + +TEST(LlvmLibcIntegerLiteralTest, u8) { + EXPECT_EQ(uint8_t(0), 0_u8); + EXPECT_EQ(uint8_t(UINT8_MAX), 255_u8); + EXPECT_EQ(uint8_t(UINT8_MAX), 0xFF_u8); + EXPECT_EQ(uint8_t(UINT8_MAX), 0b11111111_u8); +} + +TEST(LlvmLibcIntegerLiteralTest, u16) { + EXPECT_EQ(uint16_t(0), 0_u16); + EXPECT_EQ(uint16_t(UINT8_MAX), 255_u16); + EXPECT_EQ(uint16_t(UINT8_MAX), 0xFF_u16); + EXPECT_EQ(uint16_t(UINT8_MAX), 0b11111111_u16); + EXPECT_EQ(uint16_t(UINT16_MAX), 65535_u16); + EXPECT_EQ(uint16_t(UINT16_MAX), 0xFFFF_u16); + EXPECT_EQ(uint16_t(UINT16_MAX), 0b11111111'11111111_u16); +} + +TEST(LlvmLibcIntegerLiteralTest, u32) { + EXPECT_EQ(uint32_t(0), 0_u32); + EXPECT_EQ(uint32_t(UINT8_MAX), 255_u32); + EXPECT_EQ(uint32_t(UINT8_MAX), 0xFF_u32); + EXPECT_EQ(uint32_t(UINT8_MAX), 0b11111111_u32); + EXPECT_EQ(uint32_t(UINT16_MAX), 65535_u32); + EXPECT_EQ(uint32_t(UINT16_MAX), 0xFFFF_u32); + EXPECT_EQ(uint32_t(UINT16_MAX), 0b11111111'11111111_u32); + EXPECT_EQ(uint32_t(UINT32_MAX), 4294967295_u32); + EXPECT_EQ(uint32_t(UINT32_MAX), 0xFFFFFFFF_u32); + EXPECT_EQ(uint32_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u32); +} + +TEST(LlvmLibcIntegerLiteralTest, u64) { + EXPECT_EQ(uint64_t(0), 0_u64); + EXPECT_EQ(uint64_t(UINT8_MAX), 255_u64); + EXPECT_EQ(uint64_t(UINT8_MAX), 0xFF_u64); + EXPECT_EQ(uint64_t(UINT8_MAX), 0b11111111_u64); + EXPECT_EQ(uint64_t(UINT16_MAX), 65535_u64); + EXPECT_EQ(uint64_t(UINT16_MAX), 0xFFFF_u64); + EXPECT_EQ(uint64_t(UINT16_MAX), 0b11111111'11111111_u64); + EXPECT_EQ(uint64_t(UINT32_MAX), 4294967295_u64); + EXPECT_EQ(uint64_t(UINT32_MAX), 0xFFFFFFFF_u64); + EXPECT_EQ(uint64_t(UINT32_MAX), 0b1111111111111111'1111111111111111_u64); + EXPECT_EQ(uint64_t(UINT64_MAX), 18446744073709551615_u64); + EXPECT_EQ(uint64_t(UINT64_MAX), 0xFFFFFFFF'FFFFFFFF_u64); + EXPECT_EQ( + uint64_t(UINT64_MAX), + 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u64); +} + +TEST(LlvmLibcIntegerLiteralTest, u128) { +#if defined(__SIZEOF_INT128__) + const __uint128_t ZERO = 0; + const __uint128_t U8_MAX = UINT8_MAX; + const __uint128_t U16_MAX = UINT16_MAX; + const __uint128_t U32_MAX = UINT32_MAX; + const __uint128_t U64_MAX = UINT64_MAX; + const __uint128_t U128_MAX = (U64_MAX << 64) | U64_MAX; +#else + const UInt128 ZERO = 0; + const UInt128 U8_MAX = UINT8_MAX; + const UInt128 U16_MAX = UINT16_MAX; + const UInt128 U32_MAX = UINT32_MAX; + const UInt128 U64_MAX = UINT64_MAX; + const UInt128 U128_MAX = (U64_MAX << 64) | U64_MAX; +#endif + EXPECT_EQ(ZERO, 0_u128); + EXPECT_EQ(U8_MAX, 255_u128); + EXPECT_EQ(U8_MAX, 0xFF_u128); + EXPECT_EQ(U8_MAX, 0b11111111_u128); + EXPECT_EQ(U16_MAX, 65535_u128); + EXPECT_EQ(U16_MAX, 0xFFFF_u128); + EXPECT_EQ(U16_MAX, 0b11111111'11111111_u128); + EXPECT_EQ(U32_MAX, 4294967295_u128); + EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u128); + EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u128); + EXPECT_EQ(U64_MAX, 18446744073709551615_u128); + EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u128); + EXPECT_EQ( + U64_MAX, + 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128); + EXPECT_EQ(U128_MAX, 340282366920938463463374607431768211455_u128); + EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u128); + EXPECT_EQ( + U128_MAX, + 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111'1111111111111111_u128); +} + +TEST(LlvmLibcIntegerLiteralTest, u256) { + using UInt256 = LIBC_NAMESPACE::cpp::UInt<256>; + const UInt256 ZERO = 0; + const UInt256 U8_MAX = UINT8_MAX; + const UInt256 U16_MAX = UINT16_MAX; + const UInt256 U32_MAX = UINT32_MAX; + const UInt256 U64_MAX = UINT64_MAX; + const UInt256 U128_MAX = (U64_MAX << 64) | U64_MAX; + const UInt256 U256_MAX = (U128_MAX << 128) | U128_MAX; + EXPECT_EQ(ZERO, 0_u256); + EXPECT_EQ(U8_MAX, 255_u256); + EXPECT_EQ(U8_MAX, 0xFF_u256); + EXPECT_EQ(U8_MAX, 0b11111111_u256); + EXPECT_EQ(U16_MAX, 65535_u256); + EXPECT_EQ(U16_MAX, 0xFFFF_u256); + EXPECT_EQ(U16_MAX, 0b11111111'11111111_u256); + EXPECT_EQ(U32_MAX, 4294967295_u256); + EXPECT_EQ(U32_MAX, 0xFFFFFFFF_u256); + EXPECT_EQ(U32_MAX, 0b1111111111111111'1111111111111111_u256); + EXPECT_EQ(U64_MAX, 18446744073709551615_u256); + EXPECT_EQ(U64_MAX, 0xFFFFFFFF'FFFFFFFF_u256); + EXPECT_EQ( + U64_MAX, + 0b1111111111111111'1111111111111111'1111111111111111'1111111111111111_u256); + EXPECT_EQ(U128_MAX, 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256); + EXPECT_EQ( + U256_MAX, + 0xFFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF'FFFFFFFF_u256); +} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 30c180b5a8b473..fde2bac746f4f8 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -472,6 +472,15 @@ libc_support_library( ], ) +libc_support_library( + name = "__support_integer_literals", + hdrs = ["src/__support/integer_literals.h"], + deps = [ + ":__support_cpp_limits", + ":__support_uint128", + ], +) + libc_support_library( name = "__support_str_to_num_result", hdrs = ["src/__support/str_to_num_result.h"], diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel index 22f4d03ee900b6..e691d3c3d2ebdd 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/__support/BUILD.bazel @@ -99,3 +99,11 @@ libc_test( "//libc:__support_char_vector", ], ) + +libc_test( + name = "integer_literals_test", + srcs = ["integer_literals_test.cpp"], + deps = [ + "//libc:__support_integer_literals", + ], +) diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel index 461d5127a42a74..76443fc5d9f85b 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/src/__support/FPUtil/BUILD.bazel @@ -16,6 +16,7 @@ libc_test( deps = [ "//libc:__support_fputil_fp_bits", "//libc:__support_fputil_fpbits_str", + "//libc:__support_integer_literals", ], )