diff options
Diffstat (limited to 'llvm/lib/Support/APFloat.cpp')
| -rw-r--r-- | llvm/lib/Support/APFloat.cpp | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 5dea98ee3993..7abca8391f70 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -66,6 +66,13 @@ namespace llvm { /* Number of bits actually used in the semantics. */ unsigned int sizeInBits; + + // Returns true if any number described by this semantics can be precisely + // represented by the specified semantics. + bool isRepresentableBy(const fltSemantics &S) const { + return maxExponent <= S.maxExponent && minExponent >= S.minExponent && + precision <= S.precision; + } }; static const fltSemantics semIEEEhalf = {15, -14, 11, 16}; @@ -3748,7 +3755,7 @@ namespace { exp += FirstSignificant; buffer.erase(&buffer[0], &buffer[FirstSignificant]); } -} +} // namespace void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision, unsigned FormatMaxPadding, bool TruncateZero) const { @@ -4761,7 +4768,8 @@ bool DoubleAPFloat::getExactInverse(APFloat *inv) const { return Ret; } -DoubleAPFloat scalbn(DoubleAPFloat Arg, int Exp, APFloat::roundingMode RM) { +DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, + APFloat::roundingMode RM) { assert(Arg.Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); return DoubleAPFloat(semPPCDoubleDouble, scalbn(Arg.Floats[0], Exp, RM), scalbn(Arg.Floats[1], Exp, RM)); @@ -4777,7 +4785,7 @@ DoubleAPFloat frexp(const DoubleAPFloat &Arg, int &Exp, return DoubleAPFloat(semPPCDoubleDouble, std::move(First), std::move(Second)); } -} // End detail namespace +} // namespace detail APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) { if (usesLayout<IEEEFloat>(Semantics)) { @@ -4874,6 +4882,32 @@ APFloat::opStatus APFloat::convertToInteger(APSInt &result, return status; } +double APFloat::convertToDouble() const { + if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEdouble) + return getIEEE().convertToDouble(); + assert(getSemantics().isRepresentableBy(semIEEEdouble) && + "Float semantics is not representable by IEEEdouble"); + APFloat Temp = *this; + bool LosesInfo; + opStatus St = Temp.convert(semIEEEdouble, rmNearestTiesToEven, &LosesInfo); + assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); + (void)St; + return Temp.getIEEE().convertToDouble(); +} + +float APFloat::convertToFloat() const { + if (&getSemantics() == (const llvm::fltSemantics *)&semIEEEsingle) + return getIEEE().convertToFloat(); + assert(getSemantics().isRepresentableBy(semIEEEsingle) && + "Float semantics is not representable by IEEEsingle"); + APFloat Temp = *this; + bool LosesInfo; + opStatus St = Temp.convert(semIEEEsingle, rmNearestTiesToEven, &LosesInfo); + assert(!(St & opInexact) && !LosesInfo && "Unexpected imprecision"); + (void)St; + return Temp.getIEEE().convertToFloat(); +} + } // namespace llvm #undef APFLOAT_DISPATCH_ON_SEMANTICS |
