summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNeil Booth <neil@daikokuya.co.uk>2007-09-22 02:56:19 +0000
committerNeil Booth <neil@daikokuya.co.uk>2007-09-22 02:56:19 +0000
commitc8db43ddaf1c1f484ea08dff6fb61e5fa18352bc (patch)
tree656b2dc9519aa5593c04a73759c060b92d5d7943 /lib
parentd3989a820c3f99bd22516878144e0ed780153acf (diff)
downloadexternal_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.cpp41
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;