[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