Index: llvm/trunk/include/llvm/ADT/APInt.h =================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h +++ llvm/trunk/include/llvm/ADT/APInt.h @@ -698,6 +698,13 @@ /// \returns *this after ANDing with RHS. APInt &operator&=(const APInt &RHS); + /// \brief Bitwise AND assignment operator. + /// + /// Performs a bitwise AND operation on this APInt and RHS. RHS is + /// logically zero-extended or truncated to match the bit-width of + /// the LHS. + APInt &operator&=(uint64_t RHS); + /// \brief Bitwise OR assignment operator. /// /// Performs a bitwise OR operation on this APInt and RHS. The result is @@ -729,6 +736,21 @@ /// \returns *this after XORing with RHS. APInt &operator^=(const APInt &RHS); + /// \brief Bitwise XOR assignment operator. + /// + /// Performs a bitwise XOR operation on this APInt and RHS. RHS is + /// logically zero-extended or truncated to match the bit-width of + /// the LHS. + APInt &operator^=(uint64_t RHS) { + if (isSingleWord()) { + VAL ^= RHS; + clearUnusedBits(); + } else { + pVal[0] ^= RHS; + } + return *this; + } + /// \brief Multiplication assignment operator. /// /// Multiplies this APInt by RHS and assigns the result to *this. @@ -1723,6 +1745,36 @@ inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; } +inline APInt operator&(APInt a, uint64_t RHS) { + a &= RHS; + return a; +} + +inline APInt operator&(uint64_t LHS, APInt b) { + b &= LHS; + return b; +} + +inline APInt operator|(APInt a, uint64_t RHS) { + a |= RHS; + return a; +} + +inline APInt operator|(uint64_t LHS, APInt b) { + b |= LHS; + return b; +} + +inline APInt operator^(APInt a, uint64_t RHS) { + a ^= RHS; + return a; +} + +inline APInt operator^(uint64_t LHS, APInt b) { + b ^= LHS; + return b; +} + inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) { I.print(OS, true); return OS; Index: llvm/trunk/lib/Support/APInt.cpp =================================================================== --- llvm/trunk/lib/Support/APInt.cpp +++ llvm/trunk/lib/Support/APInt.cpp @@ -424,6 +424,18 @@ return *this; } +APInt &APInt::operator&=(uint64_t RHS) { + if (isSingleWord()) { + VAL &= RHS; + return *this; + } + pVal[0] &= RHS; + unsigned numWords = getNumWords(); + for (unsigned i = 1; i < numWords; ++i) + pVal[i] = 0; + return *this; +} + APInt& APInt::operator|=(const APInt& RHS) { assert(BitWidth == RHS.BitWidth && "Bit widths must be the same"); if (isSingleWord()) { Index: llvm/trunk/unittests/ADT/APIntTest.cpp =================================================================== --- llvm/trunk/unittests/ADT/APIntTest.cpp +++ llvm/trunk/unittests/ADT/APIntTest.cpp @@ -446,6 +446,58 @@ EXPECT_TRUE(!MinusTwo.slt(MinusTwo)); } +TEST(APIntTest, binaryOpsWithRawIntegers) { + // Single word check. + uint64_t E1 = 0x2CA7F46BF6569915ULL; + APInt A1(64, E1); + + EXPECT_EQ(A1 & E1, E1); + EXPECT_EQ(A1 & 0, 0); + EXPECT_EQ(A1 & 1, 1); + EXPECT_EQ(A1 & 5, 5); + EXPECT_EQ(A1 & UINT64_MAX, E1); + + EXPECT_EQ(A1 | E1, E1); + EXPECT_EQ(A1 | 0, E1); + EXPECT_EQ(A1 | 1, E1); + EXPECT_EQ(A1 | 2, E1 | 2); + EXPECT_EQ(A1 | UINT64_MAX, UINT64_MAX); + + EXPECT_EQ(A1 ^ E1, 0); + EXPECT_EQ(A1 ^ 0, E1); + EXPECT_EQ(A1 ^ 1, E1 ^ 1); + EXPECT_EQ(A1 ^ 7, E1 ^ 7); + EXPECT_EQ(A1 ^ UINT64_MAX, ~E1); + + // Multiword check. + uint64_t N = 0xEB6EB136591CBA21ULL; + integerPart E2[4] = { + N, + 0x7B9358BD6A33F10AULL, + 0x7E7FFA5EADD8846ULL, + 0x305F341CA00B613DULL + }; + APInt A2(integerPartWidth*4, E2); + + EXPECT_EQ(A2 & N, N); + EXPECT_EQ(A2 & 0, 0); + EXPECT_EQ(A2 & 1, 1); + EXPECT_EQ(A2 & 5, 1); + EXPECT_EQ(A2 & UINT64_MAX, N); + + EXPECT_EQ(A2 | N, A2); + EXPECT_EQ(A2 | 0, A2); + EXPECT_EQ(A2 | 1, A2); + EXPECT_EQ(A2 | 2, A2 + 2); + EXPECT_EQ(A2 | UINT64_MAX, A2 - N + UINT64_MAX); + + EXPECT_EQ(A2 ^ N, A2 - N); + EXPECT_EQ(A2 ^ 0, A2); + EXPECT_EQ(A2 ^ 1, A2 - 1); + EXPECT_EQ(A2 ^ 7, A2 + 5); + EXPECT_EQ(A2 ^ UINT64_MAX, A2 - N + ~N); +} + TEST(APIntTest, rvalue_arithmetic) { // Test all combinations of lvalue/rvalue lhs/rhs of add/sub