From 978661d05301a9bcd1222c048affef679da5ac43 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Sat, 6 Oct 2007 00:24:48 +0000 Subject: [PATCH] Generalize tcFullMultiply so that the operands can be of differing 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 | 10 ++++++---- lib/Support/APFloat.cpp | 7 ++++--- lib/Support/APInt.cpp | 33 ++++++++++++++++++++------------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 01b49d0864f..61e8f52fc7c 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -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 diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 3746ae8cfef..34784a0468e 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -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); diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 63bde6c4262..e7b7c1f4bb6 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -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); - assert(!overflow); + n = lhsParts + rhsParts; + + return n - (dst[n - 1] == 0); + } } /* If RHS is zero LHS and REMAINDER are left unchanged, return one.