aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2007-09-20 23:47:58 +0000
committerDale Johannesen <dalej@apple.com>2007-09-20 23:47:58 +0000
commita72a5a095d0161f9258e75f38436698e9d75b879 (patch)
tree5e5c87cbd37a3c5de164bd353cf4480eef8bec85 /lib/Support
parent9ee49c541bb2b83e05005d4c45685b79c5d8af07 (diff)
downloadexternal_llvm-a72a5a095d0161f9258e75f38436698e9d75b879.zip
external_llvm-a72a5a095d0161f9258e75f38436698e9d75b879.tar.gz
external_llvm-a72a5a095d0161f9258e75f38436698e9d75b879.tar.bz2
Fix PR 1688. See comments there.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42181 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 68c1fcc..d314742 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -47,7 +47,7 @@ namespace llvm {
const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true };
const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true };
const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, false };
- const fltSemantics APFloat::Bogus = { 0, 0, 0, true };
+ const fltSemantics APFloat::Bogus = { 0, 0, 0, false };
}
/* Put a bunch of private, handy routines in an anonymous namespace. */
@@ -339,8 +339,7 @@ APFloat::~APFloat()
unsigned int
APFloat::partCount() const
{
- return partCountForBits(semantics->precision +
- semantics->implicitIntegerBit ? 1 : 0);
+ return partCountForBits(semantics->precision + 1);
}
unsigned int
@@ -1324,7 +1323,11 @@ APFloat::convert(const fltSemantics &toSemantics,
newPartCount = partCountForBits(toSemantics.precision + 1);
/* If our new form is wider, re-allocate our bit pattern into wider
- storage. */
+ 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()) {
integerPart *newParts;
@@ -1333,6 +1336,13 @@ APFloat::convert(const fltSemantics &toSemantics,
APInt::tcAssign(newParts, significandParts(), partCount());
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;
}
if(category == fcNormal) {
@@ -1588,22 +1598,22 @@ APFloat::getHashValue() const {
// Conversion from APFloat to/from host float/double. It may eventually be
// possible to eliminate these and have everybody deal with APFloats, but that
// will take a while. This approach will not easily extend to long double.
-// Current implementation requires partCount()==1, which is correct at the
-// moment but could be made more general.
+// Current implementation requires integerPartWidth==64, which is correct at
+// the moment but could be made more general.
// Denormals have exponent minExponent in APFloat, but minExponent-1 in
-// the actual IEEE respresentation. We compensate for that here.
+// the actual IEEE respresentations. We compensate for that here.
APInt
APFloat::convertF80LongDoubleAPFloatToAPInt() const {
assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended);
- assert (partCount()==1);
+ assert (partCount()==2);
uint64_t myexponent, mysignificand;
if (category==fcNormal) {
myexponent = exponent+16383; //bias
- mysignificand = *significandParts();
+ mysignificand = significandParts()[0];
if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
myexponent = 0; // denormal
} else if (category==fcZero) {
@@ -1614,7 +1624,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const {
mysignificand = 0x8000000000000000ULL;
} else if (category==fcNaN) {
myexponent = 0x7fff;
- mysignificand = *significandParts();
+ mysignificand = significandParts()[0];
} else
assert(0);
@@ -1727,7 +1737,7 @@ APFloat::initFromF80LongDoubleAPInt(const APInt &api) {
(i2 & 0xffff);
initialize(&APFloat::x87DoubleExtended);
- assert(partCount()==1);
+ assert(partCount()==2);
sign = i1>>63;
if (myexponent==0 && mysignificand==0) {
@@ -1739,11 +1749,13 @@ APFloat::initFromF80LongDoubleAPInt(const APInt &api) {
} else if (myexponent==0x7fff && mysignificand!=0x8000000000000000ULL) {
// exponent meaningless
category = fcNaN;
- *significandParts() = mysignificand;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = 0;
} else {
category = fcNormal;
exponent = myexponent - 16383;
- *significandParts() = mysignificand;
+ significandParts()[0] = mysignificand;
+ significandParts()[1] = 0;
if (myexponent==0) // denormal
exponent = -16382;
}