diff options
Diffstat (limited to 'llvm/lib/Support/APFloat.cpp')
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 1069d1f..7abca83 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}; @@ -4875,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 |