Make the host endianness check an integer constant expression.

I will remove the isBigEndianHost function once I update clang.

The ifdef logic is designed to
* not use configure/cmake to avoid breaking -arch i686 -arch ppc.
* default to little endian
* be as small as possible

It looks like sys/endian.h is the preferred header on most modern BSD systems,
but it is better to change this in a followup patch as machine/endian.h is
available on FreeBSD, OpenBSD, NetBSD and OS X.

llvm-svn: 179527
This commit is contained in:
Rafael Espindola 2013-04-15 14:44:24 +00:00
parent cb45bc1861
commit 41cb64f4fa
8 changed files with 30 additions and 22 deletions

View File

@ -151,7 +151,7 @@ namespace detail {
inline uint64_t fetch64(const char *p) { inline uint64_t fetch64(const char *p) {
uint64_t result; uint64_t result;
memcpy(&result, p, sizeof(result)); memcpy(&result, p, sizeof(result));
if (sys::isBigEndianHost()) if (sys::IsBigEndianHost)
return sys::SwapByteOrder(result); return sys::SwapByteOrder(result);
return result; return result;
} }
@ -159,7 +159,7 @@ inline uint64_t fetch64(const char *p) {
inline uint32_t fetch32(const char *p) { inline uint32_t fetch32(const char *p) {
uint32_t result; uint32_t result;
memcpy(&result, p, sizeof(result)); memcpy(&result, p, sizeof(result));
if (sys::isBigEndianHost()) if (sys::IsBigEndianHost)
return sys::SwapByteOrder(result); return sys::SwapByteOrder(result);
return result; return result;
} }

View File

@ -37,7 +37,7 @@ namespace detail {
namespace endian { namespace endian {
template<typename value_type, endianness endian> template<typename value_type, endianness endian>
inline value_type byte_swap(value_type value) { inline value_type byte_swap(value_type value) {
if (endian != native && sys::isBigEndianHost() != (endian == big)) if (endian != native && sys::IsBigEndianHost != (endian == big))
return sys::SwapByteOrder(value); return sys::SwapByteOrder(value);
return value; return value;
} }

View File

@ -15,22 +15,30 @@
#define LLVM_SUPPORT_HOST_H #define LLVM_SUPPORT_HOST_H
#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringMap.h"
#if defined(__linux__)
#include <endian.h>
#else
#ifndef _MSC_VER
#include <machine/endian.h>
#endif
#endif
#include <string> #include <string>
namespace llvm { namespace llvm {
namespace sys { namespace sys {
inline bool isLittleEndianHost() { #if BYTE_ORDER == BIG_ENDIAN
union { static const bool IsBigEndianHost = true;
int i; #else
char c; static const bool IsBigEndianHost = false;
}; #endif
i = 1;
return c; static const bool IsLittleEndianHost = !IsBigEndianHost;
}
inline bool isBigEndianHost() { inline bool isBigEndianHost() {
return !isLittleEndianHost(); return IsBigEndianHost;
} }
/// getDefaultTargetTriple() - Return the default target triple the compiler /// getDefaultTargetTriple() - Return the default target triple the compiler

View File

@ -948,7 +948,7 @@ static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!"); assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!");
const uint8_t *Src = (const uint8_t *)IntVal.getRawData(); const uint8_t *Src = (const uint8_t *)IntVal.getRawData();
if (sys::isLittleEndianHost()) { if (sys::IsLittleEndianHost) {
// Little-endian host - the source is ordered from LSB to MSB. Order the // Little-endian host - the source is ordered from LSB to MSB. Order the
// destination from LSB to MSB: Do a straight copy. // destination from LSB to MSB: Do a straight copy.
memcpy(Dst, Src, StoreBytes); memcpy(Dst, Src, StoreBytes);
@ -1009,7 +1009,7 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val,
break; break;
} }
if (sys::isLittleEndianHost() != getDataLayout()->isLittleEndian()) if (sys::IsLittleEndianHost != getDataLayout()->isLittleEndian())
// Host and target are different endian - reverse the stored bytes. // Host and target are different endian - reverse the stored bytes.
std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr); std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr);
} }
@ -1021,7 +1021,7 @@ static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) {
uint8_t *Dst = reinterpret_cast<uint8_t *>( uint8_t *Dst = reinterpret_cast<uint8_t *>(
const_cast<uint64_t *>(IntVal.getRawData())); const_cast<uint64_t *>(IntVal.getRawData()));
if (sys::isLittleEndianHost()) if (sys::IsLittleEndianHost)
// Little-endian host - the destination must be ordered from LSB to MSB. // Little-endian host - the destination must be ordered from LSB to MSB.
// The source is ordered from LSB to MSB: Do a straight copy. // The source is ordered from LSB to MSB: Do a straight copy.
memcpy(Dst, Src, LoadBytes); memcpy(Dst, Src, LoadBytes);

View File

@ -202,14 +202,14 @@ protected:
void writeInt16BE(uint8_t *Addr, uint16_t Value) { void writeInt16BE(uint8_t *Addr, uint16_t Value) {
if (sys::isLittleEndianHost()) if (sys::IsLittleEndianHost)
Value = sys::SwapByteOrder(Value); Value = sys::SwapByteOrder(Value);
*Addr = (Value >> 8) & 0xFF; *Addr = (Value >> 8) & 0xFF;
*(Addr+1) = Value & 0xFF; *(Addr+1) = Value & 0xFF;
} }
void writeInt32BE(uint8_t *Addr, uint32_t Value) { void writeInt32BE(uint8_t *Addr, uint32_t Value) {
if (sys::isLittleEndianHost()) if (sys::IsLittleEndianHost)
Value = sys::SwapByteOrder(Value); Value = sys::SwapByteOrder(Value);
*Addr = (Value >> 24) & 0xFF; *Addr = (Value >> 24) & 0xFF;
*(Addr+1) = (Value >> 16) & 0xFF; *(Addr+1) = (Value >> 16) & 0xFF;
@ -218,7 +218,7 @@ protected:
} }
void writeInt64BE(uint8_t *Addr, uint64_t Value) { void writeInt64BE(uint8_t *Addr, uint64_t Value) {
if (sys::isLittleEndianHost()) if (sys::IsLittleEndianHost)
Value = sys::SwapByteOrder(Value); Value = sys::SwapByteOrder(Value);
*Addr = (Value >> 56) & 0xFF; *Addr = (Value >> 56) & 0xFF;
*(Addr+1) = (Value >> 48) & 0xFF; *(Addr+1) = (Value >> 48) & 0xFF;

View File

@ -61,7 +61,7 @@ static void ReadInMemoryStruct(const MachOObject &MOO,
MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_, MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_,
bool Is64Bit_) bool Is64Bit_)
: Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_), : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_),
IsSwappedEndian(IsLittleEndian != sys::isLittleEndianHost()), IsSwappedEndian(IsLittleEndian != sys::IsLittleEndianHost),
HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) { HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) {
// Load the common header. // Load the common header.
memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header)); memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header));

View File

@ -20,7 +20,7 @@ static T getU(uint32_t *offset_ptr, const DataExtractor *de,
uint32_t offset = *offset_ptr; uint32_t offset = *offset_ptr;
if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) { if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
std::memcpy(&val, &Data[offset], sizeof(val)); std::memcpy(&val, &Data[offset], sizeof(val));
if (sys::isLittleEndianHost() != isLittleEndian) if (sys::IsLittleEndianHost != isLittleEndian)
val = sys::SwapByteOrder(val); val = sys::SwapByteOrder(val);
// Advance the offset // Advance the offset

View File

@ -101,7 +101,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
// Otherwise do it the hard way. // Otherwise do it the hard way.
// To be compatible with above bulk transfer, we need to take endianness // To be compatible with above bulk transfer, we need to take endianness
// into account. // into account.
if (sys::isBigEndianHost()) { if (sys::IsBigEndianHost) {
for (Pos += 4; Pos <= Size; Pos += 4) { for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 4] << 24) | unsigned V = ((unsigned char)String[Pos - 4] << 24) |
((unsigned char)String[Pos - 3] << 16) | ((unsigned char)String[Pos - 3] << 16) |
@ -110,7 +110,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
Bits.push_back(V); Bits.push_back(V);
} }
} else { } else {
assert(sys::isLittleEndianHost() && "Unexpected host endianness"); assert(sys::IsLittleEndianHost && "Unexpected host endianness");
for (Pos += 4; Pos <= Size; Pos += 4) { for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 1] << 24) | unsigned V = ((unsigned char)String[Pos - 1] << 24) |
((unsigned char)String[Pos - 2] << 16) | ((unsigned char)String[Pos - 2] << 16) |