From: Neil Booth Date: Sun, 7 Oct 2007 12:07:53 +0000 (+0000) Subject: Reimplement convertFromUnsignedInteger so it is passed a const bignum. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=643ce59495702ef29573b725d7431638be1c136a;p=oota-llvm.git Reimplement convertFromUnsignedInteger so it is passed a const bignum. It used to modify its argument in-place. This interface is saner and the implementation more efficient. It will be needed for decimal->binary conversion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42733 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 7505269c68c..67c979cece5 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -266,8 +266,8 @@ namespace llvm { cmpResult compareAbsoluteValue(const APFloat &) const; opStatus handleOverflow(roundingMode); bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; - opStatus convertFromUnsignedInteger(integerPart *, unsigned int, - roundingMode); + opStatus convertFromUnsignedParts(const integerPart *, unsigned int, + roundingMode); opStatus convertFromHexadecimalString(const char *, roundingMode); char *convertNormalToHexString(char *, unsigned int, bool, roundingMode) const; diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 5e3504b19a5..7e56c849a5e 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1548,30 +1548,41 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width, return opInexact; } +/* Convert an unsigned integer SRC to a floating point number, + rounding according to ROUNDING_MODE. The sign of the floating + point number is not modified. */ APFloat::opStatus -APFloat::convertFromUnsignedInteger(integerPart *parts, - unsigned int partCount, - roundingMode rounding_mode) +APFloat::convertFromUnsignedParts(const integerPart *src, + unsigned int srcCount, + roundingMode rounding_mode) { - unsigned int msb, precision; + unsigned int dstCount; lostFraction lost_fraction; - - msb = APInt::tcMSB(parts, partCount) + 1; - precision = semantics->precision; + integerPart *dst; category = fcNormal; - exponent = precision - 1; + exponent = semantics->precision - 1; - if(msb > precision) { - exponent += (msb - precision); - lost_fraction = shiftRight(parts, partCount, msb - precision); - msb = precision; - } else - lost_fraction = lfExactlyZero; + dst = significandParts(); + dstCount = partCount(); - /* Copy the bit image. */ - zeroSignificand(); - APInt::tcAssign(significandParts(), parts, partCountForBits(msb)); + /* We need to capture the non-zero most significant parts. */ + while (srcCount > dstCount && src[srcCount - 1] == 0) + srcCount--; + + /* Copy the bit image of as many parts as we can. If we are wider, + zero-out remaining parts. */ + if (dstCount >= srcCount) { + APInt::tcAssign(dst, src, srcCount); + while (srcCount < dstCount) + dst[srcCount++] = 0; + lost_fraction = lfExactlyZero; + } else { + exponent += (srcCount - dstCount) * integerPartWidth; + APInt::tcAssign(dst, src + (srcCount - dstCount), dstCount); + lost_fraction = lostFractionThroughTruncation(src, srcCount, + dstCount * integerPartWidth); + } return normalize(rounding_mode, lost_fraction); } @@ -1594,7 +1605,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, } APInt::tcAssign(copy, api.getRawData(), partCount); - status = convertFromUnsignedInteger(copy, partCount, rounding_mode); + status = convertFromUnsignedParts(copy, partCount, rounding_mode); return status; }