From e2746ac58445ed1a774b545efab4a457bb6b5ac1 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 6 Jun 2018 20:35:46 +0200 Subject: Add zix data structures for use in model --- src/zix/digest.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/zix/digest.c (limited to 'src/zix/digest.c') diff --git a/src/zix/digest.c b/src/zix/digest.c new file mode 100644 index 00000000..889cfdef --- /dev/null +++ b/src/zix/digest.c @@ -0,0 +1,123 @@ +/* + Copyright 2012-2020 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "zix/digest.h" + +#ifdef __SSE4_2__ +# include +#endif + +#include +#include + +#ifdef __SSE4_2__ + +// SSE 4.2 CRC32 + +ZIX_API uint32_t +zix_digest_start(void) +{ + return 1; +} + +ZIX_API uint32_t +zix_digest_add(uint32_t hash, const void* const buf, const size_t len) +{ + const uint8_t* str = (const uint8_t*)buf; + + for (size_t i = 0; i < (len / sizeof(uint64_t)); ++i) { + hash = (uint32_t)_mm_crc32_u64(hash, *(const uint64_t*)str); + str += sizeof(uint64_t); + } + if (len & sizeof(uint32_t)) { + hash = _mm_crc32_u32(hash, *(const uint32_t*)str); + str += sizeof(uint32_t); + } + if (len & sizeof(uint16_t)) { + hash = _mm_crc32_u16(hash, *(const uint16_t*)str); + str += sizeof(uint16_t); + } + if (len & sizeof(uint8_t)) { + hash = _mm_crc32_u8(hash, *(const uint8_t*)str); + } + + return hash; +} + +ZIX_API uint32_t +zix_digest_add_64(uint32_t hash, const void* const buf, const size_t len) +{ + assert((uintptr_t)buf % sizeof(uint64_t) == 0); + assert(len % sizeof(uint64_t) == 0); + + const uint64_t* ptr = (const uint64_t*)buf; + + for (size_t i = 0; i < (len / sizeof(uint64_t)); ++i) { + hash = (uint32_t)_mm_crc32_u64(hash, *ptr); + ++ptr; + } + + return hash; +} + +ZIX_API uint32_t +zix_digest_add_ptr(const uint32_t hash, const void* const ptr) +{ +#if UINTPTR_MAX == UINT64_MAX + return (uint32_t)_mm_crc32_u64(hash, (uintptr_t)ptr); +#else + return _mm_crc32_u32(hash, (uintptr_t)ptr); +#endif +} + +#else + +// Classic DJB hash + +ZIX_API uint32_t +zix_digest_start(void) +{ + return 5381; +} + +ZIX_API uint32_t +zix_digest_add(uint32_t hash, const void* const buf, const size_t len) +{ + const uint8_t* str = (const uint8_t*)buf; + + for (size_t i = 0; i < len; ++i) { + hash = (hash << 5u) + hash + str[i]; + } + + return hash; +} + +ZIX_API uint32_t +zix_digest_add_64(uint32_t hash, const void* const buf, const size_t len) +{ + assert((uintptr_t)buf % sizeof(uint64_t) == 0); + assert(len % sizeof(uint64_t) == 0); + + return zix_digest_add(hash, buf, len); +} + +ZIX_API uint32_t +zix_digest_add_ptr(const uint32_t hash, const void* const ptr) +{ + return zix_digest_add(hash, &ptr, sizeof(ptr)); +} + +#endif -- cgit v1.2.1