diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-03-21 16:49:16 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-03-21 16:49:16 +0000 |
commit | c25a71106cbd7369b0d77ed7e6258009c275a213 (patch) | |
tree | 56ead13ffe131b067b389f0b3c85f0d353ca8134 /llvm/lib/Support/APFloat.cpp | |
parent | b96b57347a785ffb5cdb2f0dd146b99520952823 (diff) | |
download | bcm5719-llvm-c25a71106cbd7369b0d77ed7e6258009c275a213.tar.gz bcm5719-llvm-c25a71106cbd7369b0d77ed7e6258009c275a213.zip |
APFloat: Add frexp
llvm-svn: 263950
Diffstat (limited to 'llvm/lib/Support/APFloat.cpp')
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
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); +} |