Handle storage complications of float->float conversions.

llvm-svn: 42220
This commit is contained in:
Neil Booth 2007-09-22 02:56:19 +00:00
parent cf3e26fff2
commit a8d7269269
1 changed files with 23 additions and 18 deletions

View File

@ -1318,39 +1318,44 @@ APFloat::opStatus
APFloat::convert(const fltSemantics &toSemantics, APFloat::convert(const fltSemantics &toSemantics,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
unsigned int newPartCount; lostFraction lostFraction;
unsigned int newPartCount, oldPartCount;
opStatus fs; opStatus fs;
lostFraction = lfExactlyZero;
newPartCount = partCountForBits(toSemantics.precision + 1); newPartCount = partCountForBits(toSemantics.precision + 1);
oldPartCount = partCount();
/* If our new form is wider, re-allocate our bit pattern into wider /* Handle storage complications. If our new form is wider,
storage. re-allocate our bit pattern into wider storage. If it is
If we're narrowing from multiple words to 1 words, copy to the single narrower, we ignore the excess parts, but if narrowing to a
word. If we are losing information by doing this, we would have to single part we need to free the old storage. */
worry about rounding; right now the only case is f80 -> shorter if (newPartCount > oldPartCount) {
conversion, and we are keeping all 64 significant bits, so it's OK. */
if(newPartCount > partCount()) {
integerPart *newParts; integerPart *newParts;
newParts = new integerPart[newPartCount]; newParts = new integerPart[newPartCount];
APInt::tcSet(newParts, 0, newPartCount); APInt::tcSet(newParts, 0, newPartCount);
APInt::tcAssign(newParts, significandParts(), partCount()); APInt::tcAssign(newParts, significandParts(), oldPartCount);
freeSignificand(); freeSignificand();
significand.parts = newParts; significand.parts = newParts;
} else if (newPartCount==1 && newPartCount < partCount()) { } else if (newPartCount < oldPartCount) {
integerPart newPart; /* Capture any lost fraction through truncation of parts so we get
correct rounding whilst normalizing. */
APInt::tcSet(&newPart, 0, newPartCount); lostFraction = lostFractionThroughTruncation
APInt::tcAssign(&newPart, significandParts(), partCount()); (significandParts(), oldPartCount, toSemantics.precision);
freeSignificand(); if (newPartCount == 1)
significand.part = newPart; {
integerPart newPart = significandParts()[0];
freeSignificand();
significand.part = newPart;
}
} }
if(category == fcNormal) { if(category == fcNormal) {
/* Re-interpret our bit-pattern. */ /* Re-interpret our bit-pattern. */
exponent += toSemantics.precision - semantics->precision; exponent += toSemantics.precision - semantics->precision;
semantics = &toSemantics; semantics = &toSemantics;
fs = normalize(rounding_mode, lfExactlyZero); fs = normalize(rounding_mode, lostFraction);
} else { } else {
semantics = &toSemantics; semantics = &toSemantics;
fs = opOK; fs = opOK;