Generalize tcFullMultiply so that the operands can be of differing
authorNeil Booth <neil@daikokuya.co.uk>
Sat, 6 Oct 2007 00:24:48 +0000 (00:24 +0000)
committerNeil Booth <neil@daikokuya.co.uk>
Sat, 6 Oct 2007 00:24:48 +0000 (00:24 +0000)
part widths.  Also, return the number of parts actually required to
hold the result's value.
Remove an over-cautious condition from rounding of float->hex conversion.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42669 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APInt.h
lib/Support/APFloat.cpp
lib/Support/APInt.cpp

index 01b49d0864fb89b1e230c35283f82da751293448..61e8f52fc7c6242429d89934aa66f02f2bdad1cf 100644 (file)
@@ -1114,10 +1114,12 @@ public:
   static int tcMultiply(integerPart *, const integerPart *,
                        const integerPart *, unsigned);
 
-  /// DST = LHS * RHS, where DST has twice the width as the operands.
-  /// No overflow occurs.  DST must be disjoint from both operands.
-  static void tcFullMultiply(integerPart *, const integerPart *,
-                            const integerPart *, unsigned);
+  /// DST = LHS * RHS, where DST has width the sum of the widths of
+  /// the operands.  No overflow occurs.  DST must be disjoint from
+  /// both operands. Returns the number of parts required to hold the
+  /// result.
+  static unsigned int tcFullMultiply(integerPart *, const integerPart *,
+                                    const integerPart *, unsigned, unsigned);
 
   /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
   /// Otherwise set LHS to LHS / RHS with the fractional part
index 3746ae8cfefe328489c9f711192939bce49f29fd..34784a0468e41c91a18236f08cc2fc5272771ca5 100644 (file)
@@ -519,7 +519,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
   partsCount = partCount();
 
   APInt::tcFullMultiply(fullSignificand, lhsSignificand,
-                        rhs.significandParts(), partsCount);
+                        rhs.significandParts(), partsCount, partsCount);
 
   lost_fraction = lfExactlyZero;
   omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
@@ -1795,7 +1795,7 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
 
   /* hexDigits of zero means use the required number for the
      precision.  Otherwise, see if we are truncating.  If we are,
-     found out if we need to round away from zero.  */
+     find out if we need to round away from zero.  */
   if (hexDigits) {
     if (hexDigits < outputDigits) {
       /* We are dropping non-zero bits, so need to check how to round.
@@ -1845,7 +1845,8 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
     do {
       q--;
       *q = hexDigitChars[hexDigitValue (*q) + 1];
-    } while (*q == '0' && q > p);
+    } while (*q == '0');
+    assert (q >= p);
   } else {
     /* Add trailing zeroes.  */
     memset (dst, '0', outputDigits);
index 63bde6c426274aeb1808b5e826caa8022eaa53b8..e7b7c1f4bb62187787add2a0275fcd9ce6a1f90e 100644 (file)
@@ -2363,25 +2363,32 @@ APInt::tcMultiply(integerPart *dst, const integerPart *lhs,
   return overflow;
 }
 
-/* DST = LHS * RHS, where DST has twice the width as the operands.  No
-   overflow occurs.  DST must be disjoint from both operands.  */
-void
+/* DST = LHS * RHS, where DST has width the sum of the widths of the
+   operands.  No overflow occurs.  DST must be disjoint from both
+   operands.  Returns the number of parts required to hold the
+   result.  */
+unsigned int
 APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs,
-                      const integerPart *rhs, unsigned int parts)
+                      const integerPart *rhs, unsigned int lhsParts,
+                      unsigned int rhsParts)
 {
-  unsigned int i;
-  int overflow;
+  /* Put the narrower number on the LHS for less loops below.  */
+  if (lhsParts > rhsParts) {
+    return tcFullMultiply (dst, rhs, lhs, rhsParts, lhsParts);
+  } else {
+    unsigned int n;
 
-  assert(dst != lhs && dst != rhs);
+    assert(dst != lhs && dst != rhs);
 
-  overflow = 0;
-  tcSet(dst, 0, parts);
+    tcSet(dst, 0, rhsParts);
 
-  for(i = 0; i < parts; i++)
-    overflow |= tcMultiplyPart(&dst[i], lhs, rhs[i], 0, parts,
-                               parts + 1, true);
+    for(n = 0; n < lhsParts; n++)
+      tcMultiplyPart(&dst[n], rhs, lhs[n], 0, rhsParts, rhsParts + 1, true);
+
+    n = lhsParts + rhsParts;
 
-  assert(!overflow);
+    return n - (dst[n - 1] == 0);
+  }
 }
 
 /* If RHS is zero LHS and REMAINDER are left unchanged, return one.