[llvm-commits] CVS: llvm/lib/Target/CBackend/Writer.cpp
Brian Gaeke
gaeke at cs.uiuc.edu
Tue Jul 20 20:15:36 PDT 2004
Changes in directory llvm/lib/Target/CBackend:
Writer.cpp updated: 1.190 -> 1.191
---
Log message:
Emit NaNs and INFs bit-identically to the bytecode file, if the system has
printf("%a") support.
Patch contributed by Bill Wendling.
---
Diffs of the changes: (+64 -2)
Index: llvm/lib/Target/CBackend/Writer.cpp
diff -u llvm/lib/Target/CBackend/Writer.cpp:1.190 llvm/lib/Target/CBackend/Writer.cpp:1.191
--- llvm/lib/Target/CBackend/Writer.cpp:1.190 Sat Jul 17 19:39:48 2004
+++ llvm/lib/Target/CBackend/Writer.cpp Tue Jul 20 22:15:26 2004
@@ -33,6 +33,7 @@
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/Mangler.h"
#include "Support/StringExtras.h"
+#include "Support/MathExtras.h"
#include "Config/config.h"
#include <algorithm>
#include <iostream>
@@ -556,14 +557,32 @@
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());
- Out << Buffer << " /*" << FPC->getValue() << "*/ ";
+ Num = Buffer;
#else
- Out << ftostr(FPC->getValue());
+ Num = ftostr(FPC->getValue());
#endif
+
+ if (IsNAN(FPC->getValue())) {
+ // The value is NaN
+ if (FPC->getType() == Type::FloatTy)
+ Out << "LLVM_NANF(\"" << Num << "\") /*nan*/ ";
+ else
+ Out << "LLVM_NAN(\"" << Num << "\") /*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*/ ";
+ } else {
+ Out << Num;
+ }
}
break;
}
@@ -700,6 +719,49 @@
<< "#else\n"
<< "#define __ATTRIBUTE_WEAK__\n"
<< "#endif\n\n";
+
+ // Define NaN and Inf as GCC builtins if using GCC, as 0 otherwise
+ // From the GCC documentation:
+ //
+ // double __builtin_nan (const char *str)
+ //
+ // This is an implementation of the ISO C99 function nan.
+ //
+ // Since ISO C99 defines this function in terms of strtod, which we do
+ // not implement, a description of the parsing is in order. The string is
+ // parsed as by strtol; that is, the base is recognized by leading 0 or
+ // 0x prefixes. The number parsed is placed in the significand such that
+ // the least significant bit of the number is at the least significant
+ // bit of the significand. The number is truncated to fit the significand
+ // field provided. The significand is forced to be a quiet NaN.
+ //
+ // This function, if given a string literal, is evaluated early enough
+ // that it is considered a compile-time constant.
+ //
+ // float __builtin_nanf (const char *str)
+ //
+ // Similar to __builtin_nan, except the return type is float.
+ //
+ // double __builtin_inf (void)
+ //
+ // Similar to __builtin_huge_val, except a warning is generated if the
+ // target floating-point format does not support infinities. This
+ // function is suitable for implementing the ISO C99 macro INFINITY.
+ //
+ // float __builtin_inff (void)
+ //
+ // 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"
+ << "#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"
+ << "#endif\n";
}
bool CWriter::doInitialization(Module &M) {
More information about the llvm-commits
mailing list