diff options
author | Neil Booth <neil@daikokuya.co.uk> | 2007-09-22 02:56:19 +0000 |
---|---|---|
committer | Neil Booth <neil@daikokuya.co.uk> | 2007-09-22 02:56:19 +0000 |
commit | c8db43ddaf1c1f484ea08dff6fb61e5fa18352bc (patch) | |
tree | 656b2dc9519aa5593c04a73759c060b92d5d7943 /lib | |
parent | d3989a820c3f99bd22516878144e0ed780153acf (diff) | |
download | external_llvm-c8db43ddaf1c1f484ea08dff6fb61e5fa18352bc.zip external_llvm-c8db43ddaf1c1f484ea08dff6fb61e5fa18352bc.tar.gz external_llvm-c8db43ddaf1c1f484ea08dff6fb61e5fa18352bc.tar.bz2 |
Handle storage complications of float->float conversions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42220 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Support/APFloat.cpp | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 1fab6ca..2b9930c 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1318,39 +1318,44 @@ APFloat::opStatus APFloat::convert(const fltSemantics &toSemantics, roundingMode rounding_mode) { - unsigned int newPartCount; + lostFraction lostFraction; + unsigned int newPartCount, oldPartCount; opStatus fs; - + + lostFraction = lfExactlyZero; newPartCount = partCountForBits(toSemantics.precision + 1); + oldPartCount = partCount(); - /* If our new form is wider, re-allocate our bit pattern into wider - storage. - If we're narrowing from multiple words to 1 words, copy to the single - word. If we are losing information by doing this, we would have to - worry about rounding; right now the only case is f80 -> shorter - conversion, and we are keeping all 64 significant bits, so it's OK. */ - if(newPartCount > partCount()) { + /* Handle storage complications. If our new form is wider, + re-allocate our bit pattern into wider storage. If it is + narrower, we ignore the excess parts, but if narrowing to a + single part we need to free the old storage. */ + if (newPartCount > oldPartCount) { integerPart *newParts; newParts = new integerPart[newPartCount]; APInt::tcSet(newParts, 0, newPartCount); - APInt::tcAssign(newParts, significandParts(), partCount()); + APInt::tcAssign(newParts, significandParts(), oldPartCount); freeSignificand(); significand.parts = newParts; - } else if (newPartCount==1 && newPartCount < partCount()) { - integerPart newPart; - - APInt::tcSet(&newPart, 0, newPartCount); - APInt::tcAssign(&newPart, significandParts(), partCount()); - freeSignificand(); - significand.part = newPart; + } else if (newPartCount < oldPartCount) { + /* Capture any lost fraction through truncation of parts so we get + correct rounding whilst normalizing. */ + lostFraction = lostFractionThroughTruncation + (significandParts(), oldPartCount, toSemantics.precision); + if (newPartCount == 1) + { + integerPart newPart = significandParts()[0]; + freeSignificand(); + significand.part = newPart; + } } if(category == fcNormal) { /* Re-interpret our bit-pattern. */ exponent += toSemantics.precision - semantics->precision; semantics = &toSemantics; - fs = normalize(rounding_mode, lfExactlyZero); + fs = normalize(rounding_mode, lostFraction); } else { semantics = &toSemantics; fs = opOK; |