[libc] Add compound assignment and pre-increment operators to UInt.

This commit is contained in:
Siva Chandra Reddy 2022-06-25 06:38:03 +00:00
parent 262b4091f9
commit 4965cea2f3
2 changed files with 90 additions and 0 deletions

View File

@ -89,6 +89,11 @@ public:
return result;
}
constexpr UInt<Bits> operator+=(const UInt<Bits> &other) {
*this = *this + other;
return *this;
}
// Multiply this number with x and store the result in this number. It is
// implemented using the long multiplication algorithm by splitting the
// 64-bit words of this number and |x| in to 32-bit halves but peforming
@ -158,6 +163,11 @@ public:
return result;
}
constexpr UInt<Bits> &operator*=(const UInt<Bits> &other) {
*this = *this * other;
return *this;
}
constexpr void shift_left(size_t s) {
const size_t drop = s / 64; // Number of words to drop
const size_t shift = s % 64; // Bits to shift in the remaining words.
@ -225,6 +235,12 @@ public:
return result;
}
constexpr UInt<Bits> &operator&=(const UInt<Bits> &other) {
for (size_t i = 0; i < WordCount; ++i)
val[i] &= other.val[i];
return *this;
}
constexpr UInt<Bits> operator|(const UInt<Bits> &other) const {
UInt<Bits> result;
for (size_t i = 0; i < WordCount; ++i)
@ -232,6 +248,12 @@ public:
return result;
}
constexpr UInt<Bits> &operator|=(const UInt<Bits> &other) {
for (size_t i = 0; i < WordCount; ++i)
val[i] |= other.val[i];
return *this;
}
constexpr UInt<Bits> operator^(const UInt<Bits> &other) const {
UInt<Bits> result;
for (size_t i = 0; i < WordCount; ++i)
@ -239,6 +261,12 @@ public:
return result;
}
constexpr UInt<Bits> &operator^=(const UInt<Bits> &other) {
for (size_t i = 0; i < WordCount; ++i)
val[i] ^= other.val[i];
return *this;
}
constexpr UInt<Bits> operator~() const {
UInt<Bits> result;
for (size_t i = 0; i < WordCount; ++i)
@ -314,6 +342,12 @@ public:
return true;
}
constexpr UInt<Bits> &operator++() {
UInt<Bits> one(1);
add(one);
return *this;
}
// Return the i-th 64-bit word of the number.
constexpr const uint64_t &operator[](size_t i) const { return val[i]; }

View File

@ -155,6 +155,62 @@ TEST(LlvmLibcUInt128ClassTest, OrTests) {
EXPECT_EQ((base | val32), result32);
}
TEST(LlvmLibcUInt128ClassTest, CompoundAssignments) {
LL_UInt128 x({0xffff00000000ffff, 0xffffffff00000000});
LL_UInt128 b({0xf0f0f0f00f0f0f0f, 0xff00ff0000ff00ff});
LL_UInt128 a = x;
a |= b;
LL_UInt128 or_result({0xfffff0f00f0fffff, 0xffffffff00ff00ff});
EXPECT_EQ(a, or_result);
a = x;
a &= b;
LL_UInt128 and_result({0xf0f0000000000f0f, 0xff00ff0000000000});
EXPECT_EQ(a, and_result);
a = x;
a ^= b;
LL_UInt128 xor_result({0x0f0ff0f00f0ff0f0, 0x00ff00ff00ff00ff});
EXPECT_EQ(a, xor_result);
a = LL_UInt128(uint64_t(0x0123456789abcdef));
LL_UInt128 shift_left_result(uint64_t(0x123456789abcdef0));
a <<= 4;
EXPECT_EQ(a, shift_left_result);
a = LL_UInt128(uint64_t(0x123456789abcdef1));
LL_UInt128 shift_right_result(uint64_t(0x0123456789abcdef));
a >>= 4;
EXPECT_EQ(a, shift_right_result);
a = LL_UInt128({0xf000000000000001, 0});
b = LL_UInt128({0x100000000000000f, 0});
LL_UInt128 add_result({0x10, 0x1});
a += b;
EXPECT_EQ(a, add_result);
a = LL_UInt128({0xf, 0});
b = LL_UInt128({0x1111111111111111, 0x1111111111111111});
LL_UInt128 mul_result({0xffffffffffffffff, 0xffffffffffffffff});
a *= b;
EXPECT_EQ(a, mul_result);
}
TEST(LlvmLibcUInt128ClassTest, UnaryPredecrement) {
LL_UInt128 a = LL_UInt128({0x1111111111111111, 0x1111111111111111});
++a;
EXPECT_EQ(a, LL_UInt128({0x1111111111111112, 0x1111111111111111}));
a = LL_UInt128({0xffffffffffffffff, 0x0});
++a;
EXPECT_EQ(a, LL_UInt128({0x0, 0x1}));
a = LL_UInt128({0xffffffffffffffff, 0xffffffffffffffff});
++a;
EXPECT_EQ(a, LL_UInt128({0x0, 0x0}));
}
TEST(LlvmLibcUInt128ClassTest, EqualsTests) {
LL_UInt128 a1({0xffffffff00000000, 0xffff00000000ffff});
LL_UInt128 a2({0xffffffff00000000, 0xffff00000000ffff});