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
This commit is contained in:
Neil Booth 2007-10-06 00:24:48 +00:00
parent 88cc699942
commit 978661d053
3 changed files with 30 additions and 20 deletions

View 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

View 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);

View 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);
assert(!overflow);
n = lhsParts + rhsParts;
return n - (dst[n - 1] == 0);
}
}
/* If RHS is zero LHS and REMAINDER are left unchanged, return one.