aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.co.uk>2007-10-06 00:24:48 +0000
committerNeil Booth <neil@daikokuya.co.uk>2007-10-06 00:24:48 +0000
commit004e9f4e25776a508bec14104b7d09d0a2311ce0 (patch)
tree4a83b82f779dfebaa904148fec9cd9373df1dc11 /lib/Support
parent1456bacbabfd337ea6bdf99fff172c8c364c0b9f (diff)
downloadexternal_llvm-004e9f4e25776a508bec14104b7d09d0a2311ce0.zip
external_llvm-004e9f4e25776a508bec14104b7d09d0a2311ce0.tar.gz
external_llvm-004e9f4e25776a508bec14104b7d09d0a2311ce0.tar.bz2
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
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp7
-rw-r--r--lib/Support/APInt.cpp33
2 files changed, 24 insertions, 16 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 3746ae8..34784a0 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 63bde6c..e7b7c1f 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);
+
+ n = lhsParts + rhsParts;
- assert(!overflow);
+ return n - (dst[n - 1] == 0);
+ }
}
/* If RHS is zero LHS and REMAINDER are left unchanged, return one.