Evan implemented this.
[oota-llvm.git] / lib / Support / APFloat.cpp
index 04e99149bb853a5d3c3205f7054678659a8502fd..3b448208842633111d1512ef0989295f31a03d04 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/FoldingSet.h"
 #include <cassert>
 #include <cstring>
 #include "llvm/Support/MathExtras.h"
@@ -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.  */