From 8b65b55ec1c380659195fe64d14c1d36074cf615 Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Wed, 25 Aug 2004 19:00:42 +0000 Subject: [PATCH] New version of Bill Wendling's PR33 patch. llvm-svn: 16050 --- lib/Target/CBackend/Writer.cpp | 62 ++++++++++++------- .../CBackend/2003-10-12-NANGlobalInits.ll | 2 +- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index bb1548f8a8c..960abd9caf8 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -557,30 +557,40 @@ void CWriter::printConstant(Constant *CPV) { Out << "(*(" << (FPC->getType() == Type::FloatTy ? "float" : "double") << "*)&FPConstant" << I->second << ")"; } else { - std::string Num; -#if HAVE_PRINTF_A - // Print out the constant as a floating point number. - char Buffer[100]; - sprintf(Buffer, "%a", FPC->getValue()); - Num = Buffer; -#else - Num = ftostr(FPC->getValue()); -#endif - if (IsNAN(FPC->getValue())) { // The value is NaN + + // The prefix for a quiet NaN is 0x7FF8. For a signalling NaN, + // it's 0x7ff4. + const unsigned long QuietNaN = 0x7ff8UL; + const unsigned long SignalNaN = 0x7ff4UL; + + // We need to grab the first part of the FP # + union { + double d; + uint64_t ll; + } DHex; + char Buffer[100]; + + DHex.d = FPC->getValue(); + sprintf(Buffer, "0x%llx", DHex.ll); + + std::string Num(&Buffer[0], &Buffer[6]); + unsigned long Val = strtoul(Num.c_str(), 0, 16); + if (FPC->getType() == Type::FloatTy) - Out << "LLVM_NANF(\"0\") /*nan*/ "; + Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "F(\"" + << Buffer << "\") /*nan*/ "; else - Out << "LLVM_NAN(\"0\") /*nan*/ "; + Out << "LLVM_NAN" << (Val == QuietNaN ? "" : "S") << "(\"" + << Buffer << "\") /*nan*/ "; } else if (IsInf(FPC->getValue())) { // The value is Inf if (FPC->getValue() < 0) Out << "-"; - if (FPC->getType() == Type::FloatTy) - Out << "LLVM_INFF /*inf*/ "; - else - Out << "LLVM_INF /*inf*/ "; + Out << "LLVM_INF" << (FPC->getType() == Type::FloatTy ? "F" : "") + << " /*inf*/ "; } else { + std::string Num = ftostr(FPC->getValue()); Out << Num; } } @@ -752,15 +762,19 @@ static void generateCompilerSpecificCode(std::ostream& Out) { // // Similar to __builtin_inf, except the return type is float. Out << "#ifdef __GNUC__\n" - << "#define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */\n" - << "#define LLVM_NANF(NanStr) __builtin_nan(NanStr) /* Float */\n" - << "#define LLVM_INF __builtin_inf() /* Double */\n" - << "#define LLVM_INFF __builtin_inff() /* Float */\n" + << "#define LLVM_NAN(NanStr) __builtin_nan(NanStr) /* Double */\n" + << "#define LLVM_NANF(NanStr) __builtin_nanf(NanStr) /* Float */\n" + << "#define LLVM_NANS(NanStr) __builtin_nans(NanStr) /* Double */\n" + << "#define LLVM_NANSF(NanStr) __builtin_nansf(NanStr) /* Float */\n" + << "#define LLVM_INF __builtin_inf() /* Double */\n" + << "#define LLVM_INFF __builtin_inff() /* Float */\n" << "#else\n" - << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n" - << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n" - << "#define LLVM_INF ((double)0.0) /* Double */\n" - << "#define LLVM_INFF 0.0F /* Float */\n" + << "#define LLVM_NAN(NanStr) ((double)0.0) /* Double */\n" + << "#define LLVM_NANF(NanStr) 0.0F /* Float */\n" + << "#define LLVM_NANS(NanStr) ((double)0.0) /* Double */\n" + << "#define LLVM_NANSF(NanStr) 0.0F /* Float */\n" + << "#define LLVM_INF ((double)0.0) /* Double */\n" + << "#define LLVM_INFF 0.0F /* Float */\n" << "#endif\n"; } diff --git a/test/Regression/CodeGen/CBackend/2003-10-12-NANGlobalInits.ll b/test/Regression/CodeGen/CBackend/2003-10-12-NANGlobalInits.ll index d2069985c27..184ffb49d20 100644 --- a/test/Regression/CodeGen/CBackend/2003-10-12-NANGlobalInits.ll +++ b/test/Regression/CodeGen/CBackend/2003-10-12-NANGlobalInits.ll @@ -1,3 +1,3 @@ ; This is a non-normal FP value: it's a nan. %NAN = global { float } { float 0x7FF8000000000000 } - +%NANs = global { float } { float 0x7FF4000000000000 }