mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
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:
parent
88cc699942
commit
978661d053
@ -1114,10 +1114,12 @@ public:
|
|||||||
static int tcMultiply(integerPart *, const integerPart *,
|
static int tcMultiply(integerPart *, const integerPart *,
|
||||||
const integerPart *, unsigned);
|
const integerPart *, unsigned);
|
||||||
|
|
||||||
/// DST = LHS * RHS, where DST has twice the width as the operands.
|
/// DST = LHS * RHS, where DST has width the sum of the widths of
|
||||||
/// No overflow occurs. DST must be disjoint from both operands.
|
/// the operands. No overflow occurs. DST must be disjoint from
|
||||||
static void tcFullMultiply(integerPart *, const integerPart *,
|
/// both operands. Returns the number of parts required to hold the
|
||||||
const integerPart *, unsigned);
|
/// result.
|
||||||
|
static unsigned int tcFullMultiply(integerPart *, const integerPart *,
|
||||||
|
const integerPart *, unsigned, unsigned);
|
||||||
|
|
||||||
/// If RHS is zero LHS and REMAINDER are left unchanged, return one.
|
/// If RHS is zero LHS and REMAINDER are left unchanged, return one.
|
||||||
/// Otherwise set LHS to LHS / RHS with the fractional part
|
/// Otherwise set LHS to LHS / RHS with the fractional part
|
||||||
|
@ -519,7 +519,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
|
|||||||
partsCount = partCount();
|
partsCount = partCount();
|
||||||
|
|
||||||
APInt::tcFullMultiply(fullSignificand, lhsSignificand,
|
APInt::tcFullMultiply(fullSignificand, lhsSignificand,
|
||||||
rhs.significandParts(), partsCount);
|
rhs.significandParts(), partsCount, partsCount);
|
||||||
|
|
||||||
lost_fraction = lfExactlyZero;
|
lost_fraction = lfExactlyZero;
|
||||||
omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
|
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
|
/* hexDigits of zero means use the required number for the
|
||||||
precision. Otherwise, see if we are truncating. If we are,
|
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) {
|
||||||
if (hexDigits < outputDigits) {
|
if (hexDigits < outputDigits) {
|
||||||
/* We are dropping non-zero bits, so need to check how to round.
|
/* 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 {
|
do {
|
||||||
q--;
|
q--;
|
||||||
*q = hexDigitChars[hexDigitValue (*q) + 1];
|
*q = hexDigitChars[hexDigitValue (*q) + 1];
|
||||||
} while (*q == '0' && q > p);
|
} while (*q == '0');
|
||||||
|
assert (q >= p);
|
||||||
} else {
|
} else {
|
||||||
/* Add trailing zeroes. */
|
/* Add trailing zeroes. */
|
||||||
memset (dst, '0', outputDigits);
|
memset (dst, '0', outputDigits);
|
||||||
|
@ -2363,25 +2363,32 @@ APInt::tcMultiply(integerPart *dst, const integerPart *lhs,
|
|||||||
return overflow;
|
return overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DST = LHS * RHS, where DST has twice the width as the operands. No
|
/* DST = LHS * RHS, where DST has width the sum of the widths of the
|
||||||
overflow occurs. DST must be disjoint from both operands. */
|
operands. No overflow occurs. DST must be disjoint from both
|
||||||
void
|
operands. Returns the number of parts required to hold the
|
||||||
|
result. */
|
||||||
|
unsigned int
|
||||||
APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs,
|
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;
|
/* Put the narrower number on the LHS for less loops below. */
|
||||||
int overflow;
|
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, rhsParts);
|
||||||
tcSet(dst, 0, parts);
|
|
||||||
|
|
||||||
for(i = 0; i < parts; i++)
|
for(n = 0; n < lhsParts; n++)
|
||||||
overflow |= tcMultiplyPart(&dst[i], lhs, rhs[i], 0, parts,
|
tcMultiplyPart(&dst[n], rhs, lhs[n], 0, rhsParts, rhsParts + 1, true);
|
||||||
parts + 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.
|
/* If RHS is zero LHS and REMAINDER are left unchanged, return one.
|
||||||
|
Loading…
Reference in New Issue
Block a user