Author: void Date: Tue Jan 15 18:47:01 2008 New Revision: 46039 URL: http://llvm.org/viewvc/llvm-project?rev=46039&view=rev Log: If we are building a compiler for target T on host H, and H has a different type of endianness than T, then the builtin defines are generated incorrectly. For instance, a compiler built on an X86 machine to target a PPC machine will generate something like:
#define __FLT_MIN__ $.75079687365372222456778186655567717873896992796e-52F when run on the PPC machine. Instead, it should generate something like: #define __FLT_MIN__ 1.17549435e-38F This flips the bytes if the endianness doesn't match. Note, this doesn't apply to long doubles. Those are (potentially) trickier. Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=46039&r1=46038&r2=46039&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Jan 15 18:47:01 2008 @@ -5466,6 +5466,14 @@ double V; }; if (Ty==Type::FloatTy || Ty==Type::DoubleTy) { + // Determine endianness of host machine. + union { + int x; + char y[sizeof(int)]; + } u; + u.x = 1; + bool BigEndian = (u.y[0] != 1); + REAL_VALUE_TO_TARGET_DOUBLE(TREE_REAL_CST(exp), RealArr); // Here's how this works: @@ -5477,16 +5485,21 @@ // This, then, makes the conversion pretty simple. The tricky part is // getting the byte ordering correct and make sure you don't print any // more than 32 bits per integer on platforms with ints > 32 bits. - - UArr[0] = RealArr[0]; // Long -> int convert - UArr[1] = RealArr[1]; - + // // We want to switch the words of UArr if host and target endianness // do not match. FLOAT_WORDS_BIG_ENDIAN describes the target endianness. // The host's used to be available in HOST_WORDS_BIG_ENDIAN, but the gcc // maintainers removed this in a fit of cleanliness between 4.0 // and 4.2. For now, host and target endianness must match. + if (BigEndian == FLOAT_WORDS_BIG_ENDIAN) { + UArr[0] = RealArr[0]; // Long -> int convert + UArr[1] = RealArr[1]; + } else { + UArr[0] = RealArr[1]; // Long -> int convert + UArr[1] = RealArr[0]; + } + return ConstantFP::get(Ty, Ty==Type::FloatTy ? APFloat((float)V) : APFloat(V)); } else if (Ty==Type::X86_FP80Ty) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits