[llvm-commits] [llvm-gcc-4.2] r46039 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Bill Wendling
isanbard at gmail.com
Tue Jan 15 16:47:04 PST 2008
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) {
More information about the llvm-commits
mailing list