aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Support/APInt.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r--llvm/lib/Support/APInt.cpp79
1 files changed, 76 insertions, 3 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 758fe8b4f866..9b9cd70078b3 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -187,7 +187,7 @@ APInt& APInt::operator--() {
return clearUnusedBits();
}
-/// Adds the RHS APint to this APInt.
+/// Adds the RHS APInt to this APInt.
/// @returns this, after addition of RHS.
/// Addition assignment operator.
APInt& APInt::operator+=(const APInt& RHS) {
@@ -884,6 +884,31 @@ APInt APInt::trunc(unsigned width) const {
return Result;
}
+// Truncate to new width with unsigned saturation.
+APInt APInt::truncUSat(unsigned width) const {
+ assert(width < BitWidth && "Invalid APInt Truncate request");
+ assert(width && "Can't truncate to 0 bits");
+
+ // Can we just losslessly truncate it?
+ if (isIntN(width))
+ return trunc(width);
+ // If not, then just return the new limit.
+ return APInt::getMaxValue(width);
+}
+
+// Truncate to new width with signed saturation.
+APInt APInt::truncSSat(unsigned width) const {
+ assert(width < BitWidth && "Invalid APInt Truncate request");
+ assert(width && "Can't truncate to 0 bits");
+
+ // Can we just losslessly truncate it?
+ if (isSignedIntN(width))
+ return trunc(width);
+ // If not, then just return the new limits.
+ return isNegative() ? APInt::getSignedMinValue(width)
+ : APInt::getSignedMaxValue(width);
+}
+
// Sign extend to a new width.
APInt APInt::sext(unsigned Width) const {
assert(Width > BitWidth && "Invalid APInt SignExtend request");
@@ -2048,6 +2073,46 @@ APInt APInt::usub_sat(const APInt &RHS) const {
return APInt(BitWidth, 0);
}
+APInt APInt::smul_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = smul_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ // The result is negative if one and only one of inputs is negative.
+ bool ResIsNegative = isNegative() ^ RHS.isNegative();
+
+ return ResIsNegative ? APInt::getSignedMinValue(BitWidth)
+ : APInt::getSignedMaxValue(BitWidth);
+}
+
+APInt APInt::umul_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = umul_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return APInt::getMaxValue(BitWidth);
+}
+
+APInt APInt::sshl_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = sshl_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return isNegative() ? APInt::getSignedMinValue(BitWidth)
+ : APInt::getSignedMaxValue(BitWidth);
+}
+
+APInt APInt::ushl_sat(const APInt &RHS) const {
+ bool Overflow;
+ APInt Res = ushl_ov(RHS, Overflow);
+ if (!Overflow)
+ return Res;
+
+ return APInt::getMaxValue(BitWidth);
+}
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
// Check our assumptions here
@@ -2790,7 +2855,7 @@ APInt llvm::APIntOps::RoundingSDiv(const APInt &A, const APInt &B,
return Quo;
return Quo + 1;
}
- // Currently sdiv rounds twards zero.
+ // Currently sdiv rounds towards zero.
case APInt::Rounding::TOWARD_ZERO:
return A.sdiv(B);
}
@@ -2933,7 +2998,7 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
APInt Q = SQ * SQ;
bool InexactSQ = Q != D;
// The calculated SQ may actually be greater than the exact (non-integer)
- // value. If that's the case, decremement SQ to get a value that is lower.
+ // value. If that's the case, decrement SQ to get a value that is lower.
if (Q.sgt(D))
SQ -= 1;
@@ -2987,6 +3052,14 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
return X;
}
+Optional<unsigned>
+llvm::APIntOps::GetMostSignificantDifferentBit(const APInt &A, const APInt &B) {
+ assert(A.getBitWidth() == B.getBitWidth() && "Must have the same bitwidth");
+ if (A == B)
+ return llvm::None;
+ return A.getBitWidth() - ((A ^ B).countLeadingZeros() + 1);
+}
+
/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
/// with the integer held in IntVal.
void llvm::StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,