Files
stgsharp/StgSharp.Native/sn-src/s.hash.x86.c
T

51 lines
1.7 KiB
C

#include "sn_target.h"
#if SN_IS_ARCH(SN_ARCH_X86_64)
#include "StgSharpNative.h"
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int const length)
{
uint32_t hash = length, size = length << 1;
byte const *end = str + size;
byte const *ptr = str;
if (size < 4) {
for (; ptr < end; ptr += 2) {
hash = _mm_crc32_u16(hash, *ptr);
}
} else if (size < 16) {
for (; ptr < end; ptr += 4) {
hash = _mm_crc32_u32(hash, ((uint32_t const *)ptr)[0]);
}
for (; ptr < end; ptr++) {
hash = _mm_crc32_u16(hash, *ptr);
}
} else {
byte const *last_128 = end - 16;
byte const *last_32 = end - 4;
uint64_t hash64 = size;
for (; ptr < last_128; ptr += 16) {
__m128i vec = _mm_loadu_si128((__m128i const *)ptr);
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 0));
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 1));
}
hash = _mm_crc32_u8(hash, hash64);
hash = _mm_crc32_u8(hash, hash64 >> 32);
for (; ptr < last_32; ptr += 4) {
hash = _mm_crc32_u32(hash, ((uint32_t const *)ptr)[0]);
}
for (; ptr < end; ptr += 2) {
hash = _mm_crc32_u8(hash, *ptr);
}
}
hash ^= hash >> 16;
hash *= 0x85ebca6b;
hash ^= hash >> 13;
hash *= 0xc2b2ae35;
hash ^= hash >> 16;
return hash;
}
#endif