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

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Fri Jun 24 23:47:50 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-06-25T06:38:24Z
New Revision: 4965cea2f3573110bce61d3fedd98a73e60a2670

URL: https://github.com/llvm/llvm-project/commit/4965cea2f3573110bce61d3fedd98a73e60a2670
DIFF: https://github.com/llvm/llvm-project/commit/4965cea2f3573110bce61d3fedd98a73e60a2670.diff

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

Added: 
    

Modified: 
    libc/src/__support/CPP/UInt.h
    libc/test/src/__support/uint128_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/CPP/UInt.h b/libc/src/__support/CPP/UInt.h
index 66aa1aeccc67..045950b0a96b 100644
--- a/libc/src/__support/CPP/UInt.h
+++ b/libc/src/__support/CPP/UInt.h
@@ -89,6 +89,11 @@ template <size_t Bits> class UInt {
     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 @@ template <size_t Bits> class UInt {
     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 @@ template <size_t Bits> class UInt {
     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 @@ template <size_t Bits> class UInt {
     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 @@ template <size_t Bits> class UInt {
     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 @@ template <size_t Bits> class UInt {
     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]; }
 

diff  --git a/libc/test/src/__support/uint128_test.cpp b/libc/test/src/__support/uint128_test.cpp
index bbfec2066afa..7cb405c3de87 100644
--- a/libc/test/src/__support/uint128_test.cpp
+++ b/libc/test/src/__support/uint128_test.cpp
@@ -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});


        


More information about the libc-commits mailing list