aboutsummaryrefslogtreecommitdiff
path: root/backend/lib/Support
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-14 04:33:41 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-14 04:33:41 +0800
commit8be4d04455f70892a94d1e0798e266c948b4750a (patch)
tree6ef304317a6980ecfbe32868d64cd05f5e8af8bd /backend/lib/Support
parentaa69e15c6909c3b162b15f5326f0a72ba9bb7163 (diff)
downloadrcc-project-8be4d04455f70892a94d1e0798e266c948b4750a.tar.gz
rcc-project-8be4d04455f70892a94d1e0798e266c948b4750a.tar.xz
[CodeGen] Match LLVM Legalizer ownership
Diffstat (limited to 'backend/lib/Support')
-rw-r--r--backend/lib/Support/APInt.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/backend/lib/Support/APInt.cpp b/backend/lib/Support/APInt.cpp
index 898deee..d54a4c2 100644
--- a/backend/lib/Support/APInt.cpp
+++ b/backend/lib/Support/APInt.cpp
@@ -138,6 +138,23 @@ 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) {
+ if (BitWidth == 0 || BitWidth > MaxBitWidth || SetBitCount > BitWidth)
+ 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::numeric_limits<std::uint64_t>::max());
+ const std::uint32_t RemainingBits = SetBitCount % 64U;
+ if (RemainingBits != 0)
+ Words[FullWords] = (std::uint64_t{1} << RemainingBits) - 1U;
+ return create(BitWidth, Words);
+}
+
Expected<APInt> APInt::parseDecimal(std::uint32_t BitWidth, std::string_view Text) {
if (BitWidth == 0 || BitWidth > MaxBitWidth)
return makeUnexpected(ErrorCode::ParseError, "APInt bit width is outside the supported range");
@@ -243,6 +260,43 @@ std::uint64_t APInt::word(std::size_t Index) const noexcept {
return Index < Words.size() ? Words[Index] : 0;
}
+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());
+ ResultWords.back() &= highWordMask(NewBitWidth);
+ return create(NewBitWidth, ResultWords);
+}
+
+Expected<APInt> APInt::zext(std::uint32_t NewBitWidth) const {
+ if (NewBitWidth <= BitWidth || NewBitWidth > MaxBitWidth)
+ return makeUnexpected(ErrorCode::InvalidArgument,
+ "APInt zero extension requires a larger supported width");
+ std::vector<std::uint64_t> ResultWords(wordCount(NewBitWidth), 0);
+ std::ranges::copy(Words, ResultWords.begin());
+ return create(NewBitWidth, ResultWords);
+}
+
+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::ranges::copy(Words, ResultWords.begin());
+ if (isNegative() && BitWidth % 64U != 0)
+ ResultWords[wordCount(BitWidth) - 1U] |= ~highWordMask(BitWidth);
+ ResultWords.back() &= highWordMask(NewBitWidth);
+ return create(NewBitWidth, ResultWords);
+}
+
int APInt::compare(const APInt &Other) const noexcept {
const std::size_t LeftCount = significantWordCount(Words);
const std::size_t RightCount = significantWordCount(Other.Words);