summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-03-21 16:49:16 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-03-21 16:49:16 +0000
commitc25a71106cbd7369b0d77ed7e6258009c275a213 (patch)
tree56ead13ffe131b067b389f0b3c85f0d353ca8134 /llvm/lib/Support/APFloat.cpp
parentb96b57347a785ffb5cdb2f0dd146b99520952823 (diff)
downloadbcm5719-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.cpp26
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);
+}
OpenPOWER on IntegriCloud