//
// 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;
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;
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 {
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
{
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);
// 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;
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. */
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
APInt
APFloat::convertF80LongDoubleAPFloatToAPInt() const
{
- assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended);
+ assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended);
assert (partCount()==2);
uint64_t myexponent, mysignificand;
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;
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();
}
float
APFloat::convertToFloat() const
{
- assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle);
+ assert(semantics == (const llvm::fltSemantics*)&IEEEsingle);
APInt api = convertToAPInt();
return api.bitsToFloat();
}
double
APFloat::convertToDouble() const
{
- assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble);
+ assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
APInt api = convertToAPInt();
return api.bitsToDouble();
}