#if defined(CPU_UNALIGNED) && defined(CPU_LE) || __ARM_ARCH_7A__ inline int Peek16le(const void *ptr) { return *(const word *)ptr; } inline int Peek32le(const void *ptr) { return *(const dword *)ptr; } inline int64 Peek64le(const void *ptr) { return *(const int64 *)ptr; } inline void Poke16le(const void *ptr, int val) { *(word *)ptr = val; } inline void Poke32le(const void *ptr, int val) { *(dword *)ptr = val; } inline void Poke64le(const void *ptr, int64 val) { *(int64 *)ptr = val; } #else inline int Peek16le(const void *ptr) { return MAKEWORD(((byte *)ptr)[0], ((byte *)ptr)[1]); } inline int Peek32le(const void *ptr) { return MAKELONG(Peek16le(ptr), Peek16le((byte *)ptr + 2)); } inline int64 Peek64le(const void *ptr) { return MAKEQWORD(Peek32le(ptr), Peek32le((byte *)ptr + 4)); } inline void Poke16le(const void *ptr, int val) { ((byte *)ptr)[0] = LOBYTE(val); ((byte *)ptr)[1] = HIBYTE(val); } inline void Poke32le(const void *ptr, int val) { Poke16le(ptr, LOWORD(val)); Poke16le((byte *)ptr + 2, HIWORD(val)); } inline void Poke64le(const void *ptr, int64 val) { Poke32le(ptr, LODWORD(val)); Poke32le((byte *)ptr + 4, HIDWORD(val)); } #endif inline int Peek16be(const void *ptr) { return MAKEWORD(((byte *)ptr)[1], ((byte *)ptr)[0]); } inline int Peek32be(const void *ptr) { return MAKELONG(Peek16be((byte *)ptr + 2), Peek16be(ptr)); } inline int64 Peek64be(const void *ptr) { return MAKEQWORD(Peek32be((byte *)ptr + 4), Peek32be(ptr)); } inline void Poke16be(const void *ptr, int val) { ((byte *)ptr)[1] = LOBYTE(val); ((byte *)ptr)[0] = HIBYTE(val); } inline void Poke32be(const void *ptr, int val) { Poke16be(ptr, HIWORD(val)); Poke16be((byte *)ptr + 2, LOWORD(val)); } inline void Poke64be(const void *ptr, int64 val) { Poke32be(ptr, HIDWORD(val)); Poke32be((byte *)ptr + 4, LODWORD(val)); } #ifdef CPU_LITTLE_ENDIAN #define MAKE2B(b0, b1) MAKEWORD(b0, b1); #define MAKE4B(b0, b1, b2, b3) MAKELONG(MAKEWORD(b0, b1), MAKEWORD(b2, b3)) #else #define MAKE2B(b0, b1) MAKEWORD(b1, b0); #define MAKE4B(b0, b1, b2, b3) MAKELONG(MAKEWORD(b2, b3), MAKEWORD(b0, b1)) #endif #if defined(CPU_X86) && (defined(COMPILER_GCC) || defined(COMPILER_MSC)) #ifdef COMPILER_GCC #ifdef CPU_64 inline word SwapEndian16(word v) { __asm__("xchgb %b0,%h0" : "=Q" (v) : "0" (v)); return v; } inline int16 SwapEndian16(int16 v) { __asm__("xchgb %b0,%h0" : "=Q" (v) : "0" (v)); return v; } #else inline word SwapEndian16(word v) { __asm__("xchgb %b0,%h0" : "=q" (v) : "0" (v)); return v; } inline int16 SwapEndian16(int16 v) { __asm__("xchgb %b0,%h0" : "=q" (v) : "0" (v)); return v; } #endif inline dword SwapEndian32(dword v) { __asm__("bswap %0" : "=r" (v) : "0" (v)); return v; } inline int SwapEndian32(int v) { __asm__("bswap %0" : "=r" (v) : "0" (v)); return v; } #endif #ifdef COMPILER_MSC #pragma intrinsic (_byteswap_ushort, _byteswap_ulong, _byteswap_uint64,strlen) inline word SwapEndian16(word v) { return _byteswap_ushort(v); } inline int16 SwapEndian16(int16 v) { return _byteswap_ushort(v); } inline dword SwapEndian32(dword v) { return _byteswap_ulong(v); } inline int SwapEndian32(int v) { return _byteswap_ulong(v); } #endif inline void EndianSwap(word& v) { v = SwapEndian16(v); } inline void EndianSwap(int16& v) { v = SwapEndian16(v); } inline void EndianSwap(dword& v) { v = SwapEndian32(v); } inline void EndianSwap(int& v) { v = SwapEndian32(v); } #else #ifdef COMPILER_GCC inline dword SwapEndian32(dword v) { return __builtin_bswap32(v); } inline int SwapEndian32(int v) { return __builtin_bswap32(v); } inline word SwapEndian16(word v) { return SwapEndian32(v) >> 16; } // GCC bug workaround inline int16 SwapEndian16(int16 v) { return SwapEndian32(v) >> 16; } inline void EndianSwap(word& v) { v = SwapEndian16(v); } inline void EndianSwap(int16& v) { v = SwapEndian16(v); } inline void EndianSwap(dword& v) { v = SwapEndian32(v); } inline void EndianSwap(int& v) { v = SwapEndian32(v); } #else inline void EndianSwap(word& v) { byte *x = (byte *)(&v); Swap(x[0], x[1]); } inline void EndianSwap(int16& v) { EndianSwap(*(word *)&v); } inline void EndianSwap(dword& v) { byte *x = (byte *)&v; Swap(x[0], x[3]); Swap(x[1], x[2]); } inline void EndianSwap(int& v) { EndianSwap(*(dword *)&v); } inline word SwapEndian16(word v) { EndianSwap(v); return v; } inline int16 SwapEndian16(int16 v) { EndianSwap(v); return v; } inline dword SwapEndian32(dword v) { EndianSwap(v); return v; } inline int SwapEndian32(int v) { EndianSwap(v); return v; } #endif #endif #if defined(CPU_AMD64) && (defined(COMPILER_GCC) || defined(COMPILER_MSC)) #ifdef COMPILER_GCC inline uint64 SwapEndian64(uint64 v) { __asm__("bswap %0" : "=r" (v) : "0" (v)); return v; } inline int64 SwapEndian64(int64 v) { __asm__("bswap %0" : "=r" (v) : "0" (v)); return v; } #endif #ifdef COMPILER_MSC inline uint64 SwapEndian64(uint64 v) { return _byteswap_uint64(v); } inline int64 SwapEndian64(int64 v) { return _byteswap_uint64(v); } #endif inline void EndianSwap(int64& v) { v = SwapEndian64(v); } inline void EndianSwap(uint64& v) { v = SwapEndian64(v); } #else #ifdef COMPILE_GCC inline uint64 SwapEndian64(uint64 v) { return __builtin_bswap64(v); } inline int64 SwapEndian64(int64 v) { return __builtin_bswap64(v); } inline void EndianSwap(int64& v) { v = SwapEndian64(v); } inline void EndianSwap(uint64& v) { v = SwapEndian64(v); } #else inline void EndianSwap(int64& v) { byte *x = (byte *)&v; Swap(x[0], x[7]); Swap(x[1], x[6]); Swap(x[2], x[5]); Swap(x[3], x[4]); } inline void EndianSwap(uint64& v) { EndianSwap(*(int64 *)&v); } inline int64 SwapEndian64(int64 v) { EndianSwap(v); return v; } inline uint64 SwapEndian64(uint64 v) { EndianSwap(v); return v; } #endif #endif void EndianSwap(word *v, size_t count); void EndianSwap(int16 *v, size_t count); void EndianSwap(dword *v, size_t count); void EndianSwap(int *v, size_t count); void EndianSwap(int64 *v, size_t count); void EndianSwap(uint64 *v, size_t count); #define SVO_MEMCPY(tgt, src, len) \ do { \ const char *s__ = (const char *)(src); \ char *t__ = (char *)(tgt); \ switch(len) { \ case 11: t__[10] = s__[10]; \ case 10: t__[9] = s__[9]; \ case 9: t__[8] = s__[8]; \ case 8: t__[7] = s__[7]; \ case 7: t__[6] = s__[6]; \ case 6: t__[5] = s__[5]; \ case 5: t__[4] = s__[4]; \ case 4: t__[3] = s__[3]; \ case 3: t__[2] = s__[2]; \ case 2: t__[1] = s__[1]; \ case 1: t__[0] = s__[0]; \ case 0: \ break; \ default: \ memcpy(t__, s__, len); \ } \ } while(false) #define SVO_MEMSET(tgt, val, len) \ do { \ char *t__ = (char *)(tgt); \ switch(len) { \ case 11: t__[10] = val; \ case 10: t__[9] = val; \ case 9: t__[8] = val; \ case 8: t__[7] = val; \ case 7: t__[6] = val; \ case 6: t__[5] = val; \ case 5: t__[4] = val; \ case 4: t__[3] = val; \ case 3: t__[2] = val; \ case 2: t__[1] = val; \ case 1: t__[0] = val; \ case 0: \ break; \ default: \ memset(t__, val, len); \ } \ } while(false) template force_inline bool svo_memeq(const tchar *a, const tchar *b, int len) { if(len > 11) return memcmp(a, b, len * sizeof(tchar)) == 0; switch(len) { case 11: if(a[10] != b[10]) return false; case 10: if(a[9] != b[9]) return false; case 9: if(a[8] != b[8]) return false; case 8: if(a[7] != b[7]) return false; case 7: if(a[6] != b[6]) return false; case 6: if(a[5] != b[5]) return false; case 5: if(a[4] != b[4]) return false; case 4: if(a[3] != b[3]) return false; case 3: if(a[2] != b[2]) return false; case 2: if(a[1] != b[1]) return false; case 1: if(a[0] != b[0]) return false; } return true; } force_inline bool fast_equal128(const void *a, const void *b) { uint32 *aa = (uint32 *)a; uint32 *bb = (uint32 *)b; return ((aa[0] ^ bb[0]) | (aa[1] ^ bb[1]) | (aa[2] ^ bb[2]) | (aa[3] ^ bb[3])) == 0; } force_inline void fast_zero128(void *t) { uint32 *tt = (uint32 *)t; tt[0] = tt[1] = tt[2] = tt[3] = 0; } force_inline void fast_copy128(void *t, const void *s) { uint32 *tt = (uint32 *)t; uint32 *ss = (uint32 *)s; tt[0] = ss[0]; tt[1] = ss[1]; tt[2] = ss[2]; tt[3] = ss[3]; } #if defined(CPU_UNALIGNED) && defined(CPU_LE) && (defined(COMPILER_MSC) || defined(COMPILER_GCC)) #define FAST_STRING_COMPARE #endif #ifdef FAST_STRING_COMPARE force_inline int fast_memcmp(const char *a, const char *b, size_t len) { #ifdef CPU_64 while(len >= 8) { uint64 a64 = *(uint64 *)a; uint64 b64 = *(uint64 *)b; if(a64 != b64) return SwapEndian64(a64) < SwapEndian64(b64) ? -1 : 1; a += 8; b += 8; len -= 8; } if(len & 4) { uint32 a32 = *(uint32 *)a; uint32 b32 = *(uint32 *)b; if(a32 != b32) return SwapEndian32(a32) < SwapEndian32(b32) ? -1 : 1; a += 4; b += 4; } #else while(len >= 4) { uint32 a32 = *(uint32 *)a; uint32 b32 = *(uint32 *)b; if(a32 != b32) return SwapEndian32(a32) < SwapEndian32(b32) ? -1 : 1; a += 4; b += 4; len -= 4; } #endif if(len & 2) { uint16 a16 = *(uint16 *)a; uint16 b16 = *(uint16 *)b; if(a16 != b16) return SwapEndian16(a16) < SwapEndian16(b16) ? -1 : 1; a += 2; b += 2; } if((len & 1) != 0 && *a != *b) return *a < *b ? -1 : 1; return 0; } #else inline int fast_memcmp(const char *a, const char *b, size_t len) { return memcmp(a, b, len); } #endif