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

Chris Lattner clattner at apple.com
Thu Aug 6 22:23:04 PDT 2009


On Aug 6, 2009, at 10:23 AM, Dale Johannesen wrote:

> 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.

llvm/Support/MathExtras.h has ByteSwap_16/ByteSwap_32 functions which  
might make this a bit cleaner.

-Chris

>
>
> 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!");
>   }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list