[llvm-commits] [llvm] r42745 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Support/APInt.cpp

Neil Booth neil at daikokuya.co.uk
Mon Oct 8 06:47:13 PDT 2007


Author: neil
Date: Mon Oct  8 08:47:12 2007
New Revision: 42745

URL: http://llvm.org/viewvc/llvm-project?rev=42745&view=rev
Log:
Add a new function tcExtract for extracting a bignum from an
arbitrary range of bits embedded in the middle of another bignum.
This kind of operation is desirable in many cases of software
floating point, e.g. converting bignum integers to floating point
numbers of fixed precision (you want to extract the precision most
significant bits).

Elsewhere, add an assertion, and exit the shift functions early if
the shift count is zero.


Modified:
    llvm/trunk/include/llvm/ADT/APInt.h
    llvm/trunk/lib/Support/APInt.cpp

Modified: llvm/trunk/include/llvm/ADT/APInt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=42745&r1=42744&r2=42745&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/APInt.h (original)
+++ llvm/trunk/include/llvm/ADT/APInt.h Mon Oct  8 08:47:12 2007
@@ -1069,6 +1069,13 @@
   /// Extract the given bit of a bignum; returns 0 or 1.  Zero-based.
   static int tcExtractBit(const integerPart *, unsigned int bit);
 
+  /// Copy the bit vector of width srcBITS from SRC, starting at bit
+  /// srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB
+  /// becomes the least significant bit of DST.  All high bits above
+  /// srcBITS in DST are zero-filled.
+  static void tcExtract(integerPart *, unsigned int dstCount, const integerPart *,
+                        unsigned int srcBits, unsigned int srcLSB);
+
   /// Set the given bit of a bignum.  Zero-based.
   static void tcSetBit(integerPart *, unsigned int bit);
 

Modified: llvm/trunk/lib/Support/APInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=42745&r1=42744&r2=42745&view=diff

==============================================================================
--- llvm/trunk/lib/Support/APInt.cpp (original)
+++ llvm/trunk/lib/Support/APInt.cpp Mon Oct  8 08:47:12 2007
@@ -2101,6 +2101,8 @@
 {
   unsigned int i;
 
+  assert (parts > 0);
+
   dst[0] = part;
   for(i = 1; i < parts; i++)
     dst[i] = 0;
@@ -2182,6 +2184,42 @@
   return -1U;
 }
 
+/* Copy the bit vector of width srcBITS from SRC, starting at bit
+   srcLSB, to DST, of dstCOUNT parts, such that the bit srcLSB becomes
+   the least significant bit of DST.  All high bits above srcBITS in
+   DST are zero-filled.  */
+void
+APInt::tcExtract(integerPart *dst, unsigned int dstCount, const integerPart *src,
+                 unsigned int srcBits, unsigned int srcLSB)
+{
+  unsigned int firstSrcPart, dstParts, shift, n;
+
+  dstParts = (srcBits + integerPartWidth - 1) / integerPartWidth;
+  assert (dstParts <= dstCount);
+
+  firstSrcPart = srcLSB / integerPartWidth;
+  tcAssign (dst, src + firstSrcPart, dstParts);
+
+  shift = srcLSB % integerPartWidth;
+  tcShiftRight (dst, dstParts, shift);
+
+  /* We now have (dstParts * integerPartWidth - shift) bits from SRC
+     in DST.  If this is less that srcBits, append the rest, else
+     clear the high bits.  */
+  n = dstParts * integerPartWidth - shift;
+  if (n < srcBits) {
+    integerPart mask = lowBitMask (srcBits - n);
+    dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask)
+                          << n % integerPartWidth);
+  } else if (n > srcBits) {
+    dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth);
+  }
+
+  /* Clear high parts.  */
+  while (dstParts < dstCount)
+    dst[dstParts++] = 0;
+}
+
 /* DST += RHS + C where C is zero or one.  Returns the carry flag.  */
 integerPart
 APInt::tcAdd(integerPart *dst, const integerPart *rhs,
@@ -2451,31 +2489,33 @@
 void
 APInt::tcShiftLeft(integerPart *dst, unsigned int parts, unsigned int count)
 {
-  unsigned int jump, shift;
+  if (count) {
+    unsigned int jump, shift;
+
+    /* Jump is the inter-part jump; shift is is intra-part shift.  */
+    jump = count / integerPartWidth;
+    shift = count % integerPartWidth;
+
+    while (parts > jump) {
+      integerPart part;
+
+      parts--;
 
-  /* Jump is the inter-part jump; shift is is intra-part shift.  */
-  jump = count / integerPartWidth;
-  shift = count % integerPartWidth;
-
-  while (parts > jump) {
-    integerPart part;
-
-    parts--;
-
-    /* dst[i] comes from the two parts src[i - jump] and, if we have
-       an intra-part shift, src[i - jump - 1].  */
-    part = dst[parts - jump];
-    if (shift) {
-      part <<= shift;
+      /* dst[i] comes from the two parts src[i - jump] and, if we have
+         an intra-part shift, src[i - jump - 1].  */
+      part = dst[parts - jump];
+      if (shift) {
+        part <<= shift;
         if (parts >= jump + 1)
           part |= dst[parts - jump - 1] >> (integerPartWidth - shift);
       }
 
-    dst[parts] = part;
-  }
+      dst[parts] = part;
+    }
 
-  while (parts > 0)
-    dst[--parts] = 0;
+    while (parts > 0)
+      dst[--parts] = 0;
+  }
 }
 
 /* Shift a bignum right COUNT bits in-place.  Shifted in bits are
@@ -2483,29 +2523,31 @@
 void
 APInt::tcShiftRight(integerPart *dst, unsigned int parts, unsigned int count)
 {
-  unsigned int i, jump, shift;
-
-  /* Jump is the inter-part jump; shift is is intra-part shift.  */
-  jump = count / integerPartWidth;
-  shift = count % integerPartWidth;
+  if (count) {
+    unsigned int i, jump, shift;
 
-  /* Perform the shift.  This leaves the most significant COUNT bits
-     of the result at zero.  */
-  for(i = 0; i < parts; i++) {
-    integerPart part;
-
-    if (i + jump >= parts) {
-      part = 0;
-    } else {
-      part = dst[i + jump];
-      if (shift) {
-        part >>= shift;
-        if (i + jump + 1 < parts)
-          part |= dst[i + jump + 1] << (integerPartWidth - shift);
+    /* Jump is the inter-part jump; shift is is intra-part shift.  */
+    jump = count / integerPartWidth;
+    shift = count % integerPartWidth;
+
+    /* Perform the shift.  This leaves the most significant COUNT bits
+       of the result at zero.  */
+    for(i = 0; i < parts; i++) {
+      integerPart part;
+
+      if (i + jump >= parts) {
+        part = 0;
+      } else {
+        part = dst[i + jump];
+        if (shift) {
+          part >>= shift;
+          if (i + jump + 1 < parts)
+            part |= dst[i + jump + 1] << (integerPartWidth - shift);
+        }
       }
-    }
 
-    dst[i] = part;
+      dst[i] = part;
+    }
   }
 }
 





More information about the llvm-commits mailing list