/// out-of-line slow case for shl
APInt shlSlowCase(unsigned shiftAmt) const;
- /// out-of-line slow case for operator&
- APInt AndSlowCase(const APInt &RHS) const;
-
- /// out-of-line slow case for operator|
- APInt OrSlowCase(const APInt &RHS) const;
-
- /// out-of-line slow case for operator^
- APInt XorSlowCase(const APInt &RHS) const;
-
/// out-of-line slow case for operator=
APInt &AssignSlowCase(const APInt &RHS);
/// \name Binary Operators
/// @{
- /// \brief Bitwise AND operator.
- ///
- /// Performs a bitwise AND operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise AND of *this and RHS.
- APInt operator&(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(getBitWidth(), VAL & RHS.VAL);
- return AndSlowCase(RHS);
- }
-
- /// \brief Bitwise OR operator.
- ///
- /// Performs a bitwise OR operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise OR of *this and RHS.
- APInt operator|(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(getBitWidth(), VAL | RHS.VAL);
- return OrSlowCase(RHS);
- }
-
- /// \brief Bitwise XOR operator.
- ///
- /// Performs a bitwise XOR operation on *this and RHS.
- ///
- /// \returns An APInt value representing the bitwise XOR of *this and RHS.
- APInt operator^(const APInt &RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(BitWidth, VAL ^ RHS.VAL);
- return XorSlowCase(RHS);
- }
-
/// \brief Multiplication operator.
///
/// Multiplies this APInt by RHS and returns the result.
/// This operation tests if there are any pairs of corresponding bits
/// between this APInt and RHS that are both set.
- bool intersects(const APInt &RHS) const { return (*this & RHS) != 0; }
+ bool intersects(const APInt &RHS) const {
+ APInt temp(*this);
+ temp &= RHS;
+ return temp != 0;
+ }
/// @}
/// \name Resizing Operators
return v;
}
+inline APInt operator&(APInt a, const APInt &b) {
+ a &= b;
+ return a;
+}
+
+inline APInt operator&(const APInt &a, APInt &&b) {
+ b &= a;
+ return std::move(b);
+}
+
inline APInt operator&(APInt a, uint64_t RHS) {
a &= RHS;
return a;
return b;
}
+inline APInt operator|(APInt a, const APInt &b) {
+ a |= b;
+ return a;
+}
+
+inline APInt operator|(const APInt &a, APInt &&b) {
+ b |= a;
+ return std::move(b);
+}
+
inline APInt operator|(APInt a, uint64_t RHS) {
a |= RHS;
return a;
return b;
}
+inline APInt operator^(APInt a, const APInt &b) {
+ a ^= b;
+ return a;
+}
+
+inline APInt operator^(const APInt &a, APInt &&b) {
+ b ^= a;
+ return std::move(b);
+}
+
inline APInt operator^(APInt a, uint64_t RHS) {
a ^= RHS;
return a;
return *this;
}
-APInt APInt::AndSlowCase(const APInt& RHS) const {
- unsigned numWords = getNumWords();
- uint64_t* val = getMemory(numWords);
- for (unsigned i = 0; i < numWords; ++i)
- val[i] = pVal[i] & RHS.pVal[i];
- return APInt(val, getBitWidth());
-}
-
-APInt APInt::OrSlowCase(const APInt& RHS) const {
- unsigned numWords = getNumWords();
- uint64_t *val = getMemory(numWords);
- for (unsigned i = 0; i < numWords; ++i)
- val[i] = pVal[i] | RHS.pVal[i];
- return APInt(val, getBitWidth());
-}
-
-APInt APInt::XorSlowCase(const APInt& RHS) const {
- unsigned numWords = getNumWords();
- uint64_t *val = getMemory(numWords);
- for (unsigned i = 0; i < numWords; ++i)
- val[i] = pVal[i] ^ RHS.pVal[i];
-
- return APInt(val, getBitWidth());
-}
-
APInt APInt::operator*(const APInt& RHS) const {
assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
if (isSingleWord())
}
}
+TEST(APIntTest, rvalue_bitwise) {
+ // Test all combinations of lvalue/rvalue lhs/rhs of and/or/xor
+
+ // Lamdba to return an APInt by value, but also provide the raw value of the
+ // allocated data.
+ auto getRValue = [](const char *HexString, uint64_t const *&RawData) {
+ APInt V(129, HexString, 16);
+ RawData = V.getRawData();
+ return V;
+ };
+
+ APInt Ten(129, "A", 16);
+ APInt Twelve(129, "C", 16);
+
+ const uint64_t *RawDataL = nullptr;
+ const uint64_t *RawDataR = nullptr;
+
+ {
+ // 12 & 10 = 8
+ APInt AndLL = Ten & Twelve;
+ EXPECT_EQ(AndLL, 0x8);
+
+ APInt AndLR = Ten & getRValue("C", RawDataR);
+ EXPECT_EQ(AndLR, 0x8);
+ EXPECT_EQ(AndLR.getRawData(), RawDataR);
+
+ APInt AndRL = getRValue("A", RawDataL) & Twelve;
+ EXPECT_EQ(AndRL, 0x8);
+ EXPECT_EQ(AndRL.getRawData(), RawDataL);
+
+ APInt AndRR = getRValue("A", RawDataL) & getRValue("C", RawDataR);
+ EXPECT_EQ(AndRR, 0x8);
+ EXPECT_EQ(AndRR.getRawData(), RawDataR);
+
+ // LValue's and constants
+ APInt AndLK = Ten & 0xc;
+ EXPECT_EQ(AndLK, 0x8);
+
+ APInt AndKL = 0xa & Twelve;
+ EXPECT_EQ(AndKL, 0x8);
+
+ // RValue's and constants
+ APInt AndRK = getRValue("A", RawDataL) & 0xc;
+ EXPECT_EQ(AndRK, 0x8);
+ EXPECT_EQ(AndRK.getRawData(), RawDataL);
+
+ APInt AndKR = 0xa & getRValue("C", RawDataR);
+ EXPECT_EQ(AndKR, 0x8);
+ EXPECT_EQ(AndKR.getRawData(), RawDataR);
+ }
+
+ {
+ // 12 | 10 = 14
+ APInt OrLL = Ten | Twelve;
+ EXPECT_EQ(OrLL, 0xe);
+
+ APInt OrLR = Ten | getRValue("C", RawDataR);
+ EXPECT_EQ(OrLR, 0xe);
+ EXPECT_EQ(OrLR.getRawData(), RawDataR);
+
+ APInt OrRL = getRValue("A", RawDataL) | Twelve;
+ EXPECT_EQ(OrRL, 0xe);
+ EXPECT_EQ(OrRL.getRawData(), RawDataL);
+
+ APInt OrRR = getRValue("A", RawDataL) | getRValue("C", RawDataR);
+ EXPECT_EQ(OrRR, 0xe);
+ EXPECT_EQ(OrRR.getRawData(), RawDataR);
+
+ // LValue's and constants
+ APInt OrLK = Ten | 0xc;
+ EXPECT_EQ(OrLK, 0xe);
+
+ APInt OrKL = 0xa | Twelve;
+ EXPECT_EQ(OrKL, 0xe);
+
+ // RValue's and constants
+ APInt OrRK = getRValue("A", RawDataL) | 0xc;
+ EXPECT_EQ(OrRK, 0xe);
+ EXPECT_EQ(OrRK.getRawData(), RawDataL);
+
+ APInt OrKR = 0xa | getRValue("C", RawDataR);
+ EXPECT_EQ(OrKR, 0xe);
+ EXPECT_EQ(OrKR.getRawData(), RawDataR);
+ }
+
+ {
+ // 12 ^ 10 = 6
+ APInt XorLL = Ten ^ Twelve;
+ EXPECT_EQ(XorLL, 0x6);
+
+ APInt XorLR = Ten ^ getRValue("C", RawDataR);
+ EXPECT_EQ(XorLR, 0x6);
+ EXPECT_EQ(XorLR.getRawData(), RawDataR);
+
+ APInt XorRL = getRValue("A", RawDataL) ^ Twelve;
+ EXPECT_EQ(XorRL, 0x6);
+ EXPECT_EQ(XorRL.getRawData(), RawDataL);
+
+ APInt XorRR = getRValue("A", RawDataL) ^ getRValue("C", RawDataR);
+ EXPECT_EQ(XorRR, 0x6);
+ EXPECT_EQ(XorRR.getRawData(), RawDataR);
+
+ // LValue's and constants
+ APInt XorLK = Ten ^ 0xc;
+ EXPECT_EQ(XorLK, 0x6);
+
+ APInt XorKL = 0xa ^ Twelve;
+ EXPECT_EQ(XorKL, 0x6);
+
+ // RValue's and constants
+ APInt XorRK = getRValue("A", RawDataL) ^ 0xc;
+ EXPECT_EQ(XorRK, 0x6);
+ EXPECT_EQ(XorRK.getRawData(), RawDataL);
+
+ APInt XorKR = 0xa ^ getRValue("C", RawDataR);
+ EXPECT_EQ(XorKR, 0x6);
+ EXPECT_EQ(XorKR.getRawData(), RawDataR);
+ }
+}
+
TEST(APIntTest, rvalue_invert) {
// Lamdba to return an APInt by value, but also provide the raw value of the
// allocated data.