Don't depend on host real_t.init, use LLVM's signalling NaN instead

This commit is contained in:
Martin 2017-07-16 22:34:01 +02:00
parent f63166cf35
commit f17ff5efe0
3 changed files with 23 additions and 3 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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");