244#if defined(__cplusplus) && !defined(XXH_NO_EXTERNC_GUARD)
268# define XXH_STATIC_LINKING_ONLY
281# define XXH_IMPLEMENTATION
302# define XXH_INLINE_ALL
303# undef XXH_INLINE_ALL
307# define XXH_PRIVATE_API
308# undef XXH_PRIVATE_API
322# define XXH_NAMESPACE
326#define XXH_CAT(A,B) A##B
327#define XXH_NAME2(A,B) XXH_CAT(A,B)
328#define XXH_IPREF(Id) XXH_NAME2(XXH_NAMESPACE, Id)
330#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
331 && !defined(XXH_INLINE_ALL_31684351384)
333# define XXH_INLINE_ALL_31684351384
335# undef XXH_STATIC_LINKING_ONLY
336# define XXH_STATIC_LINKING_ONLY
338# undef XXH_PUBLIC_API
339# if defined(__GNUC__)
340# define XXH_PUBLIC_API static __inline __attribute__((__unused__))
341# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) )
342# define XXH_PUBLIC_API static inline
343# elif defined(_MSC_VER)
344# define XXH_PUBLIC_API static __inline
347# define XXH_PUBLIC_API static
363# undef XXH_versionNumber
366# undef XXH32_createState
367# undef XXH32_freeState
371# undef XXH32_copyState
372# undef XXH32_canonicalFromHash
373# undef XXH32_hashFromCanonical
376# undef XXH64_createState
377# undef XXH64_freeState
381# undef XXH64_copyState
382# undef XXH64_canonicalFromHash
383# undef XXH64_hashFromCanonical
386# undef XXH3_64bits_withSecret
387# undef XXH3_64bits_withSeed
388# undef XXH3_64bits_withSecretandSeed
389# undef XXH3_createState
390# undef XXH3_freeState
391# undef XXH3_copyState
392# undef XXH3_64bits_reset
393# undef XXH3_64bits_reset_withSeed
394# undef XXH3_64bits_reset_withSecret
395# undef XXH3_64bits_update
396# undef XXH3_64bits_digest
397# undef XXH3_generateSecret
401# undef XXH3_128bits_withSeed
402# undef XXH3_128bits_withSecret
403# undef XXH3_128bits_reset
404# undef XXH3_128bits_reset_withSeed
405# undef XXH3_128bits_reset_withSecret
406# undef XXH3_128bits_reset_withSecretandSeed
407# undef XXH3_128bits_update
408# undef XXH3_128bits_digest
409# undef XXH128_isEqual
411# undef XXH128_canonicalFromHash
412# undef XXH128_hashFromCanonical
417# define XXH_NAMESPACE XXH_INLINE_
425# define XXH_OK XXH_IPREF(XXH_OK)
426# define XXH_ERROR XXH_IPREF(XXH_ERROR)
427# define XXH_errorcode XXH_IPREF(XXH_errorcode)
428# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)
429# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)
430# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)
431# define XXH32_state_s XXH_IPREF(XXH32_state_s)
432# define XXH32_state_t XXH_IPREF(XXH32_state_t)
433# define XXH64_state_s XXH_IPREF(XXH64_state_s)
434# define XXH64_state_t XXH_IPREF(XXH64_state_t)
435# define XXH3_state_s XXH_IPREF(XXH3_state_s)
436# define XXH3_state_t XXH_IPREF(XXH3_state_t)
437# define XXH128_hash_t XXH_IPREF(XXH128_hash_t)
439# undef XXHASH_H_5627135585666179
440# undef XXHASH_H_STATIC_13879238742
446#ifndef XXHASH_H_5627135585666179
447#define XXHASH_H_5627135585666179 1
450#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
451# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
453# define XXH_PUBLIC_API __declspec(dllexport)
455# define XXH_PUBLIC_API __declspec(dllimport)
458# define XXH_PUBLIC_API
463# define XXH_versionNumber XXH_IPREF(XXH_versionNumber)
465# define XXH32 XXH_IPREF(XXH32)
466# define XXH32_createState XXH_IPREF(XXH32_createState)
467# define XXH32_freeState XXH_IPREF(XXH32_freeState)
468# define XXH32_reset XXH_IPREF(XXH32_reset)
469# define XXH32_update XXH_IPREF(XXH32_update)
470# define XXH32_digest XXH_IPREF(XXH32_digest)
471# define XXH32_copyState XXH_IPREF(XXH32_copyState)
472# define XXH32_canonicalFromHash XXH_IPREF(XXH32_canonicalFromHash)
473# define XXH32_hashFromCanonical XXH_IPREF(XXH32_hashFromCanonical)
475# define XXH64 XXH_IPREF(XXH64)
476# define XXH64_createState XXH_IPREF(XXH64_createState)
477# define XXH64_freeState XXH_IPREF(XXH64_freeState)
478# define XXH64_reset XXH_IPREF(XXH64_reset)
479# define XXH64_update XXH_IPREF(XXH64_update)
480# define XXH64_digest XXH_IPREF(XXH64_digest)
481# define XXH64_copyState XXH_IPREF(XXH64_copyState)
482# define XXH64_canonicalFromHash XXH_IPREF(XXH64_canonicalFromHash)
483# define XXH64_hashFromCanonical XXH_IPREF(XXH64_hashFromCanonical)
485# define XXH3_64bits XXH_IPREF(XXH3_64bits)
486# define XXH3_64bits_withSecret XXH_IPREF(XXH3_64bits_withSecret)
487# define XXH3_64bits_withSeed XXH_IPREF(XXH3_64bits_withSeed)
488# define XXH3_64bits_withSecretandSeed XXH_IPREF(XXH3_64bits_withSecretandSeed)
489# define XXH3_createState XXH_IPREF(XXH3_createState)
490# define XXH3_freeState XXH_IPREF(XXH3_freeState)
491# define XXH3_copyState XXH_IPREF(XXH3_copyState)
492# define XXH3_64bits_reset XXH_IPREF(XXH3_64bits_reset)
493# define XXH3_64bits_reset_withSeed XXH_IPREF(XXH3_64bits_reset_withSeed)
494# define XXH3_64bits_reset_withSecret XXH_IPREF(XXH3_64bits_reset_withSecret)
495# define XXH3_64bits_reset_withSecretandSeed XXH_IPREF(XXH3_64bits_reset_withSecretandSeed)
496# define XXH3_64bits_update XXH_IPREF(XXH3_64bits_update)
497# define XXH3_64bits_digest XXH_IPREF(XXH3_64bits_digest)
498# define XXH3_generateSecret XXH_IPREF(XXH3_generateSecret)
499# define XXH3_generateSecret_fromSeed XXH_IPREF(XXH3_generateSecret_fromSeed)
501# define XXH128 XXH_IPREF(XXH128)
502# define XXH3_128bits XXH_IPREF(XXH3_128bits)
503# define XXH3_128bits_withSeed XXH_IPREF(XXH3_128bits_withSeed)
504# define XXH3_128bits_withSecret XXH_IPREF(XXH3_128bits_withSecret)
505# define XXH3_128bits_withSecretandSeed XXH_IPREF(XXH3_128bits_withSecretandSeed)
506# define XXH3_128bits_reset XXH_IPREF(XXH3_128bits_reset)
507# define XXH3_128bits_reset_withSeed XXH_IPREF(XXH3_128bits_reset_withSeed)
508# define XXH3_128bits_reset_withSecret XXH_IPREF(XXH3_128bits_reset_withSecret)
509# define XXH3_128bits_reset_withSecretandSeed XXH_IPREF(XXH3_128bits_reset_withSecretandSeed)
510# define XXH3_128bits_update XXH_IPREF(XXH3_128bits_update)
511# define XXH3_128bits_digest XXH_IPREF(XXH3_128bits_digest)
512# define XXH128_isEqual XXH_IPREF(XXH128_isEqual)
513# define XXH128_cmp XXH_IPREF(XXH128_cmp)
514# define XXH128_canonicalFromHash XXH_IPREF(XXH128_canonicalFromHash)
515# define XXH128_hashFromCanonical XXH_IPREF(XXH128_hashFromCanonical)
524#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
525# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
527# define XXH_PUBLIC_API __declspec(dllexport)
529# define XXH_PUBLIC_API __declspec(dllimport)
532# define XXH_PUBLIC_API
536#if defined (__GNUC__)
537# define XXH_CONSTF __attribute__((__const__))
538# define XXH_PUREF __attribute__((__pure__))
539# define XXH_MALLOCF __attribute__((__malloc__))
549#define XXH_VERSION_MAJOR 0
550#define XXH_VERSION_MINOR 8
551#define XXH_VERSION_RELEASE 3
553#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
582#if defined(XXH_DOXYGEN)
588typedef uint32_t XXH32_hash_t;
590#elif !defined (__VMS) \
591 && (defined (__cplusplus) \
592 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ) )
594# include <inttypes.h>
598 typedef uint32_t XXH32_hash_t;
602# if UINT_MAX == 0xFFFFFFFFUL
603 typedef unsigned int XXH32_hash_t;
604# elif ULONG_MAX == 0xFFFFFFFFUL
605 typedef unsigned long XXH32_hash_t;
607# error "unsupported platform: need a 32-bit type"
756 unsigned char digest[4];
788#ifdef __has_attribute
789# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
791# define XXH_HAS_ATTRIBUTE(x) 0
797#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L) && defined(__has_c_attribute)
798# define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
800# define XXH_HAS_C_ATTRIBUTE(x) 0
805#if defined(__cplusplus) && defined(__has_cpp_attribute)
806# define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
808# define XXH_HAS_CPP_ATTRIBUTE(x) 0
819#if XXH_HAS_C_ATTRIBUTE(fallthrough) || XXH_HAS_CPP_ATTRIBUTE(fallthrough)
820# define XXH_FALLTHROUGH [[fallthrough]]
821#elif XXH_HAS_ATTRIBUTE(__fallthrough__)
822# define XXH_FALLTHROUGH __attribute__ ((__fallthrough__))
824# define XXH_FALLTHROUGH
834#if XXH_HAS_ATTRIBUTE(noescape)
835# define XXH_NOESCAPE __attribute__((__noescape__))
848#ifndef XXH_NO_LONG_LONG
852#if defined(XXH_DOXYGEN)
859#elif !defined (__VMS) \
860 && (defined (__cplusplus) \
861 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ) )
863# include <inttypes.h>
870# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL
1112# define XXH_SCALAR 0
1115# define XXH_AVX512 3
1184#define XXH3_SECRET_SIZE_MIN 136
1222#ifndef XXH_NO_STREAM
1449#ifndef XXH_NO_STREAM
1637#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)
1638#define XXHASH_H_STATIC_13879238742
1665struct XXH32_state_s {
1666 XXH32_hash_t total_len_32;
1667 XXH32_hash_t large_len;
1668 XXH32_hash_t acc[4];
1669 unsigned char buffer[16];
1670 XXH32_hash_t bufferedSize;
1671 XXH32_hash_t reserved;
1675#ifndef XXH_NO_LONG_LONG
1689struct XXH64_state_s {
1692 unsigned char buffer[32];
1693 XXH32_hash_t bufferedSize;
1694 XXH32_hash_t reserved32;
1700#if defined(__cplusplus) && (__cplusplus >= 201103L)
1702# define XXH_ALIGN(n) alignas(n)
1703#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
1704# define XXH_ALIGN(n) _Alignas(n)
1705#elif defined(__GNUC__)
1706# define XXH_ALIGN(n) __attribute__ ((aligned(n)))
1707#elif defined(_MSC_VER)
1708# define XXH_ALIGN(n) __declspec(align(n))
1710# define XXH_ALIGN(n)
1714#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) \
1715 && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) \
1716 && defined(__GNUC__)
1717# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
1719# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type
1730#define XXH3_INTERNALBUFFER_SIZE 256
1741#define XXH3_SECRET_DEFAULT_SIZE 192
1765struct XXH3_state_s {
1768 XXH_ALIGN_MEMBER(64,
unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
1770 XXH_ALIGN_MEMBER(64,
unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
1772 XXH32_hash_t bufferedSize;
1774 XXH32_hash_t useSeed;
1776 size_t nbStripesSoFar;
1780 size_t nbStripesPerBlock;
1788 const unsigned char* extSecret;
1794#undef XXH_ALIGN_MEMBER
1807#define XXH3_INITSTATE(XXH3_state_ptr) \
1809 XXH3_state_t* tmp_xxh3_state_ptr = (XXH3_state_ptr); \
1810 tmp_xxh3_state_ptr->seed = 0; \
1811 tmp_xxh3_state_ptr->extSecret = NULL; \
1895XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE
void* secretBuffer,
size_t secretSize, XXH_NOESCAPE
const void* customSeed,
size_t customSeedSize);
1940#define XXH3_MIDSIZE_MAX 240
1977XXH3_64bits_withSecretandSeed(XXH_NOESCAPE
const void* data,
size_t len,
1978 XXH_NOESCAPE
const void* secret,
size_t secretSize,
1996XXH3_128bits_withSecretandSeed(XXH_NOESCAPE
const void*
input,
size_t length,
1997 XXH_NOESCAPE
const void* secret,
size_t secretSize,
2000#ifndef XXH_NO_STREAM
2015XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE
XXH3_state_t* statePtr,
2016 XXH_NOESCAPE
const void* secret,
size_t secretSize,
2041XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE
XXH3_state_t* statePtr,
2042 XXH_NOESCAPE
const void* secret,
size_t secretSize,
2049#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
2050# define XXH_IMPLEMENTATION
2083#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \
2084 || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)
2085# define XXH_IMPLEM_13a8737387
2103# define XXH_NO_LONG_LONG
2104# undef XXH_NO_LONG_LONG
2155# define XXH_FORCE_MEMORY_ACCESS 0
2183# define XXH_SIZE_OPT 0
2213# define XXH_FORCE_ALIGN_CHECK 0
2235# define XXH_NO_INLINE_HINTS 0
2252# define XXH3_INLINE_SECRET 0
2264# define XXH32_ENDJMP 0
2273# define XXH_OLD_NAMES
2274# undef XXH_OLD_NAMES
2284# define XXH_NO_STREAM
2285# undef XXH_NO_STREAM
2291#ifndef XXH_FORCE_MEMORY_ACCESS
2295# if defined(__GNUC__) && !(defined(__ARM_ARCH) && __ARM_ARCH < 7 && defined(__ARM_FEATURE_UNALIGNED))
2296# define XXH_FORCE_MEMORY_ACCESS 1
2302# if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE_SIZE__)
2303# define XXH_SIZE_OPT 1
2305# define XXH_SIZE_OPT 0
2309#ifndef XXH_FORCE_ALIGN_CHECK
2311# if XXH_SIZE_OPT >= 1 || \
2312 defined(__i386) || defined(__x86_64__) || defined(__aarch64__) || defined(__ARM_FEATURE_UNALIGNED) \
2313 || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) || defined(_M_ARM)
2314# define XXH_FORCE_ALIGN_CHECK 0
2316# define XXH_FORCE_ALIGN_CHECK 1
2320#ifndef XXH_NO_INLINE_HINTS
2321# if XXH_SIZE_OPT >= 1 || defined(__NO_INLINE__)
2322# define XXH_NO_INLINE_HINTS 1
2324# define XXH_NO_INLINE_HINTS 0
2328#ifndef XXH3_INLINE_SECRET
2329# if (defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12) \
2330 || !defined(XXH_INLINE_ALL)
2331# define XXH3_INLINE_SECRET 0
2333# define XXH3_INLINE_SECRET 1
2339# define XXH32_ENDJMP 0
2351#if defined(XXH_NO_STREAM)
2353#elif defined(XXH_NO_STDLIB)
2364static XXH_CONSTF void* XXH_malloc(
size_t s) { (void)s;
return NULL; }
2365static void XXH_free(
void* p) { (void)p; }
2379static XXH_MALLOCF void* XXH_malloc(
size_t s) {
return malloc(s); }
2385static void XXH_free(
void* p) { free(p); }
2395# define XXH_memcpy memcpy
2404# define XXH_memset memset
2414# define XXH_memcmp memcmp
2426# pragma warning(disable : 4127)
2429#if XXH_NO_INLINE_HINTS
2430# if defined(__GNUC__) || defined(__clang__)
2431# define XXH_FORCE_INLINE static __attribute__((__unused__))
2433# define XXH_FORCE_INLINE static
2435# define XXH_NO_INLINE static
2437#elif defined(__GNUC__) || defined(__clang__)
2438# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__))
2439# define XXH_NO_INLINE static __attribute__((__noinline__))
2440#elif defined(_MSC_VER)
2441# define XXH_FORCE_INLINE static __forceinline
2442# define XXH_NO_INLINE static __declspec(noinline)
2443#elif defined (__cplusplus) \
2444 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))
2445# define XXH_FORCE_INLINE static inline
2446# define XXH_NO_INLINE static
2448# define XXH_FORCE_INLINE static
2449# define XXH_NO_INLINE static
2452#if defined(XXH_INLINE_ALL)
2453# define XXH_STATIC XXH_FORCE_INLINE
2455# define XXH_STATIC static
2458#if XXH3_INLINE_SECRET
2459# define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE
2461# define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE
2465#if ((defined(sun) || defined(__sun)) && defined(__cplusplus))
2466# define XXH_RESTRICT
2467#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
2468# define XXH_RESTRICT restrict
2469#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \
2470 || (defined (__clang__)) \
2471 || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \
2472 || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300))
2477# define XXH_RESTRICT __restrict
2479# define XXH_RESTRICT
2493#ifndef XXH_DEBUGLEVEL
2495# define XXH_DEBUGLEVEL DEBUGLEVEL
2497# define XXH_DEBUGLEVEL 0
2501#if (XXH_DEBUGLEVEL>=1)
2503# define XXH_ASSERT(c) assert(c)
2505# if defined(__INTEL_COMPILER)
2506# define XXH_ASSERT(c) XXH_ASSUME((unsigned char) (c))
2508# define XXH_ASSERT(c) XXH_ASSUME(c)
2513#ifndef XXH_STATIC_ASSERT
2514# if defined(__cplusplus) && (__cplusplus >= 201103L)
2515# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
2516# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
2517# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { _Static_assert((c),m); } while(0)
2519# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
2521# define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
2540#if defined(__GNUC__) || defined(__clang__)
2541# define XXH_COMPILER_GUARD(var) __asm__("" : "+r" (var))
2543# define XXH_COMPILER_GUARD(var) ((void)0)
2548#if defined(__clang__) && defined(__ARM_ARCH) && !defined(__wasm__)
2549# define XXH_COMPILER_GUARD_CLANG_NEON(var) __asm__("" : "+w" (var))
2551# define XXH_COMPILER_GUARD_CLANG_NEON(var) ((void)0)
2557#if !defined (__VMS) \
2558 && (defined (__cplusplus) \
2559 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ) )
2561# include <inttypes.h>
2565 typedef uint8_t xxh_u8;
2567 typedef unsigned char xxh_u8;
2569typedef XXH32_hash_t xxh_u32;
2572# warning "XXH_OLD_NAMES is planned to be removed starting v0.9. If the program depends on it, consider moving away from it by employing newer type names directly"
2630#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2635#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
2641static xxh_u32 XXH_read32(
const void* memPtr) {
return *(
const xxh_u32*) memPtr; }
2643#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
2653typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign;
2655static xxh_u32 XXH_read32(
const void* ptr)
2657 typedef __attribute__((__aligned__(1))) __attribute__((__may_alias__)) xxh_u32 xxh_unalign32;
2658 return *((const xxh_unalign32*)ptr);
2667static xxh_u32 XXH_read32(
const void* memPtr)
2670 XXH_memcpy(&val, memPtr,
sizeof(val));
2695#ifndef XXH_CPU_LITTLE_ENDIAN
2700# if defined(_WIN32) \
2701 || defined(__LITTLE_ENDIAN__) \
2702 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
2703# define XXH_CPU_LITTLE_ENDIAN 1
2704# elif defined(__BIG_ENDIAN__) \
2705 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
2706# define XXH_CPU_LITTLE_ENDIAN 0
2714static int XXH_isLittleEndian(
void)
2720 const union { xxh_u32
u; xxh_u8
c[4]; } one = { 1 };
2723# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
2733#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
2736# define XXH_HAS_BUILTIN(x) __has_builtin(x)
2738# define XXH_HAS_BUILTIN(x) 0
2770#if XXH_HAS_BUILTIN(__builtin_unreachable)
2771# define XXH_UNREACHABLE() __builtin_unreachable()
2773#elif defined(_MSC_VER)
2774# define XXH_UNREACHABLE() __assume(0)
2777# define XXH_UNREACHABLE()
2780#if XXH_HAS_BUILTIN(__builtin_assume)
2781# define XXH_ASSUME(c) __builtin_assume(c)
2783# define XXH_ASSUME(c) if (!(c)) { XXH_UNREACHABLE(); }
2799#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \
2800 && XXH_HAS_BUILTIN(__builtin_rotateleft64)
2801# define XXH_rotl32 __builtin_rotateleft32
2802# define XXH_rotl64 __builtin_rotateleft64
2803#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left)
2804# define XXH_rotl32 __builtin_stdc_rotate_left
2805# define XXH_rotl64 __builtin_stdc_rotate_left
2807#elif defined(_MSC_VER)
2808# define XXH_rotl32(x,r) _rotl(x,r)
2809# define XXH_rotl64(x,r) _rotl64(x,r)
2811# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
2812# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
2823#if defined(_MSC_VER)
2824# define XXH_swap32 _byteswap_ulong
2825#elif XXH_GCC_VERSION >= 403
2826# define XXH_swap32 __builtin_bswap32
2828static xxh_u32 XXH_swap32 (xxh_u32
x)
2830 return ((
x << 24) & 0xff000000 ) |
2831 ((
x << 8) & 0x00ff0000 ) |
2832 ((
x >> 8) & 0x0000ff00 ) |
2833 ((
x >> 24) & 0x000000ff );
2856#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2858XXH_FORCE_INLINE xxh_u32 XXH_readLE32(
const void* memPtr)
2860 const xxh_u8* bytePtr = (
const xxh_u8 *)memPtr;
2862 | ((xxh_u32)bytePtr[1] << 8)
2863 | ((xxh_u32)bytePtr[2] << 16)
2864 | ((xxh_u32)bytePtr[3] << 24);
2867XXH_FORCE_INLINE xxh_u32 XXH_readBE32(
const void* memPtr)
2869 const xxh_u8* bytePtr = (
const xxh_u8 *)memPtr;
2871 | ((xxh_u32)bytePtr[2] << 8)
2872 | ((xxh_u32)bytePtr[1] << 16)
2873 | ((xxh_u32)bytePtr[0] << 24);
2877XXH_FORCE_INLINE xxh_u32 XXH_readLE32(
const void* ptr)
2879 return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
2882static xxh_u32 XXH_readBE32(
const void* ptr)
2884 return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
2888XXH_FORCE_INLINE xxh_u32
2889XXH_readLE32_align(
const void* ptr, XXH_alignment align)
2891 if (align==XXH_unaligned) {
2892 return XXH_readLE32(ptr);
2894 return XXH_CPU_LITTLE_ENDIAN ? *(
const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
2918#define XXH_PRIME32_1 0x9E3779B1U
2919#define XXH_PRIME32_2 0x85EBCA77U
2920#define XXH_PRIME32_3 0xC2B2AE3DU
2921#define XXH_PRIME32_4 0x27D4EB2FU
2922#define XXH_PRIME32_5 0x165667B1U
2925# define PRIME32_1 XXH_PRIME32_1
2926# define PRIME32_2 XXH_PRIME32_2
2927# define PRIME32_3 XXH_PRIME32_3
2928# define PRIME32_4 XXH_PRIME32_4
2929# define PRIME32_5 XXH_PRIME32_5
2943static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32
input)
2945 acc +=
input * XXH_PRIME32_2;
2946 acc = XXH_rotl32(acc, 13);
2947 acc *= XXH_PRIME32_1;
2948#if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
2985 XXH_COMPILER_GUARD(acc);
3000static xxh_u32 XXH32_avalanche(xxh_u32 hash)
3003 hash *= XXH_PRIME32_2;
3005 hash *= XXH_PRIME32_3;
3010#define XXH_get32bits(p) XXH_readLE32_align(p, align)
3016XXH_FORCE_INLINE
void
3017XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed)
3019 XXH_ASSERT(acc != NULL);
3020 acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
3021 acc[1] = seed + XXH_PRIME32_2;
3023 acc[3] = seed - XXH_PRIME32_1;
3032XXH_FORCE_INLINE
const xxh_u8 *
3034 xxh_u32 *XXH_RESTRICT acc,
3035 xxh_u8
const *XXH_RESTRICT
input,
3040 const xxh_u8*
const bEnd =
input + len;
3041 const xxh_u8*
const limit = bEnd - 15;
3042 XXH_ASSERT(acc != NULL);
3043 XXH_ASSERT(
input != NULL);
3044 XXH_ASSERT(len >= 16);
3046 acc[0] = XXH32_round(acc[0], XXH_get32bits(
input));
input += 4;
3047 acc[1] = XXH32_round(acc[1], XXH_get32bits(
input));
input += 4;
3048 acc[2] = XXH32_round(acc[2], XXH_get32bits(
input));
input += 4;
3049 acc[3] = XXH32_round(acc[3], XXH_get32bits(
input));
input += 4;
3050 }
while (
input < limit);
3060XXH32_mergeAccs(
const xxh_u32 *acc)
3062 XXH_ASSERT(acc != NULL);
3063 return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7)
3064 + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18);
3083XXH32_finalize(xxh_u32 hash,
const xxh_u8* ptr,
size_t len, XXH_alignment align)
3085#define XXH_PROCESS1 do { \
3086 hash += (*ptr++) * XXH_PRIME32_5; \
3087 hash = XXH_rotl32(hash, 11) * XXH_PRIME32_1; \
3090#define XXH_PROCESS4 do { \
3091 hash += XXH_get32bits(ptr) * XXH_PRIME32_3; \
3093 hash = XXH_rotl32(hash, 17) * XXH_PRIME32_4; \
3096 if (ptr==NULL) XXH_ASSERT(len == 0);
3099 if (!XXH32_ENDJMP) {
3109 return XXH32_avalanche(hash);
3112 case 12: XXH_PROCESS4;
3114 case 8: XXH_PROCESS4;
3116 case 4: XXH_PROCESS4;
3117 return XXH32_avalanche(hash);
3119 case 13: XXH_PROCESS4;
3121 case 9: XXH_PROCESS4;
3123 case 5: XXH_PROCESS4;
3125 return XXH32_avalanche(hash);
3127 case 14: XXH_PROCESS4;
3129 case 10: XXH_PROCESS4;
3131 case 6: XXH_PROCESS4;
3134 return XXH32_avalanche(hash);
3136 case 15: XXH_PROCESS4;
3138 case 11: XXH_PROCESS4;
3140 case 7: XXH_PROCESS4;
3142 case 3: XXH_PROCESS1;
3144 case 2: XXH_PROCESS1;
3146 case 1: XXH_PROCESS1;
3148 case 0:
return XXH32_avalanche(hash);
3156# define PROCESS1 XXH_PROCESS1
3157# define PROCESS4 XXH_PROCESS4
3172XXH32_endian_align(
const xxh_u8*
input,
size_t len, xxh_u32 seed, XXH_alignment align)
3176 if (
input==NULL) XXH_ASSERT(len == 0);
3180 XXH32_initAccs(acc, seed);
3182 input = XXH32_consumeLong(acc,
input, len, align);
3184 h32 = XXH32_mergeAccs(acc);
3186 h32 = seed + XXH_PRIME32_5;
3189 h32 += (xxh_u32)len;
3191 return XXH32_finalize(h32,
input, len&15, align);
3197#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2
3204 if (XXH_FORCE_ALIGN_CHECK) {
3205 if ((((
size_t)
input) & 3) == 0) {
3206 return XXH32_endian_align((
const xxh_u8*)
input, len, seed, XXH_aligned);
3209 return XXH32_endian_align((
const xxh_u8*)
input, len, seed, XXH_unaligned);
3216#ifndef XXH_NO_STREAM
3232 XXH_memcpy(dstState, srcState,
sizeof(*dstState));
3238 XXH_ASSERT(statePtr != NULL);
3239 XXH_memset(statePtr, 0,
sizeof(*statePtr));
3240 XXH32_initAccs(statePtr->acc, seed);
3250 XXH_ASSERT(len == 0);
3254 state->total_len_32 += (XXH32_hash_t)len;
3255 state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
3257 XXH_ASSERT(state->bufferedSize <
sizeof(state->buffer));
3258 if (len <
sizeof(state->buffer) - state->bufferedSize) {
3259 XXH_memcpy(state->buffer + state->bufferedSize,
input, len);
3260 state->bufferedSize += (XXH32_hash_t)len;
3264 {
const xxh_u8* xinput = (
const xxh_u8*)
input;
3265 const xxh_u8*
const bEnd = xinput + len;
3267 if (state->bufferedSize) {
3268 XXH_memcpy(state->buffer + state->bufferedSize, xinput,
sizeof(state->buffer) - state->bufferedSize);
3269 xinput +=
sizeof(state->buffer) - state->bufferedSize;
3271 (void)XXH32_consumeLong(state->acc, state->buffer,
sizeof(state->buffer), XXH_aligned);
3272 state->bufferedSize = 0;
3275 XXH_ASSERT(xinput <= bEnd);
3276 if ((
size_t)(bEnd - xinput) >=
sizeof(state->buffer)) {
3278 xinput = XXH32_consumeLong(state->acc, xinput, (
size_t)(bEnd - xinput), XXH_unaligned);
3281 if (xinput < bEnd) {
3283 XXH_memcpy(state->buffer, xinput, (
size_t)(bEnd-xinput));
3284 state->bufferedSize = (unsigned)(bEnd-xinput);
3297 if (state->large_len) {
3298 h32 = XXH32_mergeAccs(state->acc);
3300 h32 = state->acc[2] + XXH_PRIME32_5;
3303 h32 += state->total_len_32;
3305 return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned);
3315 if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
3316 XXH_memcpy(dst, &hash,
sizeof(*dst));
3321 return XXH_readBE32(src);
3325#ifndef XXH_NO_LONG_LONG
3343#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
3348#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
3351static xxh_u64 XXH_read64(
const void* memPtr)
3353 return *(
const xxh_u64*) memPtr;
3356#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
3366typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64;
3368static xxh_u64 XXH_read64(
const void* ptr)
3370 typedef __attribute__((__aligned__(1))) __attribute__((__may_alias__)) xxh_u64 xxh_unalign64;
3371 return *((const xxh_unalign64*)ptr);
3380static xxh_u64 XXH_read64(
const void* memPtr)
3383 XXH_memcpy(&val, memPtr,
sizeof(val));
3389#if defined(_MSC_VER)
3390# define XXH_swap64 _byteswap_uint64
3391#elif XXH_GCC_VERSION >= 403
3392# define XXH_swap64 __builtin_bswap64
3394static xxh_u64 XXH_swap64(xxh_u64
x)
3396 return ((
x << 56) & 0xff00000000000000ULL) |
3397 ((
x << 40) & 0x00ff000000000000ULL) |
3398 ((
x << 24) & 0x0000ff0000000000ULL) |
3399 ((
x << 8) & 0x000000ff00000000ULL) |
3400 ((
x >> 8) & 0x00000000ff000000ULL) |
3401 ((
x >> 24) & 0x0000000000ff0000ULL) |
3402 ((
x >> 40) & 0x000000000000ff00ULL) |
3403 ((
x >> 56) & 0x00000000000000ffULL);
3409#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
3411XXH_FORCE_INLINE xxh_u64 XXH_readLE64(
const void* memPtr)
3413 const xxh_u8* bytePtr = (
const xxh_u8 *)memPtr;
3415 | ((xxh_u64)bytePtr[1] << 8)
3416 | ((xxh_u64)bytePtr[2] << 16)
3417 | ((xxh_u64)bytePtr[3] << 24)
3418 | ((xxh_u64)bytePtr[4] << 32)
3419 | ((xxh_u64)bytePtr[5] << 40)
3420 | ((xxh_u64)bytePtr[6] << 48)
3421 | ((xxh_u64)bytePtr[7] << 56);
3424XXH_FORCE_INLINE xxh_u64 XXH_readBE64(
const void* memPtr)
3426 const xxh_u8* bytePtr = (
const xxh_u8 *)memPtr;
3428 | ((xxh_u64)bytePtr[6] << 8)
3429 | ((xxh_u64)bytePtr[5] << 16)
3430 | ((xxh_u64)bytePtr[4] << 24)
3431 | ((xxh_u64)bytePtr[3] << 32)
3432 | ((xxh_u64)bytePtr[2] << 40)
3433 | ((xxh_u64)bytePtr[1] << 48)
3434 | ((xxh_u64)bytePtr[0] << 56);
3438XXH_FORCE_INLINE xxh_u64 XXH_readLE64(
const void* ptr)
3440 return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
3443static xxh_u64 XXH_readBE64(
const void* ptr)
3445 return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
3449XXH_FORCE_INLINE xxh_u64
3450XXH_readLE64_align(
const void* ptr, XXH_alignment align)
3452 if (align==XXH_unaligned)
3453 return XXH_readLE64(ptr);
3455 return XXH_CPU_LITTLE_ENDIAN ? *(
const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
3469#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL
3470#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL
3471#define XXH_PRIME64_3 0x165667B19E3779F9ULL
3472#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL
3473#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL
3476# define PRIME64_1 XXH_PRIME64_1
3477# define PRIME64_2 XXH_PRIME64_2
3478# define PRIME64_3 XXH_PRIME64_3
3479# define PRIME64_4 XXH_PRIME64_4
3480# define PRIME64_5 XXH_PRIME64_5
3484static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64
input)
3486 acc +=
input * XXH_PRIME64_2;
3487 acc = XXH_rotl64(acc, 31);
3488 acc *= XXH_PRIME64_1;
3489#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
3504 XXH_COMPILER_GUARD(acc);
3509static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
3511 val = XXH64_round(0, val);
3513 acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
3518static xxh_u64 XXH64_avalanche(xxh_u64 hash)
3521 hash *= XXH_PRIME64_2;
3523 hash *= XXH_PRIME64_3;
3529#define XXH_get64bits(p) XXH_readLE64_align(p, align)
3535XXH_FORCE_INLINE
void
3536XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed)
3538 XXH_ASSERT(acc != NULL);
3539 acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
3540 acc[1] = seed + XXH_PRIME64_2;
3542 acc[3] = seed - XXH_PRIME64_1;
3551XXH_FORCE_INLINE
const xxh_u8 *
3553 xxh_u64 *XXH_RESTRICT acc,
3554 xxh_u8
const *XXH_RESTRICT
input,
3559 const xxh_u8*
const bEnd =
input + len;
3560 const xxh_u8*
const limit = bEnd - 31;
3561 XXH_ASSERT(acc != NULL);
3562 XXH_ASSERT(
input != NULL);
3563 XXH_ASSERT(len >= 32);
3566 if (
sizeof(
void *) <
sizeof(xxh_u64)) {
3568 for (i = 0;
i < 4;
i++) {
3569 acc[
i] = XXH64_round(acc[i], XXH_get64bits(
input));
3573 acc[0] = XXH64_round(acc[0], XXH_get64bits(
input));
input += 8;
3574 acc[1] = XXH64_round(acc[1], XXH_get64bits(
input));
input += 8;
3575 acc[2] = XXH64_round(acc[2], XXH_get64bits(
input));
input += 8;
3576 acc[3] = XXH64_round(acc[3], XXH_get64bits(
input));
input += 8;
3578 }
while (
input < limit);
3588XXH64_mergeAccs(
const xxh_u64 *acc)
3590 XXH_ASSERT(acc != NULL);
3592 xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7)
3593 + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18);
3595 if (
sizeof(
void *) <
sizeof(xxh_u64)) {
3597 for (i = 0;
i < 4;
i++) {
3598 h64 = XXH64_mergeRound(h64, acc[i]);
3601 h64 = XXH64_mergeRound(h64, acc[0]);
3602 h64 = XXH64_mergeRound(h64, acc[1]);
3603 h64 = XXH64_mergeRound(h64, acc[2]);
3604 h64 = XXH64_mergeRound(h64, acc[3]);
3626XXH64_finalize(xxh_u64 hash,
const xxh_u8* ptr,
size_t len, XXH_alignment align)
3628 if (ptr==NULL) XXH_ASSERT(len == 0);
3631 xxh_u64
const k1 = XXH64_round(0, XXH_get64bits(ptr));
3634 hash = XXH_rotl64(hash,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
3638 hash ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
3640 hash = XXH_rotl64(hash, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
3644 hash ^= (*ptr++) * XXH_PRIME64_5;
3645 hash = XXH_rotl64(hash, 11) * XXH_PRIME64_1;
3648 return XXH64_avalanche(hash);
3652# define PROCESS1_64 XXH_PROCESS1_64
3653# define PROCESS4_64 XXH_PROCESS4_64
3654# define PROCESS8_64 XXH_PROCESS8_64
3656# undef XXH_PROCESS1_64
3657# undef XXH_PROCESS4_64
3658# undef XXH_PROCESS8_64
3670XXH64_endian_align(
const xxh_u8*
input,
size_t len, xxh_u64 seed, XXH_alignment align)
3673 if (
input==NULL) XXH_ASSERT(len == 0);
3677 XXH64_initAccs(acc, seed);
3679 input = XXH64_consumeLong(acc,
input, len, align);
3681 h64 = XXH64_mergeAccs(acc);
3683 h64 = seed + XXH_PRIME64_5;
3686 h64 += (xxh_u64) len;
3688 return XXH64_finalize(h64,
input, len, align);
3695#if !defined(XXH_NO_STREAM) && XXH_SIZE_OPT >= 2
3702 if (XXH_FORCE_ALIGN_CHECK) {
3703 if ((((
size_t)
input) & 7)==0) {
3704 return XXH64_endian_align((
const xxh_u8*)
input, len, seed, XXH_aligned);
3707 return XXH64_endian_align((
const xxh_u8*)
input, len, seed, XXH_unaligned);
3713#ifndef XXH_NO_STREAM
3729 XXH_memcpy(dstState, srcState,
sizeof(*dstState));
3735 XXH_ASSERT(statePtr != NULL);
3736 XXH_memset(statePtr, 0,
sizeof(*statePtr));
3737 XXH64_initAccs(statePtr->acc, seed);
3746 XXH_ASSERT(len == 0);
3750 state->total_len += len;
3752 XXH_ASSERT(state->bufferedSize <=
sizeof(state->buffer));
3753 if (len <
sizeof(state->buffer) - state->bufferedSize) {
3754 XXH_memcpy(state->buffer + state->bufferedSize,
input, len);
3755 state->bufferedSize += (XXH32_hash_t)len;
3759 {
const xxh_u8* xinput = (
const xxh_u8*)
input;
3760 const xxh_u8*
const bEnd = xinput + len;
3762 if (state->bufferedSize) {
3763 XXH_memcpy(state->buffer + state->bufferedSize, xinput,
sizeof(state->buffer) - state->bufferedSize);
3764 xinput +=
sizeof(state->buffer) - state->bufferedSize;
3766 (void)XXH64_consumeLong(state->acc, state->buffer,
sizeof(state->buffer), XXH_aligned);
3767 state->bufferedSize = 0;
3770 XXH_ASSERT(xinput <= bEnd);
3771 if ((
size_t)(bEnd - xinput) >=
sizeof(state->buffer)) {
3773 xinput = XXH64_consumeLong(state->acc, xinput, (
size_t)(bEnd - xinput), XXH_unaligned);
3776 if (xinput < bEnd) {
3778 XXH_memcpy(state->buffer, xinput, (
size_t)(bEnd-xinput));
3779 state->bufferedSize = (unsigned)(bEnd-xinput);
3792 if (state->total_len >= 32) {
3793 h64 = XXH64_mergeAccs(state->acc);
3795 h64 = state->acc[2] + XXH_PRIME64_5;
3798 h64 += (xxh_u64) state->total_len;
3800 return XXH64_finalize(h64, state->buffer, (
size_t)state->total_len, XXH_aligned);
3810 if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
3811 XXH_memcpy(dst, &hash,
sizeof(*dst));
3817 return XXH_readBE64(src);
3836#if (defined(__GNUC__) && (__GNUC__ >= 3)) \
3837 || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
3838 || defined(__clang__)
3839# define XXH_likely(x) __builtin_expect(x, 1)
3840# define XXH_unlikely(x) __builtin_expect(x, 0)
3842# define XXH_likely(x) (x)
3843# define XXH_unlikely(x) (x)
3846#ifndef XXH_HAS_INCLUDE
3847# ifdef __has_include
3852# define XXH_HAS_INCLUDE __has_include
3854# define XXH_HAS_INCLUDE(x) 0
3858#if defined(__GNUC__) || defined(__clang__)
3859# if defined(__ARM_FEATURE_SVE)
3860# include <arm_sve.h>
3862# if defined(__ARM_NEON__) || defined(__ARM_NEON) \
3863 || (defined(_M_ARM) && _M_ARM >= 7) \
3864 || defined(_M_ARM64) || defined(_M_ARM64EC) \
3865 || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE(<arm_neon.h>))
3866# define inline __inline__
3867# include <arm_neon.h>
3869# elif defined(__AVX2__)
3870# include <immintrin.h>
3871# elif defined(__SSE2__)
3872# include <emmintrin.h>
3873# elif defined(__loongarch_asx)
3874# include <lasxintrin.h>
3875# include <lsxintrin.h>
3876# elif defined(__loongarch_sx)
3877# include <lsxintrin.h>
3878# elif defined(__riscv_vector)
3879# include <riscv_vector.h>
3883#if defined(_MSC_VER)
3956#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM)
3957# warning "XXH3 is highly inefficient without ARM or Thumb-2."
3975# define XXH_VECTOR XXH_SCALAR
3985# define XXH_ACC_ALIGN 8
3994 defined(__ARM_NEON__) || defined(__ARM_NEON) \
3995 || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) \
3996 || (defined(__wasm_simd128__) && XXH_HAS_INCLUDE(<arm_neon.h>)) \
3998 defined(_WIN32) || defined(__LITTLE_ENDIAN__) \
3999 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
4001# define XXH_VECTOR XXH_NEON
4002# elif defined(__ARM_FEATURE_SVE)
4003# define XXH_VECTOR XXH_SVE
4004# elif defined(__AVX512F__)
4005# define XXH_VECTOR XXH_AVX512
4006# elif defined(__AVX2__)
4007# define XXH_VECTOR XXH_AVX2
4008# elif defined(__SSE2__) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
4009# define XXH_VECTOR XXH_SSE2
4010# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
4011 || (defined(__s390x__) && defined(__VEC__)) \
4012 && defined(__GNUC__)
4013# define XXH_VECTOR XXH_VSX
4014# elif defined(__loongarch_asx)
4015# define XXH_VECTOR XXH_LASX
4016# elif defined(__loongarch_sx)
4017# define XXH_VECTOR XXH_LSX
4018# elif defined(__riscv_vector)
4019# define XXH_VECTOR XXH_RVV
4021# define XXH_VECTOR XXH_SCALAR
4026#if (XXH_VECTOR == XXH_SVE) && !defined(__ARM_FEATURE_SVE)
4028# pragma warning(once : 4606)
4030# warning "__ARM_FEATURE_SVE isn't supported. Use SCALAR instead."
4033# define XXH_VECTOR XXH_SCALAR
4040#ifndef XXH_ACC_ALIGN
4041# if defined(XXH_X86DISPATCH)
4042# define XXH_ACC_ALIGN 64
4043# elif XXH_VECTOR == XXH_SCALAR
4044# define XXH_ACC_ALIGN 8
4045# elif XXH_VECTOR == XXH_SSE2
4046# define XXH_ACC_ALIGN 16
4047# elif XXH_VECTOR == XXH_AVX2
4048# define XXH_ACC_ALIGN 32
4049# elif XXH_VECTOR == XXH_NEON
4050# define XXH_ACC_ALIGN 16
4051# elif XXH_VECTOR == XXH_VSX
4052# define XXH_ACC_ALIGN 16
4053# elif XXH_VECTOR == XXH_AVX512
4054# define XXH_ACC_ALIGN 64
4055# elif XXH_VECTOR == XXH_SVE
4056# define XXH_ACC_ALIGN 64
4057# elif XXH_VECTOR == XXH_LASX
4058# define XXH_ACC_ALIGN 64
4059# elif XXH_VECTOR == XXH_LSX
4060# define XXH_ACC_ALIGN 64
4061# elif XXH_VECTOR == XXH_RVV
4062# define XXH_ACC_ALIGN 64
4066#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \
4067 || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512
4068# define XXH_SEC_ALIGN XXH_ACC_ALIGN
4069#elif XXH_VECTOR == XXH_SVE
4070# define XXH_SEC_ALIGN XXH_ACC_ALIGN
4071#elif XXH_VECTOR == XXH_RVV
4072# define XXH_SEC_ALIGN XXH_ACC_ALIGN
4074# define XXH_SEC_ALIGN 8
4077#if defined(__GNUC__) || defined(__clang__)
4078# define XXH_ALIASING __attribute__((__may_alias__))
4080# define XXH_ALIASING
4104#if XXH_VECTOR == XXH_AVX2 \
4105 && defined(__GNUC__) && !defined(__clang__) \
4106 && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0
4107# pragma GCC push_options
4108# pragma GCC optimize("-O2")
4111#if XXH_VECTOR == XXH_NEON
4120typedef uint64x2_t xxh_aliasing_uint64x2_t XXH_ALIASING;
4135#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__)
4136XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(
void const* ptr)
4138 return *(xxh_aliasing_uint64x2_t
const *)ptr;
4141XXH_FORCE_INLINE uint64x2_t XXH_vld1q_u64(
void const* ptr)
4143 return vreinterpretq_u64_u8(vld1q_u8((uint8_t
const*)ptr));
4155#if defined(__aarch64__) && defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 11
4156XXH_FORCE_INLINE uint64x2_t
4157XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
4160 __asm__(
"umlal %0.2d, %1.2s, %2.2s" :
"+w" (acc) :
"w" (lhs),
"w" (rhs));
4163XXH_FORCE_INLINE uint64x2_t
4164XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
4167 return vmlal_high_u32(acc, lhs, rhs);
4171XXH_FORCE_INLINE uint64x2_t
4172XXH_vmlal_low_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
4174 return vmlal_u32(acc, vget_low_u32(lhs), vget_low_u32(rhs));
4178XXH_FORCE_INLINE uint64x2_t
4179XXH_vmlal_high_u32(uint64x2_t acc, uint32x4_t lhs, uint32x4_t rhs)
4181 return vmlal_u32(acc, vget_high_u32(lhs), vget_high_u32(rhs));
4223# ifndef XXH3_NEON_LANES
4224# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \
4225 && !defined(__APPLE__) && XXH_SIZE_OPT <= 0
4226# define XXH3_NEON_LANES 6
4228# define XXH3_NEON_LANES XXH_ACC_NB
4241#if XXH_VECTOR == XXH_VSX
4250# pragma push_macro("bool")
4251# pragma push_macro("vector")
4252# pragma push_macro("pixel")
4258# if defined(__s390x__)
4259# include <s390intrin.h>
4261# include <altivec.h>
4265# pragma pop_macro("pixel")
4266# pragma pop_macro("vector")
4267# pragma pop_macro("bool")
4269typedef __vector
unsigned long long xxh_u64x2;
4270typedef __vector
unsigned char xxh_u8x16;
4271typedef __vector
unsigned xxh_u32x4;
4276typedef xxh_u64x2 xxh_aliasing_u64x2 XXH_ALIASING;
4279# if defined(__BIG_ENDIAN__) \
4280 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
4281# define XXH_VSX_BE 1
4282# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__
4283# warning "-maltivec=be is not recommended. Please use native endianness."
4284# define XXH_VSX_BE 1
4286# define XXH_VSX_BE 0
4291# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
4292# define XXH_vec_revb vec_revb
4297XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
4299 xxh_u8x16
const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
4300 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
4301 return vec_perm(val, val, vByteSwap);
4309XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(
const void *ptr)
4312 XXH_memcpy(&ret, ptr,
sizeof(xxh_u64x2));
4314 ret = XXH_vec_revb(ret);
4325# if defined(__s390x__)
4327# define XXH_vec_mulo vec_mulo
4328# define XXH_vec_mule vec_mule
4329# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) && !defined(__ibmxl__)
4332# define XXH_vec_mulo __builtin_altivec_vmulouw
4333# define XXH_vec_mule __builtin_altivec_vmuleuw
4337XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4
a, xxh_u32x4
b)
4340 __asm__(
"vmulouw %0, %1, %2" :
"=v" (result) :
"v" (
a),
"v" (
b));
4343XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4
a, xxh_u32x4
b)
4346 __asm__(
"vmuleuw %0, %1, %2" :
"=v" (result) :
"v" (
a),
"v" (
b));
4352#if XXH_VECTOR == XXH_SVE
4353#define ACCRND(acc, offset) \
4355 svuint64_t input_vec = svld1_u64(mask, xinput + offset); \
4356 svuint64_t secret_vec = svld1_u64(mask, xsecret + offset); \
4357 svuint64_t mixed = sveor_u64_x(mask, secret_vec, input_vec); \
4358 svuint64_t swapped = svtbl_u64(input_vec, kSwap); \
4359 svuint64_t mixed_lo = svextw_u64_x(mask, mixed); \
4360 svuint64_t mixed_hi = svlsr_n_u64_x(mask, mixed, 32); \
4361 svuint64_t mul = svmad_u64_x(mask, mixed_lo, mixed_hi, swapped); \
4362 acc = svadd_u64_x(mask, acc, mul); \
4368#if defined(XXH_NO_PREFETCH)
4369# define XXH_PREFETCH(ptr) (void)(ptr)
4371# if XXH_SIZE_OPT >= 1
4372# define XXH_PREFETCH(ptr) (void)(ptr)
4373# elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
4374# include <mmintrin.h>
4375# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
4376# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
4377# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 , 3 )
4379# define XXH_PREFETCH(ptr) (void)(ptr)
4388#define XXH_SECRET_DEFAULT_SIZE 192
4390#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
4391# error "default keyset is not large enough"
4398XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
4399 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
4400 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
4401 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
4402 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
4403 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
4404 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
4405 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
4406 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
4407 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
4408 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
4409 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
4410 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
4413static const xxh_u64 PRIME_MX1 = 0x165667919E3779F9ULL;
4414static const xxh_u64 PRIME_MX2 = 0x9FB21C651E98DF25ULL;
4417# define kSecret XXH3_kSecret
4437XXH_FORCE_INLINE xxh_u64
4438XXH_mult32to64(xxh_u64
x, xxh_u64
y)
4440 return (
x & 0xFFFFFFFF) * (
y & 0xFFFFFFFF);
4442#elif defined(_MSC_VER) && defined(_M_IX86)
4443# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y))
4452# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y))
4465XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
4482#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \
4483 && defined(__SIZEOF_INT128__) \
4484 || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
4486 __uint128_t
const product = (__uint128_t)lhs * (__uint128_t)rhs;
4488 r128.
low64 = (xxh_u64)(product);
4489 r128.
high64 = (xxh_u64)(product >> 64);
4499#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC)
4502# pragma intrinsic(_umul128)
4504 xxh_u64 product_high;
4505 xxh_u64
const product_low = _umul128(lhs, rhs, &product_high);
4507 r128.
low64 = product_low;
4508 r128.
high64 = product_high;
4516#elif defined(_M_ARM64) || defined(_M_ARM64EC)
4519# pragma intrinsic(__umulh)
4522 r128.
low64 = lhs * rhs;
4523 r128.
high64 = __umulh(lhs, rhs);
4571 xxh_u64
const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
4572 xxh_u64
const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
4573 xxh_u64
const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
4574 xxh_u64
const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32);
4577 xxh_u64
const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
4578 xxh_u64
const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
4579 xxh_u64
const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
4599XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
4606XXH_FORCE_INLINE
XXH_CONSTF xxh_u64 XXH_xorshift64(xxh_u64 v64,
int shift)
4608 XXH_ASSERT(0 <= shift && shift < 64);
4609 return v64 ^ (v64 >> shift);
4618 h64 = XXH_xorshift64(h64, 37);
4620 h64 = XXH_xorshift64(h64, 32);
4629static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
4632 h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
4634 h64 ^= (h64 >> 35) + len ;
4636 return XXH_xorshift64(h64, 28);
4674XXH3_len_1to3_64b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
4676 XXH_ASSERT(
input != NULL);
4677 XXH_ASSERT(1 <= len && len <= 3);
4678 XXH_ASSERT(secret != NULL);
4684 { xxh_u8
const c1 =
input[0];
4685 xxh_u8
const c2 =
input[len >> 1];
4686 xxh_u8
const c3 =
input[len - 1];
4687 xxh_u32
const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24)
4688 | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
4689 xxh_u64
const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
4690 xxh_u64
const keyed = (xxh_u64)combined ^ bitflip;
4691 return XXH64_avalanche(keyed);
4696XXH3_len_4to8_64b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
4698 XXH_ASSERT(
input != NULL);
4699 XXH_ASSERT(secret != NULL);
4700 XXH_ASSERT(4 <= len && len <= 8);
4701 seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
4702 { xxh_u32
const input1 = XXH_readLE32(
input);
4703 xxh_u32
const input2 = XXH_readLE32(
input + len - 4);
4704 xxh_u64
const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed;
4705 xxh_u64
const input64 = input2 + (((xxh_u64)input1) << 32);
4706 xxh_u64
const keyed = input64 ^ bitflip;
4707 return XXH3_rrmxmx(keyed, len);
4712XXH3_len_9to16_64b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
4714 XXH_ASSERT(
input != NULL);
4715 XXH_ASSERT(secret != NULL);
4716 XXH_ASSERT(9 <= len && len <= 16);
4717 { xxh_u64
const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed;
4718 xxh_u64
const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed;
4719 xxh_u64
const input_lo = XXH_readLE64(
input) ^ bitflip1;
4720 xxh_u64
const input_hi = XXH_readLE64(
input + len - 8) ^ bitflip2;
4721 xxh_u64
const acc = len
4722 + XXH_swap64(input_lo) + input_hi
4723 + XXH3_mul128_fold64(input_lo, input_hi);
4724 return XXH3_avalanche(acc);
4729XXH3_len_0to16_64b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
4731 XXH_ASSERT(len <= 16);
4732 {
if (XXH_likely(len > 8))
return XXH3_len_9to16_64b(
input, len, secret, seed);
4733 if (XXH_likely(len >= 4))
return XXH3_len_4to8_64b(
input, len, secret, seed);
4734 if (len)
return XXH3_len_1to3_64b(
input, len, secret, seed);
4735 return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64)));
4765XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(
const xxh_u8* XXH_RESTRICT
input,
4766 const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64)
4768#if defined(__GNUC__) && !defined(__clang__) \
4769 && defined(__i386__) && defined(__SSE2__) \
4770 && !defined(XXH_ENABLE_AUTOVECTORIZE)
4786 XXH_COMPILER_GUARD(seed64);
4788 { xxh_u64
const input_lo = XXH_readLE64(
input);
4789 xxh_u64
const input_hi = XXH_readLE64(
input+8);
4790 return XXH3_mul128_fold64(
4791 input_lo ^ (XXH_readLE64(secret) + seed64),
4792 input_hi ^ (XXH_readLE64(secret+8) - seed64)
4799XXH3_len_17to128_64b(
const xxh_u8* XXH_RESTRICT
input,
size_t len,
4800 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
4804 XXH_ASSERT(16 < len && len <= 128);
4806 { xxh_u64 acc = len * XXH_PRIME64_1;
4807#if XXH_SIZE_OPT >= 1
4809 unsigned int i = (
unsigned int)(len - 1) / 32;
4811 acc += XXH3_mix16B(
input+16 * i, secret+32*i, seed);
4812 acc += XXH3_mix16B(
input+len-16*(i+1), secret+32*i+16, seed);
4818 acc += XXH3_mix16B(
input+48, secret+96, seed);
4819 acc += XXH3_mix16B(
input+len-64, secret+112, seed);
4821 acc += XXH3_mix16B(
input+32, secret+64, seed);
4822 acc += XXH3_mix16B(
input+len-48, secret+80, seed);
4824 acc += XXH3_mix16B(
input+16, secret+32, seed);
4825 acc += XXH3_mix16B(
input+len-32, secret+48, seed);
4827 acc += XXH3_mix16B(
input+0, secret+0, seed);
4828 acc += XXH3_mix16B(
input+len-16, secret+16, seed);
4830 return XXH3_avalanche(acc);
4835XXH3_len_129to240_64b(
const xxh_u8* XXH_RESTRICT
input,
size_t len,
4836 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
4840 XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
4842 #define XXH3_MIDSIZE_STARTOFFSET 3
4843 #define XXH3_MIDSIZE_LASTOFFSET 17
4845 { xxh_u64 acc = len * XXH_PRIME64_1;
4847 unsigned int const nbRounds = (
unsigned int)len / 16;
4849 XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
4850 for (i=0;
i<8;
i++) {
4851 acc += XXH3_mix16B(
input+(16*i), secret+(16*i), seed);
4855 XXH_ASSERT(nbRounds >= 8);
4856 acc = XXH3_avalanche(acc);
4857#if defined(__clang__) \
4858 && (defined(__ARM_NEON) || defined(__ARM_NEON__)) \
4859 && !defined(XXH_ENABLE_AUTOVECTORIZE)
4880 #pragma clang loop vectorize(disable)
4882 for (i=8 ;
i < nbRounds;
i++) {
4886 XXH_COMPILER_GUARD(acc);
4887 acc_end += XXH3_mix16B(
input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
4889 return XXH3_avalanche(acc + acc_end);
4896#define XXH_STRIPE_LEN 64
4897#define XXH_SECRET_CONSUME_RATE 8
4898#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64))
4901# define STRIPE_LEN XXH_STRIPE_LEN
4902# define ACC_NB XXH_ACC_NB
4905#ifndef XXH_PREFETCH_DIST
4907# define XXH_PREFETCH_DIST 320
4909# if (XXH_VECTOR == XXH_AVX512)
4910# define XXH_PREFETCH_DIST 512
4912# define XXH_PREFETCH_DIST 384
4927#define XXH3_ACCUMULATE_TEMPLATE(name) \
4929XXH3_accumulate_##name(xxh_u64* XXH_RESTRICT acc, \
4930 const xxh_u8* XXH_RESTRICT input, \
4931 const xxh_u8* XXH_RESTRICT secret, \
4935 for (n = 0; n < nbStripes; n++ ) { \
4936 const xxh_u8* const in = input + n*XXH_STRIPE_LEN; \
4937 XXH_PREFETCH(in + XXH_PREFETCH_DIST); \
4938 XXH3_accumulate_512_##name( \
4941 secret + n*XXH_SECRET_CONSUME_RATE); \
4946XXH_FORCE_INLINE
void XXH_writeLE64(
void* dst, xxh_u64 v64)
4948 if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
4949 XXH_memcpy(dst, &v64,
sizeof(v64));
4957#if !defined (__VMS) \
4958 && (defined (__cplusplus) \
4959 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ) )
4960 typedef int64_t xxh_i64;
4963 typedef long long xxh_i64;
4990#if (XXH_VECTOR == XXH_AVX512) \
4991 || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0)
4993#ifndef XXH_TARGET_AVX512
4994# define XXH_TARGET_AVX512
4997XXH_FORCE_INLINE XXH_TARGET_AVX512
void
4998XXH3_accumulate_512_avx512(
void* XXH_RESTRICT acc,
4999 const void* XXH_RESTRICT
input,
5000 const void* XXH_RESTRICT secret)
5002 __m512i*
const xacc = (__m512i *) acc;
5003 XXH_ASSERT((((
size_t)acc) & 63) == 0);
5004 XXH_STATIC_ASSERT(XXH_STRIPE_LEN ==
sizeof(__m512i));
5008 __m512i
const data_vec = _mm512_loadu_si512 (
input);
5010 __m512i
const key_vec = _mm512_loadu_si512 (secret);
5012 __m512i
const data_key = _mm512_xor_si512 (data_vec, key_vec);
5014 __m512i
const data_key_lo = _mm512_srli_epi64 (data_key, 32);
5016 __m512i
const product = _mm512_mul_epu32 (data_key, data_key_lo);
5018 __m512i
const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2));
5019 __m512i
const sum = _mm512_add_epi64(*xacc, data_swap);
5021 *xacc = _mm512_add_epi64(product, sum);
5024XXH_FORCE_INLINE XXH_TARGET_AVX512 XXH3_ACCUMULATE_TEMPLATE(avx512)
5047XXH_FORCE_INLINE XXH_TARGET_AVX512
void
5048XXH3_scrambleAcc_avx512(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5050 XXH_ASSERT((((
size_t)acc) & 63) == 0);
5051 XXH_STATIC_ASSERT(XXH_STRIPE_LEN ==
sizeof(__m512i));
5052 { __m512i*
const xacc = (__m512i*) acc;
5053 const __m512i prime32 = _mm512_set1_epi32((
int)XXH_PRIME32_1);
5056 __m512i
const acc_vec = *xacc;
5057 __m512i
const shifted = _mm512_srli_epi64 (acc_vec, 47);
5059 __m512i
const key_vec = _mm512_loadu_si512 (secret);
5060 __m512i
const data_key = _mm512_ternarylogic_epi32(key_vec, acc_vec, shifted, 0x96 );
5063 __m512i
const data_key_hi = _mm512_srli_epi64 (data_key, 32);
5064 __m512i
const prod_lo = _mm512_mul_epu32 (data_key, prime32);
5065 __m512i
const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32);
5066 *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32));
5070XXH_FORCE_INLINE XXH_TARGET_AVX512
void
5071XXH3_initCustomSecret_avx512(
void* XXH_RESTRICT customSecret, xxh_u64 seed64)
5073 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0);
5074 XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64);
5075 XXH_ASSERT(((
size_t)customSecret & 63) == 0);
5076 (void)(&XXH_writeLE64);
5077 {
int const nbRounds = XXH_SECRET_DEFAULT_SIZE /
sizeof(__m512i);
5078 __m512i
const seed_pos = _mm512_set1_epi64((xxh_i64)seed64);
5079 __m512i
const seed = _mm512_mask_sub_epi64(seed_pos, 0xAA, _mm512_set1_epi8(0), seed_pos);
5081 const __m512i*
const src = (
const __m512i*) ((
const void*) XXH3_kSecret);
5082 __m512i*
const dest = ( __m512i*) customSecret;
5084 XXH_ASSERT(((
size_t)src & 63) == 0);
5085 XXH_ASSERT(((
size_t)dest & 63) == 0);
5086 for (i=0;
i < nbRounds; ++
i) {
5087 dest[
i] = _mm512_add_epi64(_mm512_load_si512(src + i), seed);
5093#if (XXH_VECTOR == XXH_AVX2) \
5094 || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0)
5096#ifndef XXH_TARGET_AVX2
5097# define XXH_TARGET_AVX2
5100XXH_FORCE_INLINE XXH_TARGET_AVX2
void
5101XXH3_accumulate_512_avx2(
void* XXH_RESTRICT acc,
5102 const void* XXH_RESTRICT
input,
5103 const void* XXH_RESTRICT secret)
5105 XXH_ASSERT((((
size_t)acc) & 31) == 0);
5106 { __m256i*
const xacc = (__m256i *) acc;
5109 const __m256i*
const xinput = (
const __m256i *)
input;
5112 const __m256i*
const xsecret = (
const __m256i *) secret;
5115 for (i=0;
i < XXH_STRIPE_LEN/
sizeof(__m256i);
i++) {
5117 __m256i
const data_vec = _mm256_loadu_si256 (xinput+i);
5119 __m256i
const key_vec = _mm256_loadu_si256 (xsecret+i);
5121 __m256i
const data_key = _mm256_xor_si256 (data_vec, key_vec);
5123 __m256i
const data_key_lo = _mm256_srli_epi64 (data_key, 32);
5125 __m256i
const product = _mm256_mul_epu32 (data_key, data_key_lo);
5127 __m256i
const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2));
5128 __m256i
const sum = _mm256_add_epi64(xacc[i], data_swap);
5130 xacc[
i] = _mm256_add_epi64(product, sum);
5133XXH_FORCE_INLINE XXH_TARGET_AVX2 XXH3_ACCUMULATE_TEMPLATE(avx2)
5135XXH_FORCE_INLINE XXH_TARGET_AVX2
void
5136XXH3_scrambleAcc_avx2(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5138 XXH_ASSERT((((
size_t)acc) & 31) == 0);
5139 { __m256i*
const xacc = (__m256i*) acc;
5142 const __m256i*
const xsecret = (
const __m256i *) secret;
5143 const __m256i prime32 = _mm256_set1_epi32((
int)XXH_PRIME32_1);
5146 for (i=0;
i < XXH_STRIPE_LEN/
sizeof(__m256i);
i++) {
5148 __m256i
const acc_vec = xacc[
i];
5149 __m256i
const shifted = _mm256_srli_epi64 (acc_vec, 47);
5150 __m256i
const data_vec = _mm256_xor_si256 (acc_vec, shifted);
5152 __m256i
const key_vec = _mm256_loadu_si256 (xsecret+i);
5153 __m256i
const data_key = _mm256_xor_si256 (data_vec, key_vec);
5156 __m256i
const data_key_hi = _mm256_srli_epi64 (data_key, 32);
5157 __m256i
const prod_lo = _mm256_mul_epu32 (data_key, prime32);
5158 __m256i
const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32);
5159 xacc[
i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32));
5164XXH_FORCE_INLINE XXH_TARGET_AVX2
void XXH3_initCustomSecret_avx2(
void* XXH_RESTRICT customSecret, xxh_u64 seed64)
5166 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0);
5167 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE /
sizeof(__m256i)) == 6);
5168 XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
5169 (void)(&XXH_writeLE64);
5170 XXH_PREFETCH(customSecret);
5171 { __m256i
const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
5173 const __m256i*
const src = (
const __m256i*) ((
const void*) XXH3_kSecret);
5174 __m256i* dest = ( __m256i*) customSecret;
5176# if defined(__GNUC__) || defined(__clang__)
5182 XXH_COMPILER_GUARD(dest);
5184 XXH_ASSERT(((
size_t)src & 31) == 0);
5185 XXH_ASSERT(((
size_t)dest & 31) == 0);
5188 dest[0] = _mm256_add_epi64(_mm256_load_si256(src+0), seed);
5189 dest[1] = _mm256_add_epi64(_mm256_load_si256(src+1), seed);
5190 dest[2] = _mm256_add_epi64(_mm256_load_si256(src+2), seed);
5191 dest[3] = _mm256_add_epi64(_mm256_load_si256(src+3), seed);
5192 dest[4] = _mm256_add_epi64(_mm256_load_si256(src+4), seed);
5193 dest[5] = _mm256_add_epi64(_mm256_load_si256(src+5), seed);
5200#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH)
5202#ifndef XXH_TARGET_SSE2
5203# define XXH_TARGET_SSE2
5206XXH_FORCE_INLINE XXH_TARGET_SSE2
void
5207XXH3_accumulate_512_sse2(
void* XXH_RESTRICT acc,
5208 const void* XXH_RESTRICT
input,
5209 const void* XXH_RESTRICT secret)
5212 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5213 { __m128i*
const xacc = (__m128i *) acc;
5216 const __m128i*
const xinput = (
const __m128i *)
input;
5219 const __m128i*
const xsecret = (
const __m128i *) secret;
5222 for (i=0;
i < XXH_STRIPE_LEN/
sizeof(__m128i);
i++) {
5224 __m128i
const data_vec = _mm_loadu_si128 (xinput+i);
5226 __m128i
const key_vec = _mm_loadu_si128 (xsecret+i);
5228 __m128i
const data_key = _mm_xor_si128 (data_vec, key_vec);
5230 __m128i
const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
5232 __m128i
const product = _mm_mul_epu32 (data_key, data_key_lo);
5234 __m128i
const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2));
5235 __m128i
const sum = _mm_add_epi64(xacc[i], data_swap);
5237 xacc[
i] = _mm_add_epi64(product, sum);
5240XXH_FORCE_INLINE XXH_TARGET_SSE2 XXH3_ACCUMULATE_TEMPLATE(sse2)
5242XXH_FORCE_INLINE XXH_TARGET_SSE2
void
5243XXH3_scrambleAcc_sse2(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5245 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5246 { __m128i*
const xacc = (__m128i*) acc;
5249 const __m128i*
const xsecret = (
const __m128i *) secret;
5250 const __m128i prime32 = _mm_set1_epi32((
int)XXH_PRIME32_1);
5253 for (i=0;
i < XXH_STRIPE_LEN/
sizeof(__m128i);
i++) {
5255 __m128i
const acc_vec = xacc[
i];
5256 __m128i
const shifted = _mm_srli_epi64 (acc_vec, 47);
5257 __m128i
const data_vec = _mm_xor_si128 (acc_vec, shifted);
5259 __m128i
const key_vec = _mm_loadu_si128 (xsecret+i);
5260 __m128i
const data_key = _mm_xor_si128 (data_vec, key_vec);
5263 __m128i
const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
5264 __m128i
const prod_lo = _mm_mul_epu32 (data_key, prime32);
5265 __m128i
const prod_hi = _mm_mul_epu32 (data_key_hi, prime32);
5266 xacc[
i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32));
5271XXH_FORCE_INLINE XXH_TARGET_SSE2
void XXH3_initCustomSecret_sse2(
void* XXH_RESTRICT customSecret, xxh_u64 seed64)
5273 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
5274 (void)(&XXH_writeLE64);
5275 {
int const nbRounds = XXH_SECRET_DEFAULT_SIZE /
sizeof(__m128i);
5277# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER <= 1900
5281 xxh_u64
const seed64_unsigned = (xxh_u64)seed64;
5282 xxh_u64
const neg_seed64 = (xxh_u64)(0ULL - seed64_unsigned);
5283 __m128i
const seed = _mm_set_epi32(
5284 (
int)(neg_seed64 >> 32),
5286 (
int)(seed64_unsigned >> 32),
5287 (
int)(seed64_unsigned)
5290 __m128i
const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
5294 const void*
const src16 = XXH3_kSecret;
5295 __m128i* dst16 = (__m128i*) customSecret;
5296# if defined(__GNUC__) || defined(__clang__)
5302 XXH_COMPILER_GUARD(dst16);
5304 XXH_ASSERT(((
size_t)src16 & 15) == 0);
5305 XXH_ASSERT(((
size_t)dst16 & 15) == 0);
5307 for (i=0;
i < nbRounds; ++
i) {
5308 dst16[
i] = _mm_add_epi64(_mm_load_si128((
const __m128i *)src16+i), seed);
5314#if (XXH_VECTOR == XXH_NEON)
5317XXH_FORCE_INLINE
void
5318XXH3_scalarRound(
void* XXH_RESTRICT acc,
void const* XXH_RESTRICT
input,
5319 void const* XXH_RESTRICT secret,
size_t lane);
5321XXH_FORCE_INLINE
void
5322XXH3_scalarScrambleRound(
void* XXH_RESTRICT acc,
5323 void const* XXH_RESTRICT secret,
size_t lane);
5349XXH_FORCE_INLINE
void
5350XXH3_accumulate_512_neon(
void* XXH_RESTRICT acc,
5351 const void* XXH_RESTRICT
input,
5352 const void* XXH_RESTRICT secret)
5354 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5355 XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0);
5357 xxh_aliasing_uint64x2_t*
const xacc = (xxh_aliasing_uint64x2_t*) acc;
5359 uint8_t
const* xinput = (
const uint8_t *)
input;
5360 uint8_t
const* xsecret = (
const uint8_t *) secret;
5363#ifdef __wasm_simd128__
5381 XXH_COMPILER_GUARD(xsecret);
5384 for (i = XXH3_NEON_LANES;
i < XXH_ACC_NB;
i++) {
5385 XXH3_scalarRound(acc,
input, secret, i);
5389 for (;
i+1 < XXH3_NEON_LANES / 2;
i+=2) {
5391 uint64x2_t data_vec_1 = XXH_vld1q_u64(xinput + (i * 16));
5392 uint64x2_t data_vec_2 = XXH_vld1q_u64(xinput + ((i+1) * 16));
5394 uint64x2_t key_vec_1 = XXH_vld1q_u64(xsecret + (i * 16));
5395 uint64x2_t key_vec_2 = XXH_vld1q_u64(xsecret + ((i+1) * 16));
5397 uint64x2_t data_swap_1 = vextq_u64(data_vec_1, data_vec_1, 1);
5398 uint64x2_t data_swap_2 = vextq_u64(data_vec_2, data_vec_2, 1);
5400 uint64x2_t data_key_1 = veorq_u64(data_vec_1, key_vec_1);
5401 uint64x2_t data_key_2 = veorq_u64(data_vec_2, key_vec_2);
5416 uint32x4x2_t unzipped = vuzpq_u32(
5417 vreinterpretq_u32_u64(data_key_1),
5418 vreinterpretq_u32_u64(data_key_2)
5421 uint32x4_t data_key_lo = unzipped.val[0];
5423 uint32x4_t data_key_hi = unzipped.val[1];
5431 uint64x2_t sum_1 = XXH_vmlal_low_u32(data_swap_1, data_key_lo, data_key_hi);
5432 uint64x2_t sum_2 = XXH_vmlal_high_u32(data_swap_2, data_key_lo, data_key_hi);
5445 XXH_COMPILER_GUARD_CLANG_NEON(sum_1);
5446 XXH_COMPILER_GUARD_CLANG_NEON(sum_2);
5448 xacc[
i] = vaddq_u64(xacc[i], sum_1);
5449 xacc[
i+1] = vaddq_u64(xacc[i+1], sum_2);
5452 for (;
i < XXH3_NEON_LANES / 2;
i++) {
5454 uint64x2_t data_vec = XXH_vld1q_u64(xinput + (i * 16));
5456 uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16));
5458 uint64x2_t data_swap = vextq_u64(data_vec, data_vec, 1);
5460 uint64x2_t data_key = veorq_u64(data_vec, key_vec);
5463 uint32x2_t data_key_lo = vmovn_u64(data_key);
5465 uint32x2_t data_key_hi = vshrn_n_u64(data_key, 32);
5467 uint64x2_t sum = vmlal_u32(data_swap, data_key_lo, data_key_hi);
5469 XXH_COMPILER_GUARD_CLANG_NEON(sum);
5471 xacc[
i] = vaddq_u64 (xacc[i], sum);
5475XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(neon)
5477XXH_FORCE_INLINE
void
5478XXH3_scrambleAcc_neon(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5480 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5482 { xxh_aliasing_uint64x2_t* xacc = (xxh_aliasing_uint64x2_t*) acc;
5483 uint8_t
const* xsecret = (uint8_t
const*) secret;
5487#ifndef __wasm_simd128__
5489 uint32x2_t
const kPrimeLo = vdup_n_u32(XXH_PRIME32_1);
5491 uint32x4_t
const kPrimeHi = vreinterpretq_u32_u64(vdupq_n_u64((xxh_u64)XXH_PRIME32_1 << 32));
5495 for (i = XXH3_NEON_LANES;
i < XXH_ACC_NB;
i++) {
5496 XXH3_scalarScrambleRound(acc, secret, i);
5498 for (i=0;
i < XXH3_NEON_LANES / 2;
i++) {
5500 uint64x2_t acc_vec = xacc[
i];
5501 uint64x2_t shifted = vshrq_n_u64(acc_vec, 47);
5502 uint64x2_t data_vec = veorq_u64(acc_vec, shifted);
5505 uint64x2_t key_vec = XXH_vld1q_u64(xsecret + (i * 16));
5506 uint64x2_t data_key = veorq_u64(data_vec, key_vec);
5508#ifdef __wasm_simd128__
5510 xacc[
i] = data_key * XXH_PRIME32_1;
5523 uint32x4_t prod_hi = vmulq_u32 (vreinterpretq_u32_u64(data_key), kPrimeHi);
5525 uint32x2_t data_key_lo = vmovn_u64(data_key);
5527 xacc[
i] = vmlal_u32(vreinterpretq_u64_u32(prod_hi), data_key_lo, kPrimeLo);
5534#if (XXH_VECTOR == XXH_VSX)
5536XXH_FORCE_INLINE
void
5537XXH3_accumulate_512_vsx(
void* XXH_RESTRICT acc,
5538 const void* XXH_RESTRICT
input,
5539 const void* XXH_RESTRICT secret)
5542 xxh_aliasing_u64x2*
const xacc = (xxh_aliasing_u64x2*) acc;
5543 xxh_u8
const*
const xinput = (xxh_u8
const*)
input;
5544 xxh_u8
const*
const xsecret = (xxh_u8
const*) secret;
5545 xxh_u64x2
const v32 = { 32, 32 };
5547 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(xxh_u64x2);
i++) {
5549 xxh_u64x2
const data_vec = XXH_vec_loadu(xinput + 16*i);
5551 xxh_u64x2
const key_vec = XXH_vec_loadu(xsecret + 16*i);
5552 xxh_u64x2
const data_key = data_vec ^ key_vec;
5554 xxh_u32x4
const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
5556 xxh_u64x2
const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
5558 xxh_u64x2 acc_vec = xacc[
i];
5563 acc_vec += vec_permi(data_vec, data_vec, 2);
5565 acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
5570XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(vsx)
5572XXH_FORCE_INLINE
void
5573XXH3_scrambleAcc_vsx(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5575 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5577 { xxh_aliasing_u64x2*
const xacc = (xxh_aliasing_u64x2*) acc;
5578 const xxh_u8*
const xsecret = (
const xxh_u8*) secret;
5580 xxh_u64x2
const v32 = { 32, 32 };
5581 xxh_u64x2
const v47 = { 47, 47 };
5582 xxh_u32x4
const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 };
5584 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(xxh_u64x2);
i++) {
5586 xxh_u64x2
const acc_vec = xacc[
i];
5587 xxh_u64x2
const data_vec = acc_vec ^ (acc_vec >> v47);
5590 xxh_u64x2
const key_vec = XXH_vec_loadu(xsecret + 16*i);
5591 xxh_u64x2
const data_key = data_vec ^ key_vec;
5595 xxh_u64x2
const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime);
5597 xxh_u64x2
const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime);
5598 xacc[
i] = prod_odd + (prod_even << v32);
5604#if (XXH_VECTOR == XXH_SVE)
5606XXH_FORCE_INLINE
void
5607XXH3_accumulate_512_sve(
void* XXH_RESTRICT acc,
5608 const void* XXH_RESTRICT
input,
5609 const void* XXH_RESTRICT secret)
5611 uint64_t *xacc = (uint64_t *)acc;
5612 const uint64_t *xinput = (
const uint64_t *)(
const void *)
input;
5613 const uint64_t *xsecret = (
const uint64_t *)(
const void *)secret;
5614 svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1);
5615 uint64_t element_count = svcntd();
5616 if (element_count >= 8) {
5617 svbool_t
mask = svptrue_pat_b64(SV_VL8);
5618 svuint64_t vacc = svld1_u64(mask, xacc);
5620 svst1_u64(mask, xacc, vacc);
5621 }
else if (element_count == 2) {
5622 svbool_t
mask = svptrue_pat_b64(SV_VL2);
5623 svuint64_t acc0 = svld1_u64(mask, xacc + 0);
5624 svuint64_t acc1 = svld1_u64(mask, xacc + 2);
5625 svuint64_t acc2 = svld1_u64(mask, xacc + 4);
5626 svuint64_t acc3 = svld1_u64(mask, xacc + 6);
5631 svst1_u64(mask, xacc + 0, acc0);
5632 svst1_u64(mask, xacc + 2, acc1);
5633 svst1_u64(mask, xacc + 4, acc2);
5634 svst1_u64(mask, xacc + 6, acc3);
5636 svbool_t
mask = svptrue_pat_b64(SV_VL4);
5637 svuint64_t acc0 = svld1_u64(mask, xacc + 0);
5638 svuint64_t acc1 = svld1_u64(mask, xacc + 4);
5641 svst1_u64(mask, xacc + 0, acc0);
5642 svst1_u64(mask, xacc + 4, acc1);
5646XXH_FORCE_INLINE
void
5647XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc,
5648 const xxh_u8* XXH_RESTRICT
input,
5649 const xxh_u8* XXH_RESTRICT secret,
5652 if (nbStripes != 0) {
5653 uint64_t *xacc = (uint64_t *)acc;
5654 const uint64_t *xinput = (
const uint64_t *)(
const void *)
input;
5655 const uint64_t *xsecret = (
const uint64_t *)(
const void *)secret;
5656 svuint64_t kSwap = sveor_n_u64_z(svptrue_b64(), svindex_u64(0, 1), 1);
5657 uint64_t element_count = svcntd();
5658 if (element_count >= 8) {
5659 svbool_t
mask = svptrue_pat_b64(SV_VL8);
5660 svuint64_t vacc = svld1_u64(mask, xacc + 0);
5663 svprfd(mask, xinput + 128, SV_PLDL1STRM);
5668 }
while (nbStripes != 0);
5670 svst1_u64(mask, xacc + 0, vacc);
5671 }
else if (element_count == 2) {
5672 svbool_t
mask = svptrue_pat_b64(SV_VL2);
5673 svuint64_t acc0 = svld1_u64(mask, xacc + 0);
5674 svuint64_t acc1 = svld1_u64(mask, xacc + 2);
5675 svuint64_t acc2 = svld1_u64(mask, xacc + 4);
5676 svuint64_t acc3 = svld1_u64(mask, xacc + 6);
5678 svprfd(mask, xinput + 128, SV_PLDL1STRM);
5686 }
while (nbStripes != 0);
5688 svst1_u64(mask, xacc + 0, acc0);
5689 svst1_u64(mask, xacc + 2, acc1);
5690 svst1_u64(mask, xacc + 4, acc2);
5691 svst1_u64(mask, xacc + 6, acc3);
5693 svbool_t
mask = svptrue_pat_b64(SV_VL4);
5694 svuint64_t acc0 = svld1_u64(mask, xacc + 0);
5695 svuint64_t acc1 = svld1_u64(mask, xacc + 4);
5697 svprfd(mask, xinput + 128, SV_PLDL1STRM);
5703 }
while (nbStripes != 0);
5705 svst1_u64(mask, xacc + 0, acc0);
5706 svst1_u64(mask, xacc + 4, acc1);
5713#if (XXH_VECTOR == XXH_LSX)
5714#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
5716XXH_FORCE_INLINE
void
5717XXH3_accumulate_512_lsx(
void* XXH_RESTRICT acc,
5718 const void* XXH_RESTRICT
input,
5719 const void* XXH_RESTRICT secret)
5721 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5723 __m128i*
const xacc = (__m128i *) acc;
5724 const __m128i*
const xinput = (
const __m128i *)
input;
5725 const __m128i*
const xsecret = (
const __m128i *) secret;
5728 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(__m128i);
i++) {
5730 __m128i
const data_vec = __lsx_vld(xinput + i, 0);
5732 __m128i
const key_vec = __lsx_vld(xsecret + i, 0);
5734 __m128i
const data_key = __lsx_vxor_v(data_vec, key_vec);
5736 __m128i
const data_key_lo = __lsx_vsrli_d(data_key, 32);
5739 __m128i
const product = __lsx_vmulwev_d_wu(data_key, data_key_lo);
5741 __m128i
const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2));
5742 __m128i
const sum = __lsx_vadd_d(xacc[i], data_swap);
5744 xacc[
i] = __lsx_vadd_d(product, sum);
5748XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx)
5750XXH_FORCE_INLINE
void
5751XXH3_scrambleAcc_lsx(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5753 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5755 __m128i*
const xacc = (__m128i*) acc;
5756 const __m128i*
const xsecret = (
const __m128i *) secret;
5757 const __m128i prime32 = __lsx_vreplgr2vr_d(XXH_PRIME32_1);
5760 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(__m128i);
i++) {
5762 __m128i
const acc_vec = xacc[
i];
5763 __m128i
const shifted = __lsx_vsrli_d(acc_vec, 47);
5764 __m128i
const data_vec = __lsx_vxor_v(acc_vec, shifted);
5766 __m128i
const key_vec = __lsx_vld(xsecret + i, 0);
5767 __m128i
const data_key = __lsx_vxor_v(data_vec, key_vec);
5770 xacc[
i] = __lsx_vmul_d(data_key, prime32);
5777#if (XXH_VECTOR == XXH_LASX)
5778#define _LASX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
5780XXH_FORCE_INLINE
void
5781XXH3_accumulate_512_lasx(
void* XXH_RESTRICT acc,
5782 const void* XXH_RESTRICT
input,
5783 const void* XXH_RESTRICT secret)
5785 XXH_ASSERT((((
size_t)acc) & 31) == 0);
5788 __m256i*
const xacc = (__m256i *) acc;
5789 const __m256i*
const xinput = (
const __m256i *)
input;
5790 const __m256i*
const xsecret = (
const __m256i *) secret;
5792 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(__m256i);
i++) {
5794 __m256i
const data_vec = __lasx_xvld(xinput + i, 0);
5796 __m256i
const key_vec = __lasx_xvld(xsecret + i, 0);
5798 __m256i
const data_key = __lasx_xvxor_v(data_vec, key_vec);
5800 __m256i
const data_key_lo = __lasx_xvsrli_d(data_key, 32);
5803 __m256i
const product = __lasx_xvmulwev_d_wu(data_key, data_key_lo);
5805 __m256i
const data_swap = __lasx_xvshuf4i_w(data_vec, _LASX_SHUFFLE(1, 0, 3, 2));
5806 __m256i
const sum = __lasx_xvadd_d(xacc[i], data_swap);
5808 xacc[
i] = __lasx_xvadd_d(product, sum);
5812XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lasx)
5814XXH_FORCE_INLINE
void
5815XXH3_scrambleAcc_lasx(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5817 XXH_ASSERT((((
size_t)acc) & 31) == 0);
5819 __m256i*
const xacc = (__m256i*) acc;
5820 const __m256i*
const xsecret = (
const __m256i *) secret;
5821 const __m256i prime32 = __lasx_xvreplgr2vr_d(XXH_PRIME32_1);
5824 for (i = 0;
i < XXH_STRIPE_LEN /
sizeof(__m256i);
i++) {
5826 __m256i
const acc_vec = xacc[
i];
5827 __m256i
const shifted = __lasx_xvsrli_d(acc_vec, 47);
5828 __m256i
const data_vec = __lasx_xvxor_v(acc_vec, shifted);
5830 __m256i
const key_vec = __lasx_xvld(xsecret + i, 0);
5831 __m256i
const data_key = __lasx_xvxor_v(data_vec, key_vec);
5834 xacc[
i] = __lasx_xvmul_d(data_key, prime32);
5841#if (XXH_VECTOR == XXH_RVV)
5842 #define XXH_CONCAT2(X, Y) X ## Y
5843 #define XXH_CONCAT(X, Y) XXH_CONCAT2(X, Y)
5844#if ((defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 13) || \
5845 (defined(__clang__) && __clang_major__ < 16))
5846 #define XXH_RVOP(op) op
5847 #define XXH_RVCAST(op) XXH_CONCAT(vreinterpret_v_, op)
5849 #define XXH_RVOP(op) XXH_CONCAT(__riscv_, op)
5850 #define XXH_RVCAST(op) XXH_CONCAT(__riscv_vreinterpret_v_, op)
5852XXH_FORCE_INLINE
void
5853XXH3_accumulate_512_rvv(
void* XXH_RESTRICT acc,
5854 const void* XXH_RESTRICT
input,
5855 const void* XXH_RESTRICT secret)
5857 XXH_ASSERT((((
size_t)acc) & 63) == 0);
5861 size_t vl = XXH_RVOP(vsetvl_e64m2)(8);
5863 uint64_t* xacc = (uint64_t*) acc;
5864 const uint64_t* xinput = (
const uint64_t*)
input;
5865 const uint64_t* xsecret = (
const uint64_t*) secret;
5866 static const uint64_t swap_mask[16] = {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14};
5867 vuint64m2_t xswap_mask = XXH_RVOP(vle64_v_u64m2)(swap_mask, vl);
5870 for (i = 0;
i < XXH_STRIPE_LEN/8;
i += vl) {
5872 vuint64m2_t data_vec = XXH_RVCAST(u8m2_u64m2)(XXH_RVOP(vle8_v_u8m2)((
const uint8_t*)(xinput + i), vl * 8));
5874 vuint64m2_t key_vec = XXH_RVCAST(u8m2_u64m2)(XXH_RVOP(vle8_v_u8m2)((
const uint8_t*)(xsecret + i), vl * 8));
5876 vuint64m2_t acc_vec = XXH_RVOP(vle64_v_u64m2)(xacc +
i, vl);
5878 vuint64m2_t data_key = XXH_RVOP(vxor_vv_u64m2)(data_vec, key_vec, vl);
5880 vuint64m2_t data_key_hi = XXH_RVOP(vsrl_vx_u64m2)(data_key, 32, vl);
5882 vuint64m2_t data_key_lo = XXH_RVOP(vand_vx_u64m2)(data_key, 0xffffffff, vl);
5884 vuint64m2_t data_swap = XXH_RVOP(vrgather_vv_u64m2)(data_vec, xswap_mask, vl);
5886 acc_vec = XXH_RVOP(vmacc_vv_u64m2)(acc_vec, data_key_lo, data_key_hi, vl);
5888 acc_vec = XXH_RVOP(vadd_vv_u64m2)(acc_vec, data_swap, vl);
5890 XXH_RVOP(vse64_v_u64m2)(xacc +
i, acc_vec, vl);
5895XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(rvv)
5897XXH_FORCE_INLINE
void
5898XXH3_scrambleAcc_rvv(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
5900 XXH_ASSERT((((
size_t)acc) & 15) == 0);
5902 size_t count = XXH_STRIPE_LEN/8;
5903 uint64_t* xacc = (uint64_t*)acc;
5904 const uint8_t* xsecret = (
const uint8_t *)secret;
5906 for (;
count > 0;
count -= vl, xacc += vl, xsecret += vl*8) {
5907 vl = XXH_RVOP(vsetvl_e64m2)(
count);
5910 vuint64m2_t key_vec = XXH_RVCAST(u8m2_u64m2)(XXH_RVOP(vle8_v_u8m2)(xsecret, vl*8));
5912 vuint64m2_t acc_vec = XXH_RVOP(vle64_v_u64m2)(xacc, vl);
5914 vuint64m2_t vsrl = XXH_RVOP(vsrl_vx_u64m2)(acc_vec, 47, vl);
5915 acc_vec = XXH_RVOP(vxor_vv_u64m2)(acc_vec, vsrl, vl);
5917 acc_vec = XXH_RVOP(vxor_vv_u64m2)(acc_vec, key_vec, vl);
5919 acc_vec = XXH_RVOP(vmul_vx_u64m2)(acc_vec, XXH_PRIME32_1, vl);
5921 XXH_RVOP(vse64_v_u64m2)(xacc, acc_vec, vl);
5927XXH_FORCE_INLINE
void
5928XXH3_initCustomSecret_rvv(
void* XXH_RESTRICT customSecret, xxh_u64 seed64)
5930 XXH_STATIC_ASSERT(XXH_SEC_ALIGN >= 8);
5931 XXH_ASSERT(((
size_t)customSecret & 7) == 0);
5932 (void)(&XXH_writeLE64);
5934 size_t count = XXH_SECRET_DEFAULT_SIZE/8;
5936 size_t VLMAX = XXH_RVOP(vsetvlmax_e64m2)();
5937 int64_t* cSecret = (int64_t*)customSecret;
5938 const int64_t* kSecret = (
const int64_t*)(
const void*)XXH3_kSecret;
5940#if __riscv_v_intrinsic >= 1000000
5942 vbool32_t mneg = XXH_RVCAST(u8m1_b32)(
5943 XXH_RVOP(vmv_v_x_u8m1)(0xaa, XXH_RVOP(vsetvlmax_e8m1)()));
5946 size_t vlmax = XXH_RVOP(vsetvlmax_e8m1)();
5947 vbool32_t mneg = XXH_RVOP(vmseq_vx_u8mf4_b32)(
5948 XXH_RVOP(vand_vx_u8mf4)(
5949 XXH_RVOP(vid_v_u8mf4)(vlmax), 1, vlmax), 1, vlmax);
5951 vint64m2_t seed = XXH_RVOP(vmv_v_x_i64m2)((int64_t)seed64, VLMAX);
5952 seed = XXH_RVOP(vneg_v_i64m2_mu)(mneg, seed, seed, VLMAX);
5954 for (;
count > 0;
count -= vl, cSecret += vl, kSecret += vl) {
5956 vl = XXH_RVOP(vsetvl_e64m2)(
count < VLMAX ?
count : VLMAX);
5958 vint64m2_t src = XXH_RVOP(vle64_v_i64m2)(kSecret, vl);
5959 vint64m2_t res = XXH_RVOP(vadd_vv_i64m2)(src, seed, vl);
5960 XXH_RVOP(vse64_v_i64m2)(cSecret, res, vl);
5970#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__))
5985XXH_FORCE_INLINE xxh_u64
5986XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc)
5990 __asm__(
"umaddl %x0, %w1, %w2, %x3" :
"=r" (ret) :
"r" (lhs),
"r" (rhs),
"r" (acc));
5994XXH_FORCE_INLINE xxh_u64
5995XXH_mult32to64_add64(xxh_u64 lhs, xxh_u64 rhs, xxh_u64 acc)
5997 return XXH_mult32to64((xxh_u32)lhs, (xxh_u32)rhs) + acc;
6008XXH_FORCE_INLINE
void
6009XXH3_scalarRound(
void* XXH_RESTRICT acc,
6010 void const* XXH_RESTRICT
input,
6011 void const* XXH_RESTRICT secret,
6014 xxh_u64* xacc = (xxh_u64*) acc;
6015 xxh_u8
const* xinput = (xxh_u8
const*)
input;
6016 xxh_u8
const* xsecret = (xxh_u8
const*) secret;
6017 XXH_ASSERT(lane < XXH_ACC_NB);
6018 XXH_ASSERT(((
size_t)acc & (XXH_ACC_ALIGN-1)) == 0);
6020 xxh_u64
const data_val = XXH_readLE64(xinput + lane * 8);
6021 xxh_u64
const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8);
6022 xacc[lane ^ 1] += data_val;
6023 xacc[lane] = XXH_mult32to64_add64(data_key , data_key >> 32, xacc[lane]);
6031XXH_FORCE_INLINE
void
6032XXH3_accumulate_512_scalar(
void* XXH_RESTRICT acc,
6033 const void* XXH_RESTRICT
input,
6034 const void* XXH_RESTRICT secret)
6038#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 8 \
6039 && (defined(__arm__) || defined(__thumb2__)) \
6040 && defined(__ARM_FEATURE_UNALIGNED) \
6041 && XXH_SIZE_OPT <= 0
6042# pragma GCC unroll 8
6044 for (i=0;
i < XXH_ACC_NB;
i++) {
6045 XXH3_scalarRound(acc,
input, secret, i);
6048XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(scalar)
6057XXH_FORCE_INLINE
void
6058XXH3_scalarScrambleRound(
void* XXH_RESTRICT acc,
6059 void const* XXH_RESTRICT secret,
6062 xxh_u64*
const xacc = (xxh_u64*) acc;
6063 const xxh_u8*
const xsecret = (
const xxh_u8*) secret;
6064 XXH_ASSERT((((
size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
6065 XXH_ASSERT(lane < XXH_ACC_NB);
6067 xxh_u64
const key64 = XXH_readLE64(xsecret + lane * 8);
6068 xxh_u64 acc64 = xacc[lane];
6069 acc64 = XXH_xorshift64(acc64, 47);
6071 acc64 *= XXH_PRIME32_1;
6080XXH_FORCE_INLINE
void
6081XXH3_scrambleAcc_scalar(
void* XXH_RESTRICT acc,
const void* XXH_RESTRICT secret)
6084 for (i=0;
i < XXH_ACC_NB;
i++) {
6085 XXH3_scalarScrambleRound(acc, secret, i);
6089XXH_FORCE_INLINE
void
6090XXH3_initCustomSecret_scalar(
void* XXH_RESTRICT customSecret, xxh_u64 seed64)
6097 const xxh_u8* kSecretPtr = XXH3_kSecret;
6098 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
6100#if defined(__GNUC__) && defined(__aarch64__)
6133 XXH_COMPILER_GUARD(kSecretPtr);
6135 {
int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16;
6137 for (i=0;
i < nbRounds;
i++) {
6144 xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64;
6145 xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64;
6146 XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo);
6147 XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi);
6152typedef void (*XXH3_f_accumulate)(xxh_u64* XXH_RESTRICT,
const xxh_u8* XXH_RESTRICT,
const xxh_u8* XXH_RESTRICT, size_t);
6153typedef void (*XXH3_f_scrambleAcc)(
void* XXH_RESTRICT,
const void*);
6154typedef void (*XXH3_f_initCustomSecret)(
void* XXH_RESTRICT, xxh_u64);
6157#if (XXH_VECTOR == XXH_AVX512)
6159#define XXH3_accumulate_512 XXH3_accumulate_512_avx512
6160#define XXH3_accumulate XXH3_accumulate_avx512
6161#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512
6162#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512
6164#elif (XXH_VECTOR == XXH_AVX2)
6166#define XXH3_accumulate_512 XXH3_accumulate_512_avx2
6167#define XXH3_accumulate XXH3_accumulate_avx2
6168#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2
6169#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2
6171#elif (XXH_VECTOR == XXH_SSE2)
6173#define XXH3_accumulate_512 XXH3_accumulate_512_sse2
6174#define XXH3_accumulate XXH3_accumulate_sse2
6175#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2
6176#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2
6178#elif (XXH_VECTOR == XXH_NEON)
6180#define XXH3_accumulate_512 XXH3_accumulate_512_neon
6181#define XXH3_accumulate XXH3_accumulate_neon
6182#define XXH3_scrambleAcc XXH3_scrambleAcc_neon
6183#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6185#elif (XXH_VECTOR == XXH_VSX)
6187#define XXH3_accumulate_512 XXH3_accumulate_512_vsx
6188#define XXH3_accumulate XXH3_accumulate_vsx
6189#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx
6190#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6192#elif (XXH_VECTOR == XXH_SVE)
6193#define XXH3_accumulate_512 XXH3_accumulate_512_sve
6194#define XXH3_accumulate XXH3_accumulate_sve
6195#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
6196#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6198#elif (XXH_VECTOR == XXH_LASX)
6199#define XXH3_accumulate_512 XXH3_accumulate_512_lasx
6200#define XXH3_accumulate XXH3_accumulate_lasx
6201#define XXH3_scrambleAcc XXH3_scrambleAcc_lasx
6202#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6204#elif (XXH_VECTOR == XXH_LSX)
6205#define XXH3_accumulate_512 XXH3_accumulate_512_lsx
6206#define XXH3_accumulate XXH3_accumulate_lsx
6207#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx
6208#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6210#elif (XXH_VECTOR == XXH_RVV)
6211#define XXH3_accumulate_512 XXH3_accumulate_512_rvv
6212#define XXH3_accumulate XXH3_accumulate_rvv
6213#define XXH3_scrambleAcc XXH3_scrambleAcc_rvv
6214#define XXH3_initCustomSecret XXH3_initCustomSecret_rvv
6218#define XXH3_accumulate_512 XXH3_accumulate_512_scalar
6219#define XXH3_accumulate XXH3_accumulate_scalar
6220#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
6221#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6225#if XXH_SIZE_OPT >= 1
6226# undef XXH3_initCustomSecret
6227# define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
6230XXH_FORCE_INLINE
void
6231XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc,
6232 const xxh_u8* XXH_RESTRICT
input,
size_t len,
6233 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
6234 XXH3_f_accumulate f_acc,
6235 XXH3_f_scrambleAcc f_scramble)
6237 size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE;
6238 size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock;
6239 size_t const nb_blocks = (len - 1) / block_len;
6245 for (n = 0;
n < nb_blocks;
n++) {
6246 f_acc(acc,
input + n*block_len, secret, nbStripesPerBlock);
6247 f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN);
6251 XXH_ASSERT(len > XXH_STRIPE_LEN);
6252 {
size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN;
6253 XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE));
6254 f_acc(acc,
input + nb_blocks*block_len, secret, nbStripes);
6257 {
const xxh_u8*
const p =
input + len - XXH_STRIPE_LEN;
6258#define XXH_SECRET_LASTACC_START 7
6259 XXH3_accumulate_512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START);
6263XXH_FORCE_INLINE xxh_u64
6264XXH3_mix2Accs(
const xxh_u64* XXH_RESTRICT acc,
const xxh_u8* XXH_RESTRICT secret)
6266 return XXH3_mul128_fold64(
6267 acc[0] ^ XXH_readLE64(secret),
6268 acc[1] ^ XXH_readLE64(secret+8) );
6272XXH3_mergeAccs(
const xxh_u64* XXH_RESTRICT acc,
const xxh_u8* XXH_RESTRICT secret, xxh_u64
start)
6274 xxh_u64 result64 =
start;
6277 for (i = 0;
i < 4;
i++) {
6278 result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i);
6279#if defined(__clang__) \
6280 && (defined(__arm__) || defined(__thumb__)) \
6281 && (defined(__ARM_NEON) || defined(__ARM_NEON__)) \
6282 && !defined(XXH_ENABLE_AUTOVECTORIZE)
6291 XXH_COMPILER_GUARD(result64);
6295 return XXH3_avalanche(result64);
6299#define XXH_SECRET_MERGEACCS_START 11
6302XXH3_finalizeLong_64b(
const xxh_u64* XXH_RESTRICT acc,
const xxh_u8* XXH_RESTRICT secret, xxh_u64 len)
6304 return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1);
6307#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
6308 XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
6311XXH3_hashLong_64b_internal(
const void* XXH_RESTRICT
input,
size_t len,
6312 const void* XXH_RESTRICT secret,
size_t secretSize,
6313 XXH3_f_accumulate f_acc,
6314 XXH3_f_scrambleAcc f_scramble)
6316 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
6318 XXH3_hashLong_internal_loop(acc, (
const xxh_u8*)
input, len, (
const xxh_u8*)secret, secretSize, f_acc, f_scramble);
6321 XXH_STATIC_ASSERT(
sizeof(acc) == 64);
6322 XXH_ASSERT(secretSize >=
sizeof(acc) + XXH_SECRET_MERGEACCS_START);
6323 return XXH3_finalizeLong_64b(acc, (
const xxh_u8*)secret, (xxh_u64)len);
6334XXH3_hashLong_64b_withSecret(
const void* XXH_RESTRICT
input,
size_t len,
6335 XXH64_hash_t seed64,
const xxh_u8* XXH_RESTRICT secret,
size_t secretLen)
6338 return XXH3_hashLong_64b_internal(
input, len, secret, secretLen, XXH3_accumulate, XXH3_scrambleAcc);
6348XXH3_hashLong_64b_default(
const void* XXH_RESTRICT
input,
size_t len,
6349 XXH64_hash_t seed64,
const xxh_u8* XXH_RESTRICT secret,
size_t secretLen)
6351 (void)seed64; (void)secret; (void)secretLen;
6352 return XXH3_hashLong_64b_internal(
input, len, XXH3_kSecret,
sizeof(XXH3_kSecret), XXH3_accumulate, XXH3_scrambleAcc);
6367XXH3_hashLong_64b_withSeed_internal(
const void*
input,
size_t len,
6369 XXH3_f_accumulate f_acc,
6370 XXH3_f_scrambleAcc f_scramble,
6371 XXH3_f_initCustomSecret f_initSec)
6373#if XXH_SIZE_OPT <= 0
6375 return XXH3_hashLong_64b_internal(
input, len,
6376 XXH3_kSecret,
sizeof(XXH3_kSecret),
6379 { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
6380 f_initSec(secret, seed);
6381 return XXH3_hashLong_64b_internal(
input, len, secret,
sizeof(secret),
6390XXH3_hashLong_64b_withSeed(
const void* XXH_RESTRICT
input,
size_t len,
6391 XXH64_hash_t seed,
const xxh_u8* XXH_RESTRICT secret,
size_t secretLen)
6393 (void)secret; (void)secretLen;
6394 return XXH3_hashLong_64b_withSeed_internal(
input, len, seed,
6395 XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret);
6399typedef XXH64_hash_t (*XXH3_hashLong64_f)(
const void* XXH_RESTRICT, size_t,
6403XXH3_64bits_internal(
const void* XXH_RESTRICT
input,
size_t len,
6404 XXH64_hash_t seed64,
const void* XXH_RESTRICT secret,
size_t secretLen,
6405 XXH3_hashLong64_f f_hashLong)
6416 return XXH3_len_0to16_64b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, seed64);
6418 return XXH3_len_17to128_64b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, secretLen, seed64);
6419 if (len <= XXH3_MIDSIZE_MAX)
6420 return XXH3_len_129to240_64b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, secretLen, seed64);
6421 return f_hashLong(
input, len, seed64, (
const xxh_u8*)secret, secretLen);
6430 return XXH3_64bits_internal(
input, length, 0, XXH3_kSecret,
sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
6437 return XXH3_64bits_internal(
input, length, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
6444 return XXH3_64bits_internal(
input, length, seed, XXH3_kSecret,
sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
6448XXH3_64bits_withSecretandSeed(XXH_NOESCAPE
const void*
input,
size_t length, XXH_NOESCAPE
const void* secret,
size_t secretSize,
XXH64_hash_t seed)
6450 if (length <= XXH3_MIDSIZE_MAX)
6451 return XXH3_64bits_internal(
input, length, seed, XXH3_kSecret,
sizeof(XXH3_kSecret), NULL);
6452 return XXH3_hashLong_64b_withSecret(
input, length, seed, (
const xxh_u8*)secret, secretSize);
6457#ifndef XXH_NO_STREAM
6481static XXH_MALLOCF void* XXH_alignedMalloc(
size_t s,
size_t align)
6483 XXH_ASSERT(align <= 128 && align >= 8);
6484 XXH_ASSERT((align & (align-1)) == 0);
6485 XXH_ASSERT(s != 0 && s < (s + align));
6487 xxh_u8* base = (xxh_u8*)XXH_malloc(s + align);
6495 size_t offset =
align - ((size_t)base & (
align - 1));
6497 xxh_u8* ptr = base + offset;
6499 XXH_ASSERT((
size_t)ptr % align == 0);
6502 ptr[-1] = (xxh_u8)offset;
6512static void XXH_alignedFree(
void* p)
6515 xxh_u8* ptr = (xxh_u8*)p;
6517 xxh_u8 offset = ptr[-1];
6519 xxh_u8* base = ptr - offset;
6537 if (state==NULL)
return NULL;
6538 XXH3_INITSTATE(state);
6556 XXH_alignedFree(statePtr);
6564 XXH_memcpy(dst_state, src_state,
sizeof(*dst_state));
6570 const void* secret,
size_t secretSize)
6572 size_t const initStart = offsetof(
XXH3_state_t, bufferedSize);
6573 size_t const initLength = offsetof(
XXH3_state_t, nbStripesPerBlock) - initStart;
6574 XXH_ASSERT(offsetof(
XXH3_state_t, nbStripesPerBlock) > initStart);
6575 XXH_ASSERT(statePtr != NULL);
6577 XXH_memset((
char*)statePtr + initStart, 0, initLength);
6578 statePtr->acc[0] = XXH_PRIME32_3;
6579 statePtr->acc[1] = XXH_PRIME64_1;
6580 statePtr->acc[2] = XXH_PRIME64_2;
6581 statePtr->acc[3] = XXH_PRIME64_3;
6582 statePtr->acc[4] = XXH_PRIME64_4;
6583 statePtr->acc[5] = XXH_PRIME32_2;
6584 statePtr->acc[6] = XXH_PRIME64_5;
6585 statePtr->acc[7] = XXH_PRIME32_1;
6586 statePtr->seed = seed;
6587 statePtr->useSeed = (seed != 0);
6588 statePtr->extSecret = (
const unsigned char*)secret;
6590 statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
6591 statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
6599 XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
6608 XXH3_reset_internal(statePtr, 0, secret, secretSize);
6620 if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
6621 XXH3_initCustomSecret(statePtr->customSecret, seed);
6622 XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
6628XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE
XXH3_state_t* statePtr, XXH_NOESCAPE
const void* secret,
size_t secretSize,
XXH64_hash_t seed64)
6633 XXH3_reset_internal(statePtr, seed64, secret, secretSize);
6634 statePtr->useSeed = 1;
6655XXH_FORCE_INLINE
const xxh_u8 *
6656XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
6657 size_t* XXH_RESTRICT nbStripesSoFarPtr,
size_t nbStripesPerBlock,
6658 const xxh_u8* XXH_RESTRICT
input,
size_t nbStripes,
6659 const xxh_u8* XXH_RESTRICT secret,
size_t secretLimit,
6660 XXH3_f_accumulate f_acc,
6661 XXH3_f_scrambleAcc f_scramble)
6663 const xxh_u8* initialSecret = secret + *nbStripesSoFarPtr * XXH_SECRET_CONSUME_RATE;
6665 if (nbStripes >= (nbStripesPerBlock - *nbStripesSoFarPtr)) {
6667 size_t nbStripesThisIter = nbStripesPerBlock - *nbStripesSoFarPtr;
6671 f_acc(acc,
input, initialSecret, nbStripesThisIter);
6672 f_scramble(acc, secret + secretLimit);
6673 input += nbStripesThisIter * XXH_STRIPE_LEN;
6674 nbStripes -= nbStripesThisIter;
6676 nbStripesThisIter = nbStripesPerBlock;
6677 initialSecret = secret;
6678 }
while (nbStripes >= nbStripesPerBlock);
6679 *nbStripesSoFarPtr = 0;
6682 if (nbStripes > 0) {
6683 f_acc(acc,
input, initialSecret, nbStripes);
6684 input += nbStripes * XXH_STRIPE_LEN;
6685 *nbStripesSoFarPtr += nbStripes;
6691#ifndef XXH3_STREAM_USE_STACK
6692# if XXH_SIZE_OPT <= 0 && !defined(__clang__)
6693# define XXH3_STREAM_USE_STACK 1
6702 const xxh_u8* XXH_RESTRICT
input,
size_t len,
6703 XXH3_f_accumulate f_acc,
6704 XXH3_f_scrambleAcc f_scramble)
6707 XXH_ASSERT(len == 0);
6711 XXH_ASSERT(state != NULL);
6712 state->totalLen += len;
6715 XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
6716 if (len <= XXH3_INTERNALBUFFER_SIZE - state->bufferedSize) {
6717 XXH_memcpy(state->buffer + state->bufferedSize,
input, len);
6718 state->bufferedSize += (XXH32_hash_t)len;
6722 {
const xxh_u8*
const bEnd =
input + len;
6723 const unsigned char*
const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
6724#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
6729 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8];
6730 XXH_memcpy(acc, state->acc,
sizeof(acc));
6732 xxh_u64* XXH_RESTRICT
const acc = state->acc;
6736 #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
6737 XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0);
6743 if (state->bufferedSize) {
6744 size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
6745 XXH_memcpy(state->buffer + state->bufferedSize,
input, loadSize);
6747 XXH3_consumeStripes(acc,
6748 &state->nbStripesSoFar, state->nbStripesPerBlock,
6749 state->buffer, XXH3_INTERNALBUFFER_STRIPES,
6750 secret, state->secretLimit,
6752 state->bufferedSize = 0;
6754 XXH_ASSERT(
input < bEnd);
6755 if (bEnd -
input > XXH3_INTERNALBUFFER_SIZE) {
6756 size_t nbStripes = (size_t)(bEnd - 1 -
input) / XXH_STRIPE_LEN;
6757 input = XXH3_consumeStripes(acc,
6758 &state->nbStripesSoFar, state->nbStripesPerBlock,
6760 secret, state->secretLimit,
6762 XXH_memcpy(state->buffer +
sizeof(state->buffer) - XXH_STRIPE_LEN,
input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
6766 XXH_ASSERT(
input < bEnd);
6767 XXH_ASSERT(bEnd -
input <= XXH3_INTERNALBUFFER_SIZE);
6768 XXH_ASSERT(state->bufferedSize == 0);
6769 XXH_memcpy(state->buffer,
input, (
size_t)(bEnd-
input));
6770 state->bufferedSize = (XXH32_hash_t)(bEnd-
input);
6771#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
6773 XXH_memcpy(state->acc, acc,
sizeof(acc));
6784XXH3_update_regular(XXH_NOESCAPE
XXH3_state_t* state, XXH_NOESCAPE
const void*
input,
size_t len)
6786 return XXH3_update(state, (
const xxh_u8*)
input, len,
6787 XXH3_accumulate, XXH3_scrambleAcc);
6794 return XXH3_update_regular(state,
input, len);
6798XXH_FORCE_INLINE
void
6801 const unsigned char* secret)
6803 xxh_u8 lastStripe[XXH_STRIPE_LEN];
6804 const xxh_u8* lastStripePtr;
6810 XXH_memcpy(acc, state->acc,
sizeof(state->acc));
6811 if (state->bufferedSize >= XXH_STRIPE_LEN) {
6813 size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
6814 size_t nbStripesSoFar = state->nbStripesSoFar;
6815 XXH3_consumeStripes(acc,
6816 &nbStripesSoFar, state->nbStripesPerBlock,
6817 state->buffer, nbStripes,
6818 secret, state->secretLimit,
6819 XXH3_accumulate, XXH3_scrambleAcc);
6820 lastStripePtr = state->buffer + state->bufferedSize - XXH_STRIPE_LEN;
6823 size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
6824 XXH_ASSERT(state->bufferedSize > 0);
6825 XXH_memcpy(lastStripe, state->buffer +
sizeof(state->buffer) - catchupSize, catchupSize);
6826 XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
6827 lastStripePtr = lastStripe;
6830 XXH3_accumulate_512(acc,
6832 secret + state->secretLimit - XXH_SECRET_LASTACC_START);
6838 const unsigned char*
const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
6839 if (state->totalLen > XXH3_MIDSIZE_MAX) {
6841 XXH3_digest_long(acc, state, secret);
6842 return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen);
6848 secret, state->secretLimit + XXH_STRIPE_LEN);
6871XXH3_len_1to3_128b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
6874 XXH_ASSERT(
input != NULL);
6875 XXH_ASSERT(1 <= len && len <= 3);
6876 XXH_ASSERT(secret != NULL);
6882 { xxh_u8
const c1 =
input[0];
6883 xxh_u8
const c2 =
input[len >> 1];
6884 xxh_u8
const c3 =
input[len - 1];
6885 xxh_u32
const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24)
6886 | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
6887 xxh_u32
const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13);
6888 xxh_u64
const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
6889 xxh_u64
const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed;
6890 xxh_u64
const keyed_lo = (xxh_u64)combinedl ^ bitflipl;
6891 xxh_u64
const keyed_hi = (xxh_u64)combinedh ^ bitfliph;
6893 h128.
low64 = XXH64_avalanche(keyed_lo);
6894 h128.
high64 = XXH64_avalanche(keyed_hi);
6900XXH3_len_4to8_128b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
6902 XXH_ASSERT(
input != NULL);
6903 XXH_ASSERT(secret != NULL);
6904 XXH_ASSERT(4 <= len && len <= 8);
6905 seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
6906 { xxh_u32
const input_lo = XXH_readLE32(
input);
6907 xxh_u32
const input_hi = XXH_readLE32(
input + len - 4);
6908 xxh_u64
const input_64 = input_lo + ((xxh_u64)input_hi << 32);
6909 xxh_u64
const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed;
6910 xxh_u64
const keyed = input_64 ^ bitflip;
6913 XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2));
6919 m128.
low64 *= PRIME_MX2;
6927XXH3_len_9to16_128b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
6929 XXH_ASSERT(
input != NULL);
6930 XXH_ASSERT(secret != NULL);
6931 XXH_ASSERT(9 <= len && len <= 16);
6932 { xxh_u64
const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed;
6933 xxh_u64
const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed;
6934 xxh_u64
const input_lo = XXH_readLE64(
input);
6935 xxh_u64 input_hi = XXH_readLE64(
input + len - 8);
6936 XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1);
6941 m128.
low64 += (xxh_u64)(len - 1) << 54;
6942 input_hi ^= bitfliph;
6950 if (
sizeof(
void *) <
sizeof(xxh_u64)) {
6957 m128.
high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2);
6983 m128.
high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1);
7002XXH3_len_0to16_128b(
const xxh_u8*
input,
size_t len,
const xxh_u8* secret,
XXH64_hash_t seed)
7004 XXH_ASSERT(len <= 16);
7005 {
if (len > 8)
return XXH3_len_9to16_128b(
input, len, secret, seed);
7006 if (len >= 4)
return XXH3_len_4to8_128b(
input, len, secret, seed);
7007 if (len)
return XXH3_len_1to3_128b(
input, len, secret, seed);
7009 xxh_u64
const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72);
7010 xxh_u64
const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88);
7011 h128.
low64 = XXH64_avalanche(seed ^ bitflipl);
7012 h128.
high64 = XXH64_avalanche( seed ^ bitfliph);
7021XXH128_mix32B(
XXH128_hash_t acc,
const xxh_u8* input_1,
const xxh_u8* input_2,
7024 acc.
low64 += XXH3_mix16B (input_1, secret+0, seed);
7025 acc.
low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8);
7026 acc.
high64 += XXH3_mix16B (input_2, secret+16, seed);
7027 acc.
high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8);
7033XXH3_len_17to128_128b(
const xxh_u8* XXH_RESTRICT
input,
size_t len,
7034 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
7038 XXH_ASSERT(16 < len && len <= 128);
7041 acc.
low64 = len * XXH_PRIME64_1;
7044#if XXH_SIZE_OPT >= 1
7047 unsigned int i = (
unsigned int)(len - 1) / 32;
7049 acc = XXH128_mix32B(acc,
input+16*i,
input+len-16*(i+1), secret+32*i, seed);
7056 acc = XXH128_mix32B(acc,
input+48,
input+len-64, secret+96, seed);
7058 acc = XXH128_mix32B(acc,
input+32,
input+len-48, secret+64, seed);
7060 acc = XXH128_mix32B(acc,
input+16,
input+len-32, secret+32, seed);
7062 acc = XXH128_mix32B(acc,
input,
input+len-16, secret, seed);
7067 + (acc.
high64 * XXH_PRIME64_4)
7068 + ((len - seed) * XXH_PRIME64_2);
7077XXH3_len_129to240_128b(
const xxh_u8* XXH_RESTRICT
input,
size_t len,
7078 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
7082 XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
7086 acc.
low64 = len * XXH_PRIME64_1;
7094 for (i = 32;
i < 160;
i += 32) {
7095 acc = XXH128_mix32B(acc,
7108 for (i=160;
i <= len;
i += 32) {
7109 acc = XXH128_mix32B(acc,
7112 secret + XXH3_MIDSIZE_STARTOFFSET + i - 160,
7116 acc = XXH128_mix32B(acc,
7125 + (acc.
high64 * XXH_PRIME64_4)
7126 + ((len - seed) * XXH_PRIME64_2);
7135XXH3_finalizeLong_128b(
const xxh_u64* XXH_RESTRICT acc,
const xxh_u8* XXH_RESTRICT secret,
size_t secretSize, xxh_u64 len)
7138 h128.
low64 = XXH3_finalizeLong_64b(acc, secret, len);
7139 h128.
high64 = XXH3_mergeAccs(acc, secret + secretSize
7140 - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START,
7141 ~(len * XXH_PRIME64_2));
7146XXH3_hashLong_128b_internal(
const void* XXH_RESTRICT
input,
size_t len,
7147 const xxh_u8* XXH_RESTRICT secret,
size_t secretSize,
7148 XXH3_f_accumulate f_acc,
7149 XXH3_f_scrambleAcc f_scramble)
7151 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
7153 XXH3_hashLong_internal_loop(acc, (
const xxh_u8*)
input, len, secret, secretSize, f_acc, f_scramble);
7156 XXH_STATIC_ASSERT(
sizeof(acc) == 64);
7157 XXH_ASSERT(secretSize >=
sizeof(acc) + XXH_SECRET_MERGEACCS_START);
7158 return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len);
7165XXH3_hashLong_128b_default(
const void* XXH_RESTRICT
input,
size_t len,
7167 const void* XXH_RESTRICT secret,
size_t secretLen)
7169 (void)seed64; (void)secret; (void)secretLen;
7170 return XXH3_hashLong_128b_internal(
input, len, XXH3_kSecret,
sizeof(XXH3_kSecret),
7171 XXH3_accumulate, XXH3_scrambleAcc);
7182XXH3_hashLong_128b_withSecret(
const void* XXH_RESTRICT
input,
size_t len,
7184 const void* XXH_RESTRICT secret,
size_t secretLen)
7187 return XXH3_hashLong_128b_internal(
input, len, (
const xxh_u8*)secret, secretLen,
7188 XXH3_accumulate, XXH3_scrambleAcc);
7192XXH3_hashLong_128b_withSeed_internal(
const void* XXH_RESTRICT
input,
size_t len,
7194 XXH3_f_accumulate f_acc,
7195 XXH3_f_scrambleAcc f_scramble,
7196 XXH3_f_initCustomSecret f_initSec)
7199 return XXH3_hashLong_128b_internal(
input, len,
7200 XXH3_kSecret,
sizeof(XXH3_kSecret),
7202 { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
7203 f_initSec(secret, seed64);
7204 return XXH3_hashLong_128b_internal(
input, len, (
const xxh_u8*)secret,
sizeof(secret),
7213XXH3_hashLong_128b_withSeed(
const void*
input,
size_t len,
7214 XXH64_hash_t seed64,
const void* XXH_RESTRICT secret,
size_t secretLen)
7216 (void)secret; (void)secretLen;
7217 return XXH3_hashLong_128b_withSeed_internal(
input, len, seed64,
7218 XXH3_accumulate, XXH3_scrambleAcc, XXH3_initCustomSecret);
7221typedef XXH128_hash_t (*XXH3_hashLong128_f)(
const void* XXH_RESTRICT, size_t,
7225XXH3_128bits_internal(
const void*
input,
size_t len,
7226 XXH64_hash_t seed64,
const void* XXH_RESTRICT secret,
size_t secretLen,
7227 XXH3_hashLong128_f f_hl128)
7237 return XXH3_len_0to16_128b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, seed64);
7239 return XXH3_len_17to128_128b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, secretLen, seed64);
7240 if (len <= XXH3_MIDSIZE_MAX)
7241 return XXH3_len_129to240_128b((
const xxh_u8*)
input, len, (
const xxh_u8*)secret, secretLen, seed64);
7242 return f_hl128(
input, len, seed64, secret, secretLen);
7251 return XXH3_128bits_internal(
input, len, 0,
7252 XXH3_kSecret,
sizeof(XXH3_kSecret),
7253 XXH3_hashLong_128b_default);
7260 return XXH3_128bits_internal(
input, len, 0,
7261 (
const xxh_u8*)secret, secretSize,
7262 XXH3_hashLong_128b_withSecret);
7269 return XXH3_128bits_internal(
input, len, seed,
7270 XXH3_kSecret,
sizeof(XXH3_kSecret),
7271 XXH3_hashLong_128b_withSeed);
7276XXH3_128bits_withSecretandSeed(XXH_NOESCAPE
const void*
input,
size_t len, XXH_NOESCAPE
const void* secret,
size_t secretSize,
XXH64_hash_t seed)
7278 if (len <= XXH3_MIDSIZE_MAX)
7279 return XXH3_128bits_internal(
input, len, seed, XXH3_kSecret,
sizeof(XXH3_kSecret), NULL);
7280 return XXH3_hashLong_128b_withSecret(
input, len, seed, secret, secretSize);
7292#ifndef XXH_NO_STREAM
7321XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE
XXH3_state_t* statePtr, XXH_NOESCAPE
const void* secret,
size_t secretSize,
XXH64_hash_t seed)
7323 return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
7330 return XXH3_update_regular(state,
input, len);
7336 const unsigned char*
const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
7337 if (state->totalLen > XXH3_MIDSIZE_MAX) {
7339 XXH3_digest_long(acc, state, secret);
7340 XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >=
sizeof(acc) + XXH_SECRET_MERGEACCS_START);
7341 return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen);
7347 secret, state->secretLimit + XXH_STRIPE_LEN);
7357 return !(XXH_memcmp(&h1, &h2,
sizeof(h1)));
7371 if (hcmp)
return hcmp;
7382 if (XXH_CPU_LITTLE_ENDIAN) {
7387 XXH_memcpy((
char*)dst +
sizeof(hash.
high64), &hash.
low64,
sizeof(hash.
low64));
7395 h.high64 = XXH_readBE64(src);
7396 h.low64 = XXH_readBE64(src->digest + 8);
7406#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
7408XXH_FORCE_INLINE
void XXH3_combine16(
void* dst,
XXH128_hash_t h128)
7410 XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.
low64 );
7411 XXH_writeLE64( (
char*)dst+8, XXH_readLE64((
char*)dst+8) ^ h128.
high64 );
7416XXH3_generateSecret(XXH_NOESCAPE
void* secretBuffer,
size_t secretSize, XXH_NOESCAPE
const void* customSeed,
size_t customSeedSize)
7418#if (XXH_DEBUGLEVEL >= 1)
7419 XXH_ASSERT(secretBuffer != NULL);
7423 if (secretBuffer == NULL)
return XXH_ERROR;
7427 if (customSeedSize == 0) {
7428 customSeed = XXH3_kSecret;
7429 customSeedSize = XXH_SECRET_DEFAULT_SIZE;
7431#if (XXH_DEBUGLEVEL >= 1)
7432 XXH_ASSERT(customSeed != NULL);
7434 if (customSeed == NULL)
return XXH_ERROR;
7439 while (pos < secretSize) {
7440 size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
7441 XXH_memcpy((
char*)secretBuffer + pos, customSeed, toCopy);
7445 {
size_t const nbSeg16 = secretSize / 16;
7449 for (n=0;
n<nbSeg16;
n++) {
7450 XXH128_hash_t const h128 = XXH128(&scrambler,
sizeof(scrambler), n);
7451 XXH3_combine16((
char*)secretBuffer + n*16, h128);
7461XXH3_generateSecret_fromSeed(XXH_NOESCAPE
void* secretBuffer,
XXH64_hash_t seed)
7463 XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
7464 XXH3_initCustomSecret(secret, seed);
7465 XXH_ASSERT(secretBuffer != NULL);
7466 XXH_memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
7472#if XXH_VECTOR == XXH_AVX2 \
7473 && defined(__GNUC__) && !defined(__clang__) \
7474 && defined(__OPTIMIZE__) && XXH_SIZE_OPT <= 0
7475# pragma GCC pop_options
7488#if defined (__cplusplus) && !defined(XXH_NO_EXTERNC_GUARD)
struct XXH32_state_s XXH32_state_t
The opaque state struct for the XXH32 streaming API.
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest(const XXH32_state_t *statePtr)
Returns the calculated hash value from an XXH32_state_t.
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32(const void *input, size_t length, XXH32_hash_t seed)
Calculates the 32-bit hash of input using xxHash32.
XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, XXH32_hash_t seed)
Resets an XXH32_state_t to begin a new hash.
XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dst_state, const XXH32_state_t *src_state)
Copies one XXH32_state_t to another.
XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr)
Frees an XXH32_state_t.
XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *statePtr, const void *input, size_t length)
Consumes a block of input to an XXH32_state_t.
XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t * XXH32_createState(void)
Allocates an XXH32_state_t.
XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash)
Converts an XXH32_hash_t to a big endian XXH32_canonical_t.
XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src)
Converts an XXH32_canonical_t to a native XXH32_hash_t.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void *input, size_t length, XXH64_hash_t seed)
Calculates 64-bit seeded variant of XXH3 hash of input.
XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t *dst, XXH128_hash_t hash)
Converts an XXH128_hash_t to a big endian XXH128_canonical_t.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t *src)
Converts an XXH128_canonical_t to a native XXH128_hash_t.
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update(XXH_NOESCAPE XXH3_state_t *statePtr, XXH_NOESCAPE const void *input, size_t length)
Consumes a block of input to an XXH3_state_t.
XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t * XXH3_createState(void)
XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void *h128_1, XXH_NOESCAPE const void *h128_2)
Compares two XXH128_hash_t.
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t *statePtr)
Resets an XXH3_state_t to begin a new hash.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest(XXH_NOESCAPE const XXH3_state_t *statePtr)
Returns the calculated XXH3 128-bit hash value from an XXH3_state_t.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest(XXH_NOESCAPE const XXH3_state_t *statePtr)
Returns the calculated XXH3 64-bit hash value from an XXH3_state_t.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void *data, size_t len, XXH_NOESCAPE const void *secret, size_t secretSize)
Calculates 128-bit variant of XXH3 with a custom "secret".
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t *statePtr)
Resets an XXH3_state_t to begin a new hash.
XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
Check equality of two XXH128_hash_t values.
struct XXH3_state_s XXH3_state_t
The opaque state struct for the XXH3 streaming API.
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t *statePtr, XXH64_hash_t seed)
Resets an XXH3_state_t with 64-bit seed to begin a new hash.
XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t *statePtr)
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void *data, size_t len)
Calculates 128-bit unseeded variant of XXH3 of data.
XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t *statePtr, XXH_NOESCAPE const void *secret, size_t secretSize)
Resets an XXH3_state_t with secret data to begin a new hash.
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t *statePtr, XXH_NOESCAPE const void *secret, size_t secretSize)
Resets an XXH3_state_t with secret data to begin a new hash.
XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void *data, size_t len, XXH64_hash_t seed)
Calculates 128-bit seeded variant of XXH3 hash of data.
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t *statePtr, XXH64_hash_t seed)
Resets an XXH3_state_t with 64-bit seed to begin a new hash.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void *data, size_t len, XXH_NOESCAPE const void *secret, size_t secretSize)
Calculates 64-bit variant of XXH3 with a custom "secret".
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void *input, size_t length)
Calculates 64-bit unseeded variant of XXH3 hash of input.
XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t *dst_state, XXH_NOESCAPE const XXH3_state_t *src_state)
Copies one XXH3_state_t to another.
XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update(XXH_NOESCAPE XXH3_state_t *statePtr, XXH_NOESCAPE const void *input, size_t length)
Consumes a block of input to an XXH3_state_t.
#define XXH3_SECRET_SIZE_MIN
struct XXH64_state_s XXH64_state_t
The opaque state struct for the XXH64 streaming API.
XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t *statePtr, XXH64_hash_t seed)
Resets an XXH64_state_t to begin a new hash.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void *input, size_t length, XXH64_hash_t seed)
Calculates the 64-bit hash of input using xxHash64.
XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t *dst, XXH64_hash_t hash)
Converts an XXH64_hash_t to a big endian XXH64_canonical_t.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t *src)
Converts an XXH64_canonical_t to a native XXH64_hash_t.
XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t *dst_state, const XXH64_state_t *src_state)
Copies one XXH64_state_t to another.
XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH_NOESCAPE XXH64_state_t *statePtr, XXH_NOESCAPE const void *input, size_t length)
Consumes a block of input to an XXH64_state_t.
XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t *statePtr)
Returns the calculated hash value from an XXH64_state_t.
XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t * XXH64_createState(void)
Allocates an XXH64_state_t.
XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr)
Frees an XXH64_state_t.
unsigned long long XXH64_hash_t
XXH_errorcode
Exit code for the streaming API.
#define XXH_PUBLIC_API
Marks a global symbol.
#define XXH_VERSION_NUMBER
Version number, encoded as two digits each.
XXH_PUBLIC_API XXH_CONSTF unsigned XXH_versionNumber(void)
Obtains the xxHash version.
@ mask
Hard alpha cutoff; casts cutout shadows.
std::vector< math::vec3 > start
The return value from 128-bit hashes.
Canonical (big endian) representation of XXH32_hash_t.
Canonical (big endian) representation of XXH64_hash_t.