aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2007-05-13 23:44:59 +0000
committerReid Spencer <rspencer@reidspencer.com>2007-05-13 23:44:59 +0000
commit19dc32a2d422ac0aafd047514e3e5e727796696e (patch)
tree5fc3fd6136231d28fda221c83f4abe84faeeebd1 /lib/Support
parent9273418777fb0c25da9067d6eec57402a504e94e (diff)
downloadexternal_llvm-19dc32a2d422ac0aafd047514e3e5e727796696e.zip
external_llvm-19dc32a2d422ac0aafd047514e3e5e727796696e.tar.gz
external_llvm-19dc32a2d422ac0aafd047514e3e5e727796696e.tar.bz2
Add some things needed by the llvm-gcc version supporting bit accurate integer
types: 1. Functions to compute div/rem at the same time. 2. Further assurance that an APInt with 0 bitwidth cannot be constructed. 3. Left and right rotate operations. 4. An exactLogBase2 function which requires an exact power of two or it returns -1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37025 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APInt.cpp68
1 files changed, 67 insertions, 1 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 2a35aa0..3501774 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -82,17 +82,23 @@ APInt::APInt(uint32_t numBits, uint32_t numWords, uint64_t bigVal[])
APInt::APInt(uint32_t numbits, const char StrStart[], uint32_t slen,
uint8_t radix)
: BitWidth(numbits), VAL(0) {
+ assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
+ assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
fromString(numbits, StrStart, slen, radix);
}
APInt::APInt(uint32_t numbits, const std::string& Val, uint8_t radix)
: BitWidth(numbits), VAL(0) {
+ assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
+ assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
assert(!Val.empty() && "String empty?");
fromString(numbits, Val.c_str(), Val.size(), radix);
}
APInt::APInt(const APInt& that)
: BitWidth(that.BitWidth), VAL(0) {
+ assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
+ assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
if (isSingleWord())
VAL = that.VAL;
else {
@@ -1242,6 +1248,23 @@ APInt APInt::shl(uint32_t shiftAmt) const {
return APInt(val, BitWidth).clearUnusedBits();
}
+APInt APInt::rotl(uint32_t rotateAmt) const {
+ // Don't get too fancy, just use existing shift/or facilities
+ APInt hi(*this);
+ APInt lo(*this);
+ hi.shl(rotateAmt);
+ lo.lshr(BitWidth - rotateAmt);
+ return hi | lo;
+}
+
+APInt APInt::rotr(uint32_t rotateAmt) const {
+ // Don't get too fancy, just use existing shift/or facilities
+ APInt hi(*this);
+ APInt lo(*this);
+ lo.lshr(rotateAmt);
+ hi.shl(BitWidth - rotateAmt);
+ return hi | lo;
+}
// Square Root - this method computes and returns the square root of "this".
// Three mechanisms are used for computation. For small values (<= 5 bits),
@@ -1754,12 +1777,55 @@ APInt APInt::urem(const APInt& RHS) const {
return APInt(BitWidth, pVal[0] % RHS.pVal[0]);
}
- // We have to compute it the hard way. Invoke the Knute divide algorithm.
+ // We have to compute it the hard way. Invoke the Knuth divide algorithm.
APInt Remainder(1,0);
divide(*this, lhsWords, RHS, rhsWords, 0, &Remainder);
return Remainder;
}
+void APInt::udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder) {
+ // Get some size facts about the dividend and divisor
+ uint32_t lhsBits = LHS.getActiveBits();
+ uint32_t lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);
+ uint32_t rhsBits = RHS.getActiveBits();
+ uint32_t rhsWords = !rhsBits ? 0 : (APInt::whichWord(rhsBits - 1) + 1);
+
+ // Check the degenerate cases
+ if (lhsWords == 0) {
+ Quotient = 0; // 0 / Y ===> 0
+ Remainder = 0; // 0 % Y ===> 0
+ return;
+ }
+
+ if (lhsWords < rhsWords || LHS.ult(RHS)) {
+ Quotient = 0; // X / Y ===> 0, iff X < Y
+ Remainder = LHS; // X % Y ===> X, iff X < Y
+ return;
+ }
+
+ if (LHS == RHS) {
+ Quotient = 1; // X / X ===> 1
+ Remainder = 0; // X % X ===> 0;
+ return;
+ }
+
+ if (lhsWords == 1 && rhsWords == 1) {
+ // There is only one word to consider so use the native versions.
+ if (LHS.isSingleWord()) {
+ Quotient = APInt(LHS.getBitWidth(), LHS.VAL / RHS.VAL);
+ Remainder = APInt(LHS.getBitWidth(), LHS.VAL % RHS.VAL);
+ } else {
+ Quotient = APInt(LHS.getBitWidth(), LHS.pVal[0] / RHS.pVal[0]);
+ Remainder = APInt(LHS.getBitWidth(), LHS.pVal[0] % RHS.pVal[0]);
+ }
+ return;
+ }
+
+ // Okay, lets do it the long way
+ divide(LHS, lhsWords, RHS, rhsWords, &Quotient, &Remainder);
+}
+
void APInt::fromString(uint32_t numbits, const char *str, uint32_t slen,
uint8_t radix) {
// Check our assumptions here