aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Support
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-14 20:35:54 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-14 20:35:54 +0800
commit97e5fbaa55b4672db36123c2425d05a4738452ab (patch)
treec2750bd49922edc8c76bc831ad7bfc8b0bf42bb8 /backend/lib/Support
parent8be4d04455f70892a94d1e0798e266c948b4750a (diff)
downloadrcc-project-97e5fbaa55b4672db36123c2425d05a4738452ab.tar.gz
rcc-project-97e5fbaa55b4672db36123c2425d05a4738452ab.tar.xz
[GlobalISel] Match LLVM legalization value tracking
Diffstat (limited to 'backend/lib/Support')
-rw-r--r--backend/lib/Support/APInt.cpp81
1 files changed, 66 insertions, 15 deletions
diff --git a/backend/lib/Support/APInt.cpp b/backend/lib/Support/APInt.cpp
index d54a4c2..74cbc56 100644
--- a/backend/lib/Support/APInt.cpp
+++ b/backend/lib/Support/APInt.cpp
@@ -138,16 +138,13 @@ Expected<APInt> APInt::fromSigned(std::uint32_t BitWidth, std::int64_t Value) {
return create(BitWidth, Words);
}
-Expected<APInt> APInt::getLowBitsSet(std::uint32_t BitWidth,
- std::uint32_t SetBitCount) {
+Expected<APInt> APInt::getLowBitsSet(std::uint32_t BitWidth, std::uint32_t SetBitCount) {
if (BitWidth == 0 || BitWidth > MaxBitWidth || SetBitCount > BitWidth)
- return makeUnexpected(ErrorCode::InvalidArgument,
- "APInt low-bit mask has an invalid width");
+ return makeUnexpected(ErrorCode::InvalidArgument, "APInt low-bit mask has an invalid width");
std::vector<std::uint64_t> Words(wordCount(BitWidth), 0);
const std::size_t FullWords = SetBitCount / 64U;
- std::ranges::fill_n(
- Words.begin(),
- static_cast<std::vector<std::uint64_t>::difference_type>(FullWords),
+ std::ranges::fill_n(Words.begin(),
+ static_cast<std::vector<std::uint64_t>::difference_type>(FullWords),
std::numeric_limits<std::uint64_t>::max());
const std::uint32_t RemainingBits = SetBitCount % 64U;
if (RemainingBits != 0)
@@ -256,20 +253,74 @@ std::size_t APInt::countrZero() const noexcept {
return Result;
}
+std::size_t APInt::countlOne() const noexcept {
+ std::size_t Result = 0;
+ for (std::size_t Bit = BitWidth; Bit != 0 && testBit(Bit - 1U); --Bit)
+ ++Result;
+ return Result;
+}
+
+bool APInt::isAllOnes() const noexcept {
+ return BitWidth != 0 && countlOne() == BitWidth;
+}
+
+bool APInt::testBit(std::size_t Bit) const noexcept {
+ return Bit < BitWidth && (Words[Bit / 64U] & (std::uint64_t{1} << (Bit % 64U))) != 0;
+}
+
std::uint64_t APInt::word(std::size_t Index) const noexcept {
return Index < Words.size() ? Words[Index] : 0;
}
+Expected<APInt> APInt::bitwiseAnd(const APInt &Other) const {
+ if (BitWidth == 0 || BitWidth != Other.BitWidth)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "APInt bitwise operands must have the same nonzero width");
+ std::vector<std::uint64_t> ResultWords(Words.size(), 0);
+ for (std::size_t Index = 0; Index != Words.size(); ++Index)
+ ResultWords[Index] = Words[Index] & Other.Words[Index];
+ return create(BitWidth, ResultWords);
+}
+
+Expected<APInt> APInt::bitwiseOr(const APInt &Other) const {
+ if (BitWidth == 0 || BitWidth != Other.BitWidth)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "APInt bitwise operands must have the same nonzero width");
+ std::vector<std::uint64_t> ResultWords(Words.size(), 0);
+ for (std::size_t Index = 0; Index != Words.size(); ++Index)
+ ResultWords[Index] = Words[Index] | Other.Words[Index];
+ return create(BitWidth, ResultWords);
+}
+
+Expected<APInt> APInt::bitwiseXor(const APInt &Other) const {
+ if (BitWidth == 0 || BitWidth != Other.BitWidth)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "APInt bitwise operands must have the same nonzero width");
+ std::vector<std::uint64_t> ResultWords(Words.size(), 0);
+ for (std::size_t Index = 0; Index != Words.size(); ++Index)
+ ResultWords[Index] = Words[Index] ^ Other.Words[Index];
+ return create(BitWidth, ResultWords);
+}
+
+Expected<APInt> APInt::bitwiseNot() const {
+ if (BitWidth == 0)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "APInt bitwise complement requires a nonzero width");
+ std::vector<std::uint64_t> ResultWords(Words.size(), 0);
+ for (std::size_t Index = 0; Index != Words.size(); ++Index)
+ ResultWords[Index] = ~Words[Index];
+ ResultWords.back() &= highWordMask(BitWidth);
+ return create(BitWidth, ResultWords);
+}
+
Expected<APInt> APInt::trunc(std::uint32_t NewBitWidth) const {
if (NewBitWidth == 0 || NewBitWidth >= BitWidth)
return makeUnexpected(ErrorCode::InvalidArgument,
"APInt truncation requires a smaller nonzero width");
std::vector<std::uint64_t> ResultWords(wordCount(NewBitWidth), 0);
- std::ranges::copy_n(
- Words.begin(),
- static_cast<std::vector<std::uint64_t>::difference_type>(
- ResultWords.size()),
- ResultWords.begin());
+ std::ranges::copy_n(Words.begin(),
+ static_cast<std::vector<std::uint64_t>::difference_type>(ResultWords.size()),
+ ResultWords.begin());
ResultWords.back() &= highWordMask(NewBitWidth);
return create(NewBitWidth, ResultWords);
}
@@ -287,9 +338,9 @@ Expected<APInt> APInt::sext(std::uint32_t NewBitWidth) const {
if (NewBitWidth <= BitWidth || NewBitWidth > MaxBitWidth)
return makeUnexpected(ErrorCode::InvalidArgument,
"APInt sign extension requires a larger supported width");
- std::vector<std::uint64_t> ResultWords(
- wordCount(NewBitWidth),
- isNegative() ? std::numeric_limits<std::uint64_t>::max() : std::uint64_t{0});
+ std::vector<std::uint64_t> ResultWords(wordCount(NewBitWidth),
+ isNegative() ? std::numeric_limits<std::uint64_t>::max()
+ : std::uint64_t{0});
std::ranges::copy(Words, ResultWords.begin());
if (isNegative() && BitWidth % 64U != 0)
ResultWords[wordCount(BitWidth) - 1U] |= ~highWordMask(BitWidth);