From c25a71106cbd7369b0d77ed7e6258009c275a213 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Mon, 21 Mar 2016 16:49:16 +0000 Subject: APFloat: Add frexp llvm-svn: 263950 --- llvm/lib/Support/APFloat.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 814c72cc4d3..ada392c519b 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -3942,7 +3942,12 @@ APFloat::makeZero(bool Negative) { category = fcZero; sign = Negative; exponent = semantics->minExponent-1; - APInt::tcSet(significandParts(), 0, partCount()); + APInt::tcSet(significandParts(), 0, partCount()); +} + +void APFloat::makeQuiet() { + assert(isNaN()); + APInt::tcSetBit(significandParts(), semantics->precision - 2); } int llvm::ilogb(const APFloat &Arg) { @@ -3981,3 +3986,22 @@ APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) { X.normalize(RoundingMode, lfExactlyZero); return X; } + +APFloat llvm::frexp(const APFloat &Val, int &Exp, APFloat::roundingMode RM) { + Exp = ilogb(Val); + + // Quiet signalling nans. + if (Exp == APFloat::IEK_NaN) { + APFloat Quiet(Val); + Quiet.makeQuiet(); + return Quiet; + } + + if (Exp == APFloat::IEK_Inf) + return Val; + + // 1 is added because frexp is defined to return a normalized fraction in + // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0). + Exp = Exp == APFloat::IEK_Zero ? 0 : Exp + 1; + return scalbn(Val, -Exp, RM); +} -- cgit v1.2.3