Evan implemented this.
[oota-llvm.git] / lib / Support / APFloat.cpp
index d713223a1e10600dbd02ae40ef1827f2d98717dc..3b448208842633111d1512ef0989295f31a03d04 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Neil Booth and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/FoldingSet.h"
 #include <cassert>
 #include <cstring>
-#include "llvm/ADT/APFloat.h"
 #include "llvm/Support/MathExtras.h"
 
 using namespace llvm;
@@ -231,8 +232,8 @@ namespace {
      is taken to have the decimal point after a single leading
      non-zero digit.
 
-     If the value is zero, V->firstSigDigit points to a zero, and the
-     return exponent is zero.
+     If the value is zero, V->firstSigDigit points to a non-digit, and
+     the return exponent is zero.
   */
   struct decimalInfo {
     const char *firstSigDigit;
@@ -627,14 +628,14 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
       category != rhs.category ||
       sign != rhs.sign)
     return false;
-  if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble &&
+  if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble &&
       sign2 != rhs.sign2)
     return false;
   if (category==fcZero || category==fcInfinity)
     return true;
   else if (category==fcNormal && exponent!=rhs.exponent)
     return false;
-  else if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble &&
+  else if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble &&
            exponent2!=rhs.exponent2)
     return false;
   else {
@@ -691,6 +692,11 @@ APFloat::~APFloat()
   freeSignificand();
 }
 
+// Profile - This method 'profiles' an APFloat for use with FoldingSet.
+void APFloat::Profile(FoldingSetNodeID& ID) const {
+  ID.Add(convertToAPInt());
+}
+
 unsigned int
 APFloat::partCount() const
 {
@@ -1712,6 +1718,8 @@ APFloat::convert(const fltSemantics &toSemantics,
     fs = normalize(rounding_mode, lostFraction);
   } else if (category == fcNaN) {
     int shift = toSemantics.precision - semantics->precision;
+    // Do this now so significandParts gets the right answer
+    semantics = &toSemantics;
     // No normalization here, just truncate
     if (shift>0)
       APInt::tcShiftLeft(significandParts(), newPartCount, shift);
@@ -1721,7 +1729,6 @@ APFloat::convert(const fltSemantics &toSemantics,
     // does not give you back the same bits.  This is dubious, and we
     // don't currently do it.  You're really supposed to get
     // an invalid operation signal at runtime, but nobody does that.
-    semantics = &toSemantics;
     fs = opOK;
   } else {
     semantics = &toSemantics;
@@ -1906,6 +1913,23 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
   return normalize(rounding_mode, lost_fraction);
 }
 
+APFloat::opStatus
+APFloat::convertFromAPInt(const APInt &Val,
+                          bool isSigned,
+                          roundingMode rounding_mode)
+{
+  unsigned int partCount = Val.getNumWords();
+  APInt api = Val;
+
+  sign = false;
+  if (isSigned && api.isNegative()) {
+    sign = true;
+    api = -api;
+  }
+
+  return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
+}
+
 /* Convert a two's complement integer SRC to a floating point number,
    rounding according to ROUNDING_MODE.  ISSIGNED is true if the
    integer is signed, in which case it must be sign-extended.  */
@@ -2145,7 +2169,7 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
            42039/12655 < L < 28738/8651  [ numerator <= 65536 ]
   */
 
-  if (*D.firstSigDigit == 0) {
+  if (decDigitValue(*D.firstSigDigit) >= 10U) {
     category = fcZero;
     fs = opOK;
   } else if ((D.normalizedExponent + 1) * 28738
@@ -2435,7 +2459,7 @@ APFloat::getHashValue() const
 APInt
 APFloat::convertF80LongDoubleAPFloatToAPInt() const
 {
-  assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended);
+  assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended);
   assert (partCount()==2);
 
   uint64_t myexponent, mysignificand;
@@ -2468,7 +2492,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
 APInt
 APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
 {
-  assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble);
+  assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
   assert (partCount()==2);
 
   uint64_t myexponent, mysignificand, myexponent2, mysignificand2;
@@ -2576,16 +2600,16 @@ APFloat::convertFloatAPFloatToAPInt() const
 APInt
 APFloat::convertToAPInt() const
 {
-  if (semantics == (const llvm::fltSemantics* const)&IEEEsingle)
+  if (semantics == (const llvm::fltSemantics*)&IEEEsingle)
     return convertFloatAPFloatToAPInt();
   
-  if (semantics == (const llvm::fltSemantics* const)&IEEEdouble)
+  if (semantics == (const llvm::fltSemantics*)&IEEEdouble)
     return convertDoubleAPFloatToAPInt();
 
-  if (semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble)
+  if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
     return convertPPCDoubleDoubleAPFloatToAPInt();
 
-  assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended &&
+  assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended &&
          "unknown format!");
   return convertF80LongDoubleAPFloatToAPInt();
 }
@@ -2593,7 +2617,7 @@ APFloat::convertToAPInt() const
 float
 APFloat::convertToFloat() const
 {
-  assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
+  assert(semantics == (const llvm::fltSemantics*)&IEEEsingle);
   APInt api = convertToAPInt();
   return api.bitsToFloat();
 }
@@ -2601,7 +2625,7 @@ APFloat::convertToFloat() const
 double
 APFloat::convertToDouble() const
 {
-  assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
+  assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
   APInt api = convertToAPInt();
   return api.bitsToDouble();
 }