diff --git a/ddmd/root/ctfloat.h b/ddmd/root/ctfloat.h index c0f5136f55..9071ed0937 100644 --- a/ddmd/root/ctfloat.h +++ b/ddmd/root/ctfloat.h @@ -52,6 +52,7 @@ struct CTFloat // implemented in gen/ctfloat.cpp static void _init(); static void toAPFloat(real_t src, llvm::APFloat &dst); + static real_t fromAPFloat(const llvm::APFloat &src); static bool isFloat32LiteralOutOfRange(const char *literal); static bool isFloat64LiteralOutOfRange(const char *literal); diff --git a/gen/ctfloat.cpp b/gen/ctfloat.cpp index 37c9d00e56..f9dc47eaa2 100644 --- a/gen/ctfloat.cpp +++ b/gen/ctfloat.cpp @@ -80,15 +80,27 @@ void CTFloat::toAPFloat(const real_t src, APFloat &dst) { //////////////////////////////////////////////////////////////////////////////// -real_t CTFloat::parse(const char *literal, bool *isOutOfRange) { - const APFloat ap = parseLiteral(*apSemantics, literal, isOutOfRange); - const APInt bits = ap.bitcastToAPInt(); +real_t CTFloat::fromAPFloat(const APFloat &src_) { + APFloat src = src_; + if (&src.getSemantics() != apSemantics) { + bool ignored; + src.convert(*apSemantics, APFloat::rmNearestTiesToEven, &ignored); + } + + const APInt bits = src.bitcastToAPInt(); CTFloatUnion u; memcpy(u.bits, bits.getRawData(), bits.getBitWidth() / 8); return u.fp; } +//////////////////////////////////////////////////////////////////////////////// + +real_t CTFloat::parse(const char *literal, bool *isOutOfRange) { + const APFloat ap = parseLiteral(*apSemantics, literal, isOutOfRange); + return fromAPFloat(ap); +} + bool CTFloat::isFloat32LiteralOutOfRange(const char *literal) { bool isOutOfRange; parseLiteral(APFloat::IEEEsingle AP_SEMANTICS_PARENS, literal, &isOutOfRange); diff --git a/gen/target.cpp b/gen/target.cpp index c027da1264..2519158a68 100644 --- a/gen/target.cpp +++ b/gen/target.cpp @@ -55,6 +55,13 @@ void Target::_init() { const auto IEEEquad = &APFloat::IEEEquad; #endif + RealProperties.nan = + CTFloat::fromAPFloat(APFloat::getQNaN(*targetRealSemantics)); + RealProperties.snan = + CTFloat::fromAPFloat(APFloat::getSNaN(*targetRealSemantics)); + RealProperties.infinity = + CTFloat::fromAPFloat(APFloat::getInf(*targetRealSemantics)); + if (targetRealSemantics == IEEEdouble) { RealProperties.max = CTFloat::parse("0x1.fffffffffffffp+1023"); RealProperties.min_normal = CTFloat::parse("0x1p-1022");