[llvm-commits] [llvm-gcc-4.2] r78324 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Dale Johannesen dalej at apple.com
Thu Aug 6 10:23:40 PDT 2009


Author: johannes
Date: Thu Aug  6 12:23:40 2009
New Revision: 78324

URL: http://llvm.org/viewvc/llvm-project?rev=78324&view=rev
Log:
Fix wide character string constants when host and
target endianness do not match.  7094398.


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=78324&r1=78323&r2=78324&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Aug  6 12:23:40 2009
@@ -7017,7 +7017,7 @@
     // 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.
+    // and 4.2. llvm::sys has a substitute.
 
     UArr[0] = RealArr[0];   // Long -> int convert
     UArr[1] = RealArr[1];
@@ -7086,14 +7086,34 @@
            "Length in bytes should be a multiple of element size");
     const unsigned short *InStr =
       (const unsigned short *)TREE_STRING_POINTER(exp);
-    for (unsigned i = 0; i != Len/2; ++i)
-      Elts.push_back(ConstantInt::get(Type::Int16Ty, InStr[i]));
+    for (unsigned i = 0; i != Len/2; ++i) {
+      // gcc has constructed the initializer elements in the target endianness,
+      // but we're going to treat them as ordinary shorts from here, with
+      // host endianness.  Adjust if necessary.
+      if (llvm::sys::isBigEndianHost() == BYTES_BIG_ENDIAN)
+        Elts.push_back(ConstantInt::get(Type::Int16Ty, InStr[i]));
+      else
+        Elts.push_back(ConstantInt::get(Type::Int16Ty, 
+          ((InStr[i] << 8)  & 0xff00) | 
+          ((InStr[i] >> 8)  & 0x00ff)));
+    }
   } else if (ElTy == Type::Int32Ty) {
     assert((Len&3) == 0 &&
            "Length in bytes should be a multiple of element size");
     const unsigned *InStr = (const unsigned *)TREE_STRING_POINTER(exp);
-    for (unsigned i = 0; i != Len/4; ++i)
-      Elts.push_back(ConstantInt::get(Type::Int32Ty, InStr[i]));
+    for (unsigned i = 0; i != Len/4; ++i) {
+      // gcc has constructed the initializer elements in the target endianness,
+      // but we're going to treat them as ordinary shorts from here, with
+      // host endianness.  Adjust if necessary.
+      if (llvm::sys::isBigEndianHost() == BYTES_BIG_ENDIAN)
+        Elts.push_back(ConstantInt::get(Type::Int32Ty, InStr[i]));
+      else
+        Elts.push_back(ConstantInt::get(Type::Int32Ty, 
+          ((InStr[i] << 24) & 0xff000000) |
+          ((InStr[i] << 8)  & 0x00ff0000) | 
+          ((InStr[i] >> 8)  & 0x0000ff00) |
+          ((InStr[i] >> 24) & 0x000000ff)));
+    }
   } else {
     assert(0 && "Unknown character type!");
   }





More information about the llvm-commits mailing list