/*-****************************************
* Dependencies
******************************************/
+#include <asm/unaligned.h>
#include <linux/types.h> /* size_t, ptrdiff_t */
#include <linux/string.h> /* memcpy */
MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
+#if defined(__LITTLE_ENDIAN)
+# define MEM_LITTLE_ENDIAN 1
+#else
+# define MEM_LITTLE_ENDIAN 0
+#endif
+
MEM_STATIC unsigned MEM_isLittleEndian(void)
{
- const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
- return one.c[0];
+ return MEM_LITTLE_ENDIAN;
}
MEM_STATIC U16 MEM_read16(const void* memPtr)
{
- U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ return get_unaligned((const U16*)memPtr);
}
MEM_STATIC U32 MEM_read32(const void* memPtr)
{
- U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ return get_unaligned((const U32*)memPtr);
}
MEM_STATIC U64 MEM_read64(const void* memPtr)
{
- U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
+ return get_unaligned((const U64*)memPtr);
}
MEM_STATIC size_t MEM_readST(const void* memPtr)
{
- size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
+ return get_unaligned((const size_t*)memPtr);
}
MEM_STATIC void MEM_write16(void* memPtr, U16 value)
{
- memcpy(memPtr, &value, sizeof(value));
+ put_unaligned(value, (U16*)memPtr);
}
MEM_STATIC void MEM_write32(void* memPtr, U32 value)
{
- memcpy(memPtr, &value, sizeof(value));
+ put_unaligned(value, (U32*)memPtr);
}
MEM_STATIC void MEM_write64(void* memPtr, U64 value)
{
- memcpy(memPtr, &value, sizeof(value));
-}
-
-MEM_STATIC U32 MEM_swap32(U32 in)
-{
-#if defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
- return __builtin_bswap32(in);
-#else
- return ((in << 24) & 0xff000000 ) |
- ((in << 8) & 0x00ff0000 ) |
- ((in >> 8) & 0x0000ff00 ) |
- ((in >> 24) & 0x000000ff );
-#endif
-}
-
-MEM_STATIC U64 MEM_swap64(U64 in)
-{
-#if defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
- return __builtin_bswap64(in);
-#else
- return ((in << 56) & 0xff00000000000000ULL) |
- ((in << 40) & 0x00ff000000000000ULL) |
- ((in << 24) & 0x0000ff0000000000ULL) |
- ((in << 8) & 0x000000ff00000000ULL) |
- ((in >> 8) & 0x00000000ff000000ULL) |
- ((in >> 24) & 0x0000000000ff0000ULL) |
- ((in >> 40) & 0x000000000000ff00ULL) |
- ((in >> 56) & 0x00000000000000ffULL);
-#endif
-}
-
-MEM_STATIC size_t MEM_swapST(size_t in)
-{
- if (MEM_32bits())
- return (size_t)MEM_swap32((U32)in);
- else
- return (size_t)MEM_swap64((U64)in);
+ put_unaligned(value, (U64*)memPtr);
}
/*=== Little endian r/w ===*/
MEM_STATIC U16 MEM_readLE16(const void* memPtr)
{
- if (MEM_isLittleEndian())
- return MEM_read16(memPtr);
- else {
- const BYTE* p = (const BYTE*)memPtr;
- return (U16)(p[0] + (p[1]<<8));
- }
+ return get_unaligned_le16(memPtr);
}
MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
{
- if (MEM_isLittleEndian()) {
- MEM_write16(memPtr, val);
- } else {
- BYTE* p = (BYTE*)memPtr;
- p[0] = (BYTE)val;
- p[1] = (BYTE)(val>>8);
- }
+ put_unaligned_le16(val, memPtr);
}
MEM_STATIC U32 MEM_readLE24(const void* memPtr)
MEM_STATIC U32 MEM_readLE32(const void* memPtr)
{
- if (MEM_isLittleEndian())
- return MEM_read32(memPtr);
- else
- return MEM_swap32(MEM_read32(memPtr));
+ return get_unaligned_le32(memPtr);
}
MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
{
- if (MEM_isLittleEndian())
- MEM_write32(memPtr, val32);
- else
- MEM_write32(memPtr, MEM_swap32(val32));
+ put_unaligned_le32(val32, memPtr);
}
MEM_STATIC U64 MEM_readLE64(const void* memPtr)
{
- if (MEM_isLittleEndian())
- return MEM_read64(memPtr);
- else
- return MEM_swap64(MEM_read64(memPtr));
+ return get_unaligned_le64(memPtr);
}
MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
{
- if (MEM_isLittleEndian())
- MEM_write64(memPtr, val64);
- else
- MEM_write64(memPtr, MEM_swap64(val64));
+ put_unaligned_le64(val64, memPtr);
}
MEM_STATIC size_t MEM_readLEST(const void* memPtr)
MEM_STATIC U32 MEM_readBE32(const void* memPtr)
{
- if (MEM_isLittleEndian())
- return MEM_swap32(MEM_read32(memPtr));
- else
- return MEM_read32(memPtr);
+ return get_unaligned_be32(memPtr);
}
MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
{
- if (MEM_isLittleEndian())
- MEM_write32(memPtr, MEM_swap32(val32));
- else
- MEM_write32(memPtr, val32);
+ put_unaligned_be32(val32, memPtr);
}
MEM_STATIC U64 MEM_readBE64(const void* memPtr)
{
- if (MEM_isLittleEndian())
- return MEM_swap64(MEM_read64(memPtr));
- else
- return MEM_read64(memPtr);
+ return get_unaligned_be64(memPtr);
}
MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
{
- if (MEM_isLittleEndian())
- MEM_write64(memPtr, MEM_swap64(val64));
- else
- MEM_write64(memPtr, val64);
+ put_unaligned_be64(val64, memPtr);
}
MEM_STATIC size_t MEM_readBEST(const void* memPtr)
#define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
#define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
-static U32 XXH_swap32 (U32 x)
-{
- return MEM_swap32(x);
-}
-static U64 XXH_swap64 (U64 x)
-{
- return MEM_swap64(x);
-}
-
-
/* *************************************
* Architecture Macros
***************************************/
/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
#ifndef XXH_CPU_LITTLE_ENDIAN
- static const int g_one = 1;
-# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
+# define XXH_CPU_LITTLE_ENDIAN MEM_LITTLE_ENDIAN
#endif
*****************************/
typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
-FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess, XXH_alignment)
{
- if (align==XXH_unaligned)
- return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
- else
- return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
+ return MEM_readLE32(ptr);
}
FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
static U32 XXH_readBE32(const void* ptr)
{
- return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+ return MEM_readBE32(ptr);
}
FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
{
- if (align==XXH_unaligned)
- return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
- else
- return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
+ return MEM_readLE64(ptr);
}
FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
static U64 XXH_readBE64(const void* ptr)
{
- return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+ return MEM_readBE64(ptr);
}
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
{
XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
- if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
- memcpy(dst, &hash, sizeof(*dst));
+ MEM_writeBE32(dst, hash);
}
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
{
XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
- if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
- memcpy(dst, &hash, sizeof(*dst));
+ MEM_writeBE64(dst, hash);
}
XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)