[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