[llvm-commits] CVS: llvm/lib/Support/APInt.cpp

Reid Spencer reid at x10sys.com
Sun May 13 16:45:23 PDT 2007



Changes in directory llvm/lib/Support:

APInt.cpp updated: 1.80 -> 1.81
---
Log message:

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.


---
Diffs of the changes:  (+67 -1)

 APInt.cpp |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 67 insertions(+), 1 deletion(-)


Index: llvm/lib/Support/APInt.cpp
diff -u llvm/lib/Support/APInt.cpp:1.80 llvm/lib/Support/APInt.cpp:1.81
--- llvm/lib/Support/APInt.cpp:1.80	Sat May 12 13:01:57 2007
+++ llvm/lib/Support/APInt.cpp	Sun May 13 18:44:59 2007
@@ -82,17 +82,23 @@
 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 @@
   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 @@
     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






More information about the llvm-commits mailing list