forked from OSchip/llvm-project
Handle storage complications of float->float conversions.
llvm-svn: 42220
This commit is contained in:
parent
cf3e26fff2
commit
a8d7269269
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue