1*cc02d7e2SAndroid Build Coastguard Worker /*
2*cc02d7e2SAndroid Build Coastguard Worker * xxHash - Extremely Fast Hash algorithm
3*cc02d7e2SAndroid Build Coastguard Worker * Header File
4*cc02d7e2SAndroid Build Coastguard Worker * Copyright (C) 2012-2020 Yann Collet
5*cc02d7e2SAndroid Build Coastguard Worker *
6*cc02d7e2SAndroid Build Coastguard Worker * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
7*cc02d7e2SAndroid Build Coastguard Worker *
8*cc02d7e2SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
9*cc02d7e2SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are
10*cc02d7e2SAndroid Build Coastguard Worker * met:
11*cc02d7e2SAndroid Build Coastguard Worker *
12*cc02d7e2SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
13*cc02d7e2SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
14*cc02d7e2SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above
15*cc02d7e2SAndroid Build Coastguard Worker * copyright notice, this list of conditions and the following disclaimer
16*cc02d7e2SAndroid Build Coastguard Worker * in the documentation and/or other materials provided with the
17*cc02d7e2SAndroid Build Coastguard Worker * distribution.
18*cc02d7e2SAndroid Build Coastguard Worker *
19*cc02d7e2SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*cc02d7e2SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*cc02d7e2SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*cc02d7e2SAndroid Build Coastguard Worker * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*cc02d7e2SAndroid Build Coastguard Worker * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*cc02d7e2SAndroid Build Coastguard Worker * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*cc02d7e2SAndroid Build Coastguard Worker * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*cc02d7e2SAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*cc02d7e2SAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*cc02d7e2SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*cc02d7e2SAndroid Build Coastguard Worker * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*cc02d7e2SAndroid Build Coastguard Worker *
31*cc02d7e2SAndroid Build Coastguard Worker * You can contact the author at:
32*cc02d7e2SAndroid Build Coastguard Worker * - xxHash homepage: https://www.xxhash.com
33*cc02d7e2SAndroid Build Coastguard Worker * - xxHash source repository: https://github.com/Cyan4973/xxHash
34*cc02d7e2SAndroid Build Coastguard Worker */
35*cc02d7e2SAndroid Build Coastguard Worker /*!
36*cc02d7e2SAndroid Build Coastguard Worker * @mainpage xxHash
37*cc02d7e2SAndroid Build Coastguard Worker *
38*cc02d7e2SAndroid Build Coastguard Worker * @file xxhash.h
39*cc02d7e2SAndroid Build Coastguard Worker * xxHash prototypes and implementation
40*cc02d7e2SAndroid Build Coastguard Worker */
41*cc02d7e2SAndroid Build Coastguard Worker /* TODO: update */
42*cc02d7e2SAndroid Build Coastguard Worker /* Notice extracted from xxHash homepage:
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard Worker xxHash is an extremely fast hash algorithm, running at RAM speed limits.
45*cc02d7e2SAndroid Build Coastguard Worker It also successfully passes all tests from the SMHasher suite.
46*cc02d7e2SAndroid Build Coastguard Worker
47*cc02d7e2SAndroid Build Coastguard Worker Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
48*cc02d7e2SAndroid Build Coastguard Worker
49*cc02d7e2SAndroid Build Coastguard Worker Name Speed Q.Score Author
50*cc02d7e2SAndroid Build Coastguard Worker xxHash 5.4 GB/s 10
51*cc02d7e2SAndroid Build Coastguard Worker CrapWow 3.2 GB/s 2 Andrew
52*cc02d7e2SAndroid Build Coastguard Worker MurmurHash 3a 2.7 GB/s 10 Austin Appleby
53*cc02d7e2SAndroid Build Coastguard Worker SpookyHash 2.0 GB/s 10 Bob Jenkins
54*cc02d7e2SAndroid Build Coastguard Worker SBox 1.4 GB/s 9 Bret Mulvey
55*cc02d7e2SAndroid Build Coastguard Worker Lookup3 1.2 GB/s 9 Bob Jenkins
56*cc02d7e2SAndroid Build Coastguard Worker SuperFastHash 1.2 GB/s 1 Paul Hsieh
57*cc02d7e2SAndroid Build Coastguard Worker CityHash64 1.05 GB/s 10 Pike & Alakuijala
58*cc02d7e2SAndroid Build Coastguard Worker FNV 0.55 GB/s 5 Fowler, Noll, Vo
59*cc02d7e2SAndroid Build Coastguard Worker CRC32 0.43 GB/s 9
60*cc02d7e2SAndroid Build Coastguard Worker MD5-32 0.33 GB/s 10 Ronald L. Rivest
61*cc02d7e2SAndroid Build Coastguard Worker SHA1-32 0.28 GB/s 10
62*cc02d7e2SAndroid Build Coastguard Worker
63*cc02d7e2SAndroid Build Coastguard Worker Q.Score is a measure of quality of the hash function.
64*cc02d7e2SAndroid Build Coastguard Worker It depends on successfully passing SMHasher test set.
65*cc02d7e2SAndroid Build Coastguard Worker 10 is a perfect score.
66*cc02d7e2SAndroid Build Coastguard Worker
67*cc02d7e2SAndroid Build Coastguard Worker Note: SMHasher's CRC32 implementation is not the fastest one.
68*cc02d7e2SAndroid Build Coastguard Worker Other speed-oriented implementations can be faster,
69*cc02d7e2SAndroid Build Coastguard Worker especially in combination with PCLMUL instruction:
70*cc02d7e2SAndroid Build Coastguard Worker https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735
71*cc02d7e2SAndroid Build Coastguard Worker
72*cc02d7e2SAndroid Build Coastguard Worker A 64-bit version, named XXH64, is available since r35.
73*cc02d7e2SAndroid Build Coastguard Worker It offers much better speed, but for 64-bit applications only.
74*cc02d7e2SAndroid Build Coastguard Worker Name Speed on 64 bits Speed on 32 bits
75*cc02d7e2SAndroid Build Coastguard Worker XXH64 13.8 GB/s 1.9 GB/s
76*cc02d7e2SAndroid Build Coastguard Worker XXH32 6.8 GB/s 6.0 GB/s
77*cc02d7e2SAndroid Build Coastguard Worker */
78*cc02d7e2SAndroid Build Coastguard Worker
79*cc02d7e2SAndroid Build Coastguard Worker #if defined (__cplusplus)
80*cc02d7e2SAndroid Build Coastguard Worker extern "C" {
81*cc02d7e2SAndroid Build Coastguard Worker #endif
82*cc02d7e2SAndroid Build Coastguard Worker
83*cc02d7e2SAndroid Build Coastguard Worker /* ****************************
84*cc02d7e2SAndroid Build Coastguard Worker * INLINE mode
85*cc02d7e2SAndroid Build Coastguard Worker ******************************/
86*cc02d7e2SAndroid Build Coastguard Worker /*!
87*cc02d7e2SAndroid Build Coastguard Worker * XXH_INLINE_ALL (and XXH_PRIVATE_API)
88*cc02d7e2SAndroid Build Coastguard Worker * Use these build macros to inline xxhash into the target unit.
89*cc02d7e2SAndroid Build Coastguard Worker * Inlining improves performance on small inputs, especially when the length is
90*cc02d7e2SAndroid Build Coastguard Worker * expressed as a compile-time constant:
91*cc02d7e2SAndroid Build Coastguard Worker *
92*cc02d7e2SAndroid Build Coastguard Worker * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html
93*cc02d7e2SAndroid Build Coastguard Worker *
94*cc02d7e2SAndroid Build Coastguard Worker * It also keeps xxHash symbols private to the unit, so they are not exported.
95*cc02d7e2SAndroid Build Coastguard Worker *
96*cc02d7e2SAndroid Build Coastguard Worker * Usage:
97*cc02d7e2SAndroid Build Coastguard Worker * #define XXH_INLINE_ALL
98*cc02d7e2SAndroid Build Coastguard Worker * #include "xxhash.h"
99*cc02d7e2SAndroid Build Coastguard Worker *
100*cc02d7e2SAndroid Build Coastguard Worker * Do not compile and link xxhash.o as a separate object, as it is not useful.
101*cc02d7e2SAndroid Build Coastguard Worker */
102*cc02d7e2SAndroid Build Coastguard Worker #if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
103*cc02d7e2SAndroid Build Coastguard Worker && !defined(XXH_INLINE_ALL_31684351384)
104*cc02d7e2SAndroid Build Coastguard Worker /* this section should be traversed only once */
105*cc02d7e2SAndroid Build Coastguard Worker # define XXH_INLINE_ALL_31684351384
106*cc02d7e2SAndroid Build Coastguard Worker /* give access to the advanced API, required to compile implementations */
107*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */
108*cc02d7e2SAndroid Build Coastguard Worker # define XXH_STATIC_LINKING_ONLY
109*cc02d7e2SAndroid Build Coastguard Worker /* make all functions private */
110*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PUBLIC_API
111*cc02d7e2SAndroid Build Coastguard Worker # if defined(__GNUC__)
112*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API static __inline __attribute__((unused))
113*cc02d7e2SAndroid Build Coastguard Worker # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
114*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API static inline
115*cc02d7e2SAndroid Build Coastguard Worker # elif defined(_MSC_VER)
116*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API static __inline
117*cc02d7e2SAndroid Build Coastguard Worker # else
118*cc02d7e2SAndroid Build Coastguard Worker /* note: this version may generate warnings for unused static functions */
119*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API static
120*cc02d7e2SAndroid Build Coastguard Worker # endif
121*cc02d7e2SAndroid Build Coastguard Worker
122*cc02d7e2SAndroid Build Coastguard Worker /*
123*cc02d7e2SAndroid Build Coastguard Worker * This part deals with the special case where a unit wants to inline xxHash,
124*cc02d7e2SAndroid Build Coastguard Worker * but "xxhash.h" has previously been included without XXH_INLINE_ALL,
125*cc02d7e2SAndroid Build Coastguard Worker * such as part of some previously included *.h header file.
126*cc02d7e2SAndroid Build Coastguard Worker * Without further action, the new include would just be ignored,
127*cc02d7e2SAndroid Build Coastguard Worker * and functions would effectively _not_ be inlined (silent failure).
128*cc02d7e2SAndroid Build Coastguard Worker * The following macros solve this situation by prefixing all inlined names,
129*cc02d7e2SAndroid Build Coastguard Worker * avoiding naming collision with previous inclusions.
130*cc02d7e2SAndroid Build Coastguard Worker */
131*cc02d7e2SAndroid Build Coastguard Worker /* Before that, we unconditionally #undef all symbols,
132*cc02d7e2SAndroid Build Coastguard Worker * in case they were already defined with XXH_NAMESPACE.
133*cc02d7e2SAndroid Build Coastguard Worker * They will then be redefined for XXH_INLINE_ALL
134*cc02d7e2SAndroid Build Coastguard Worker */
135*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_versionNumber
136*cc02d7e2SAndroid Build Coastguard Worker /* XXH32 */
137*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32
138*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_createState
139*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_freeState
140*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_reset
141*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_update
142*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_digest
143*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_copyState
144*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_canonicalFromHash
145*cc02d7e2SAndroid Build Coastguard Worker # undef XXH32_hashFromCanonical
146*cc02d7e2SAndroid Build Coastguard Worker /* XXH64 */
147*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64
148*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_createState
149*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_freeState
150*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_reset
151*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_update
152*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_digest
153*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_copyState
154*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_canonicalFromHash
155*cc02d7e2SAndroid Build Coastguard Worker # undef XXH64_hashFromCanonical
156*cc02d7e2SAndroid Build Coastguard Worker /* XXH3_64bits */
157*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits
158*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_withSecret
159*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_withSeed
160*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_withSecretandSeed
161*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_createState
162*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_freeState
163*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_copyState
164*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_reset
165*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_reset_withSeed
166*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_reset_withSecret
167*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_update
168*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_64bits_digest
169*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_generateSecret
170*cc02d7e2SAndroid Build Coastguard Worker /* XXH3_128bits */
171*cc02d7e2SAndroid Build Coastguard Worker # undef XXH128
172*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits
173*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_withSeed
174*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_withSecret
175*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_reset
176*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_reset_withSeed
177*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_reset_withSecret
178*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_reset_withSecretandSeed
179*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_update
180*cc02d7e2SAndroid Build Coastguard Worker # undef XXH3_128bits_digest
181*cc02d7e2SAndroid Build Coastguard Worker # undef XXH128_isEqual
182*cc02d7e2SAndroid Build Coastguard Worker # undef XXH128_cmp
183*cc02d7e2SAndroid Build Coastguard Worker # undef XXH128_canonicalFromHash
184*cc02d7e2SAndroid Build Coastguard Worker # undef XXH128_hashFromCanonical
185*cc02d7e2SAndroid Build Coastguard Worker /* Finally, free the namespace itself */
186*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_NAMESPACE
187*cc02d7e2SAndroid Build Coastguard Worker
188*cc02d7e2SAndroid Build Coastguard Worker /* employ the namespace for XXH_INLINE_ALL */
189*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NAMESPACE XXH_INLINE_
190*cc02d7e2SAndroid Build Coastguard Worker /*
191*cc02d7e2SAndroid Build Coastguard Worker * Some identifiers (enums, type names) are not symbols,
192*cc02d7e2SAndroid Build Coastguard Worker * but they must nonetheless be renamed to avoid redeclaration.
193*cc02d7e2SAndroid Build Coastguard Worker * Alternative solution: do not redeclare them.
194*cc02d7e2SAndroid Build Coastguard Worker * However, this requires some #ifdefs, and has a more dispersed impact.
195*cc02d7e2SAndroid Build Coastguard Worker * Meanwhile, renaming can be achieved in a single place.
196*cc02d7e2SAndroid Build Coastguard Worker */
197*cc02d7e2SAndroid Build Coastguard Worker # define XXH_IPREF(Id) XXH_NAMESPACE ## Id
198*cc02d7e2SAndroid Build Coastguard Worker # define XXH_OK XXH_IPREF(XXH_OK)
199*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ERROR XXH_IPREF(XXH_ERROR)
200*cc02d7e2SAndroid Build Coastguard Worker # define XXH_errorcode XXH_IPREF(XXH_errorcode)
201*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)
202*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)
203*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)
204*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_state_s XXH_IPREF(XXH32_state_s)
205*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_state_t XXH_IPREF(XXH32_state_t)
206*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_state_s XXH_IPREF(XXH64_state_s)
207*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_state_t XXH_IPREF(XXH64_state_t)
208*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_state_s XXH_IPREF(XXH3_state_s)
209*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_state_t XXH_IPREF(XXH3_state_t)
210*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_hash_t XXH_IPREF(XXH128_hash_t)
211*cc02d7e2SAndroid Build Coastguard Worker /* Ensure the header is parsed again, even if it was previously included */
212*cc02d7e2SAndroid Build Coastguard Worker # undef XXHASH_H_5627135585666179
213*cc02d7e2SAndroid Build Coastguard Worker # undef XXHASH_H_STATIC_13879238742
214*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
215*cc02d7e2SAndroid Build Coastguard Worker
216*cc02d7e2SAndroid Build Coastguard Worker
217*cc02d7e2SAndroid Build Coastguard Worker
218*cc02d7e2SAndroid Build Coastguard Worker /* ****************************************************************
219*cc02d7e2SAndroid Build Coastguard Worker * Stable API
220*cc02d7e2SAndroid Build Coastguard Worker *****************************************************************/
221*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXHASH_H_5627135585666179
222*cc02d7e2SAndroid Build Coastguard Worker #define XXHASH_H_5627135585666179 1
223*cc02d7e2SAndroid Build Coastguard Worker
224*cc02d7e2SAndroid Build Coastguard Worker
225*cc02d7e2SAndroid Build Coastguard Worker /*!
226*cc02d7e2SAndroid Build Coastguard Worker * @defgroup public Public API
227*cc02d7e2SAndroid Build Coastguard Worker * Contains details on the public xxHash functions.
228*cc02d7e2SAndroid Build Coastguard Worker * @{
229*cc02d7e2SAndroid Build Coastguard Worker */
230*cc02d7e2SAndroid Build Coastguard Worker /* specific declaration modes for Windows */
231*cc02d7e2SAndroid Build Coastguard Worker #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
232*cc02d7e2SAndroid Build Coastguard Worker # if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
233*cc02d7e2SAndroid Build Coastguard Worker # ifdef XXH_EXPORT
234*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API __declspec(dllexport)
235*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_IMPORT
236*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API __declspec(dllimport)
237*cc02d7e2SAndroid Build Coastguard Worker # endif
238*cc02d7e2SAndroid Build Coastguard Worker # else
239*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PUBLIC_API /* do nothing */
240*cc02d7e2SAndroid Build Coastguard Worker # endif
241*cc02d7e2SAndroid Build Coastguard Worker #endif
242*cc02d7e2SAndroid Build Coastguard Worker
243*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_DOXYGEN
244*cc02d7e2SAndroid Build Coastguard Worker /*!
245*cc02d7e2SAndroid Build Coastguard Worker * @brief Emulate a namespace by transparently prefixing all symbols.
246*cc02d7e2SAndroid Build Coastguard Worker *
247*cc02d7e2SAndroid Build Coastguard Worker * If you want to include _and expose_ xxHash functions from within your own
248*cc02d7e2SAndroid Build Coastguard Worker * library, but also want to avoid symbol collisions with other libraries which
249*cc02d7e2SAndroid Build Coastguard Worker * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix
250*cc02d7e2SAndroid Build Coastguard Worker * any public symbol from xxhash library with the value of XXH_NAMESPACE
251*cc02d7e2SAndroid Build Coastguard Worker * (therefore, avoid empty or numeric values).
252*cc02d7e2SAndroid Build Coastguard Worker *
253*cc02d7e2SAndroid Build Coastguard Worker * Note that no change is required within the calling program as long as it
254*cc02d7e2SAndroid Build Coastguard Worker * includes `xxhash.h`: Regular symbol names will be automatically translated
255*cc02d7e2SAndroid Build Coastguard Worker * by this header.
256*cc02d7e2SAndroid Build Coastguard Worker */
257*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NAMESPACE /* YOUR NAME HERE */
258*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_NAMESPACE
259*cc02d7e2SAndroid Build Coastguard Worker #endif
260*cc02d7e2SAndroid Build Coastguard Worker
261*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_NAMESPACE
262*cc02d7e2SAndroid Build Coastguard Worker # define XXH_CAT(A,B) A##B
263*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NAME2(A,B) XXH_CAT(A,B)
264*cc02d7e2SAndroid Build Coastguard Worker # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
265*cc02d7e2SAndroid Build Coastguard Worker /* XXH32 */
266*cc02d7e2SAndroid Build Coastguard Worker # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
267*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
268*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
269*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
270*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
271*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
272*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
273*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
274*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
275*cc02d7e2SAndroid Build Coastguard Worker /* XXH64 */
276*cc02d7e2SAndroid Build Coastguard Worker # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
277*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
278*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
279*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
280*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
281*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
282*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
283*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
284*cc02d7e2SAndroid Build Coastguard Worker # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
285*cc02d7e2SAndroid Build Coastguard Worker /* XXH3_64bits */
286*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)
287*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)
288*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)
289*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed)
290*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)
291*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)
292*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)
293*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)
294*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)
295*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)
296*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed)
297*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)
298*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)
299*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)
300*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed)
301*cc02d7e2SAndroid Build Coastguard Worker /* XXH3_128bits */
302*cc02d7e2SAndroid Build Coastguard Worker # define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)
303*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)
304*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)
305*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)
306*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed)
307*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)
308*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)
309*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)
310*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed)
311*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)
312*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)
313*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)
314*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp)
315*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash)
316*cc02d7e2SAndroid Build Coastguard Worker # define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical)
317*cc02d7e2SAndroid Build Coastguard Worker #endif
318*cc02d7e2SAndroid Build Coastguard Worker
319*cc02d7e2SAndroid Build Coastguard Worker
320*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
321*cc02d7e2SAndroid Build Coastguard Worker * Version
322*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
323*cc02d7e2SAndroid Build Coastguard Worker #define XXH_VERSION_MAJOR 0
324*cc02d7e2SAndroid Build Coastguard Worker #define XXH_VERSION_MINOR 8
325*cc02d7e2SAndroid Build Coastguard Worker #define XXH_VERSION_RELEASE 1
326*cc02d7e2SAndroid Build Coastguard Worker #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
327*cc02d7e2SAndroid Build Coastguard Worker
328*cc02d7e2SAndroid Build Coastguard Worker /*!
329*cc02d7e2SAndroid Build Coastguard Worker * @brief Obtains the xxHash version.
330*cc02d7e2SAndroid Build Coastguard Worker *
331*cc02d7e2SAndroid Build Coastguard Worker * This is mostly useful when xxHash is compiled as a shared library,
332*cc02d7e2SAndroid Build Coastguard Worker * since the returned value comes from the library, as opposed to header file.
333*cc02d7e2SAndroid Build Coastguard Worker *
334*cc02d7e2SAndroid Build Coastguard Worker * @return `XXH_VERSION_NUMBER` of the invoked library.
335*cc02d7e2SAndroid Build Coastguard Worker */
336*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API unsigned XXH_versionNumber (void);
337*cc02d7e2SAndroid Build Coastguard Worker
338*cc02d7e2SAndroid Build Coastguard Worker
339*cc02d7e2SAndroid Build Coastguard Worker /* ****************************
340*cc02d7e2SAndroid Build Coastguard Worker * Common basic types
341*cc02d7e2SAndroid Build Coastguard Worker ******************************/
342*cc02d7e2SAndroid Build Coastguard Worker #include <stddef.h> /* size_t */
343*cc02d7e2SAndroid Build Coastguard Worker typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
344*cc02d7e2SAndroid Build Coastguard Worker
345*cc02d7e2SAndroid Build Coastguard Worker
346*cc02d7e2SAndroid Build Coastguard Worker /*-**********************************************************************
347*cc02d7e2SAndroid Build Coastguard Worker * 32-bit hash
348*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************/
349*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_DOXYGEN) /* Don't show <stdint.h> include */
350*cc02d7e2SAndroid Build Coastguard Worker /*!
351*cc02d7e2SAndroid Build Coastguard Worker * @brief An unsigned 32-bit integer.
352*cc02d7e2SAndroid Build Coastguard Worker *
353*cc02d7e2SAndroid Build Coastguard Worker * Not necessarily defined to `uint32_t` but functionally equivalent.
354*cc02d7e2SAndroid Build Coastguard Worker */
355*cc02d7e2SAndroid Build Coastguard Worker typedef uint32_t XXH32_hash_t;
356*cc02d7e2SAndroid Build Coastguard Worker
357*cc02d7e2SAndroid Build Coastguard Worker #elif !defined (__VMS) \
358*cc02d7e2SAndroid Build Coastguard Worker && (defined (__cplusplus) \
359*cc02d7e2SAndroid Build Coastguard Worker || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
360*cc02d7e2SAndroid Build Coastguard Worker # include <stdint.h>
361*cc02d7e2SAndroid Build Coastguard Worker typedef uint32_t XXH32_hash_t;
362*cc02d7e2SAndroid Build Coastguard Worker
363*cc02d7e2SAndroid Build Coastguard Worker #else
364*cc02d7e2SAndroid Build Coastguard Worker # include <limits.h>
365*cc02d7e2SAndroid Build Coastguard Worker # if UINT_MAX == 0xFFFFFFFFUL
366*cc02d7e2SAndroid Build Coastguard Worker typedef unsigned int XXH32_hash_t;
367*cc02d7e2SAndroid Build Coastguard Worker # else
368*cc02d7e2SAndroid Build Coastguard Worker # if ULONG_MAX == 0xFFFFFFFFUL
369*cc02d7e2SAndroid Build Coastguard Worker typedef unsigned long XXH32_hash_t;
370*cc02d7e2SAndroid Build Coastguard Worker # else
371*cc02d7e2SAndroid Build Coastguard Worker # error "unsupported platform: need a 32-bit type"
372*cc02d7e2SAndroid Build Coastguard Worker # endif
373*cc02d7e2SAndroid Build Coastguard Worker # endif
374*cc02d7e2SAndroid Build Coastguard Worker #endif
375*cc02d7e2SAndroid Build Coastguard Worker
376*cc02d7e2SAndroid Build Coastguard Worker /*!
377*cc02d7e2SAndroid Build Coastguard Worker * @}
378*cc02d7e2SAndroid Build Coastguard Worker *
379*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh32_family XXH32 family
380*cc02d7e2SAndroid Build Coastguard Worker * @ingroup public
381*cc02d7e2SAndroid Build Coastguard Worker * Contains functions used in the classic 32-bit xxHash algorithm.
382*cc02d7e2SAndroid Build Coastguard Worker *
383*cc02d7e2SAndroid Build Coastguard Worker * @note
384*cc02d7e2SAndroid Build Coastguard Worker * XXH32 is useful for older platforms, with no or poor 64-bit performance.
385*cc02d7e2SAndroid Build Coastguard Worker * Note that @ref xxh3_family provides competitive speed
386*cc02d7e2SAndroid Build Coastguard Worker * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results.
387*cc02d7e2SAndroid Build Coastguard Worker *
388*cc02d7e2SAndroid Build Coastguard Worker * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families
389*cc02d7e2SAndroid Build Coastguard Worker * @see @ref xxh32_impl for implementation details
390*cc02d7e2SAndroid Build Coastguard Worker * @{
391*cc02d7e2SAndroid Build Coastguard Worker */
392*cc02d7e2SAndroid Build Coastguard Worker
393*cc02d7e2SAndroid Build Coastguard Worker /*!
394*cc02d7e2SAndroid Build Coastguard Worker * @brief Calculates the 32-bit hash of @p input using xxHash32.
395*cc02d7e2SAndroid Build Coastguard Worker *
396*cc02d7e2SAndroid Build Coastguard Worker * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s
397*cc02d7e2SAndroid Build Coastguard Worker *
398*cc02d7e2SAndroid Build Coastguard Worker * @param input The block of data to be hashed, at least @p length bytes in size.
399*cc02d7e2SAndroid Build Coastguard Worker * @param length The length of @p input, in bytes.
400*cc02d7e2SAndroid Build Coastguard Worker * @param seed The 32-bit seed to alter the hash's output predictably.
401*cc02d7e2SAndroid Build Coastguard Worker *
402*cc02d7e2SAndroid Build Coastguard Worker * @pre
403*cc02d7e2SAndroid Build Coastguard Worker * The memory between @p input and @p input + @p length must be valid,
404*cc02d7e2SAndroid Build Coastguard Worker * readable, contiguous memory. However, if @p length is `0`, @p input may be
405*cc02d7e2SAndroid Build Coastguard Worker * `NULL`. In C++, this also must be *TriviallyCopyable*.
406*cc02d7e2SAndroid Build Coastguard Worker *
407*cc02d7e2SAndroid Build Coastguard Worker * @return The calculated 32-bit hash value.
408*cc02d7e2SAndroid Build Coastguard Worker *
409*cc02d7e2SAndroid Build Coastguard Worker * @see
410*cc02d7e2SAndroid Build Coastguard Worker * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
411*cc02d7e2SAndroid Build Coastguard Worker * Direct equivalents for the other variants of xxHash.
412*cc02d7e2SAndroid Build Coastguard Worker * @see
413*cc02d7e2SAndroid Build Coastguard Worker * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.
414*cc02d7e2SAndroid Build Coastguard Worker */
415*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
416*cc02d7e2SAndroid Build Coastguard Worker
417*cc02d7e2SAndroid Build Coastguard Worker /*!
418*cc02d7e2SAndroid Build Coastguard Worker * Streaming functions generate the xxHash value from an incremental input.
419*cc02d7e2SAndroid Build Coastguard Worker * This method is slower than single-call functions, due to state management.
420*cc02d7e2SAndroid Build Coastguard Worker * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
421*cc02d7e2SAndroid Build Coastguard Worker *
422*cc02d7e2SAndroid Build Coastguard Worker * An XXH state must first be allocated using `XXH*_createState()`.
423*cc02d7e2SAndroid Build Coastguard Worker *
424*cc02d7e2SAndroid Build Coastguard Worker * Start a new hash by initializing the state with a seed using `XXH*_reset()`.
425*cc02d7e2SAndroid Build Coastguard Worker *
426*cc02d7e2SAndroid Build Coastguard Worker * Then, feed the hash state by calling `XXH*_update()` as many times as necessary.
427*cc02d7e2SAndroid Build Coastguard Worker *
428*cc02d7e2SAndroid Build Coastguard Worker * The function returns an error code, with 0 meaning OK, and any other value
429*cc02d7e2SAndroid Build Coastguard Worker * meaning there is an error.
430*cc02d7e2SAndroid Build Coastguard Worker *
431*cc02d7e2SAndroid Build Coastguard Worker * Finally, a hash value can be produced anytime, by using `XXH*_digest()`.
432*cc02d7e2SAndroid Build Coastguard Worker * This function returns the nn-bits hash as an int or long long.
433*cc02d7e2SAndroid Build Coastguard Worker *
434*cc02d7e2SAndroid Build Coastguard Worker * It's still possible to continue inserting input into the hash state after a
435*cc02d7e2SAndroid Build Coastguard Worker * digest, and generate new hash values later on by invoking `XXH*_digest()`.
436*cc02d7e2SAndroid Build Coastguard Worker *
437*cc02d7e2SAndroid Build Coastguard Worker * When done, release the state using `XXH*_freeState()`.
438*cc02d7e2SAndroid Build Coastguard Worker *
439*cc02d7e2SAndroid Build Coastguard Worker * Example code for incrementally hashing a file:
440*cc02d7e2SAndroid Build Coastguard Worker * @code{.c}
441*cc02d7e2SAndroid Build Coastguard Worker * #include <stdio.h>
442*cc02d7e2SAndroid Build Coastguard Worker * #include <xxhash.h>
443*cc02d7e2SAndroid Build Coastguard Worker * #define BUFFER_SIZE 256
444*cc02d7e2SAndroid Build Coastguard Worker *
445*cc02d7e2SAndroid Build Coastguard Worker * // Note: XXH64 and XXH3 use the same interface.
446*cc02d7e2SAndroid Build Coastguard Worker * XXH32_hash_t
447*cc02d7e2SAndroid Build Coastguard Worker * hashFile(FILE* stream)
448*cc02d7e2SAndroid Build Coastguard Worker * {
449*cc02d7e2SAndroid Build Coastguard Worker * XXH32_state_t* state;
450*cc02d7e2SAndroid Build Coastguard Worker * unsigned char buf[BUFFER_SIZE];
451*cc02d7e2SAndroid Build Coastguard Worker * size_t amt;
452*cc02d7e2SAndroid Build Coastguard Worker * XXH32_hash_t hash;
453*cc02d7e2SAndroid Build Coastguard Worker *
454*cc02d7e2SAndroid Build Coastguard Worker * state = XXH32_createState(); // Create a state
455*cc02d7e2SAndroid Build Coastguard Worker * assert(state != NULL); // Error check here
456*cc02d7e2SAndroid Build Coastguard Worker * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed
457*cc02d7e2SAndroid Build Coastguard Worker * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) {
458*cc02d7e2SAndroid Build Coastguard Worker * XXH32_update(state, buf, amt); // Hash the file in chunks
459*cc02d7e2SAndroid Build Coastguard Worker * }
460*cc02d7e2SAndroid Build Coastguard Worker * hash = XXH32_digest(state); // Finalize the hash
461*cc02d7e2SAndroid Build Coastguard Worker * XXH32_freeState(state); // Clean up
462*cc02d7e2SAndroid Build Coastguard Worker * return hash;
463*cc02d7e2SAndroid Build Coastguard Worker * }
464*cc02d7e2SAndroid Build Coastguard Worker * @endcode
465*cc02d7e2SAndroid Build Coastguard Worker */
466*cc02d7e2SAndroid Build Coastguard Worker
467*cc02d7e2SAndroid Build Coastguard Worker /*!
468*cc02d7e2SAndroid Build Coastguard Worker * @typedef struct XXH32_state_s XXH32_state_t
469*cc02d7e2SAndroid Build Coastguard Worker * @brief The opaque state struct for the XXH32 streaming API.
470*cc02d7e2SAndroid Build Coastguard Worker *
471*cc02d7e2SAndroid Build Coastguard Worker * @see XXH32_state_s for details.
472*cc02d7e2SAndroid Build Coastguard Worker */
473*cc02d7e2SAndroid Build Coastguard Worker typedef struct XXH32_state_s XXH32_state_t;
474*cc02d7e2SAndroid Build Coastguard Worker
475*cc02d7e2SAndroid Build Coastguard Worker /*!
476*cc02d7e2SAndroid Build Coastguard Worker * @brief Allocates an @ref XXH32_state_t.
477*cc02d7e2SAndroid Build Coastguard Worker *
478*cc02d7e2SAndroid Build Coastguard Worker * Must be freed with XXH32_freeState().
479*cc02d7e2SAndroid Build Coastguard Worker * @return An allocated XXH32_state_t on success, `NULL` on failure.
480*cc02d7e2SAndroid Build Coastguard Worker */
481*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
482*cc02d7e2SAndroid Build Coastguard Worker /*!
483*cc02d7e2SAndroid Build Coastguard Worker * @brief Frees an @ref XXH32_state_t.
484*cc02d7e2SAndroid Build Coastguard Worker *
485*cc02d7e2SAndroid Build Coastguard Worker * Must be allocated with XXH32_createState().
486*cc02d7e2SAndroid Build Coastguard Worker * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState().
487*cc02d7e2SAndroid Build Coastguard Worker * @return XXH_OK.
488*cc02d7e2SAndroid Build Coastguard Worker */
489*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
490*cc02d7e2SAndroid Build Coastguard Worker /*!
491*cc02d7e2SAndroid Build Coastguard Worker * @brief Copies one @ref XXH32_state_t to another.
492*cc02d7e2SAndroid Build Coastguard Worker *
493*cc02d7e2SAndroid Build Coastguard Worker * @param dst_state The state to copy to.
494*cc02d7e2SAndroid Build Coastguard Worker * @param src_state The state to copy from.
495*cc02d7e2SAndroid Build Coastguard Worker * @pre
496*cc02d7e2SAndroid Build Coastguard Worker * @p dst_state and @p src_state must not be `NULL` and must not overlap.
497*cc02d7e2SAndroid Build Coastguard Worker */
498*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
499*cc02d7e2SAndroid Build Coastguard Worker
500*cc02d7e2SAndroid Build Coastguard Worker /*!
501*cc02d7e2SAndroid Build Coastguard Worker * @brief Resets an @ref XXH32_state_t to begin a new hash.
502*cc02d7e2SAndroid Build Coastguard Worker *
503*cc02d7e2SAndroid Build Coastguard Worker * This function resets and seeds a state. Call it before @ref XXH32_update().
504*cc02d7e2SAndroid Build Coastguard Worker *
505*cc02d7e2SAndroid Build Coastguard Worker * @param statePtr The state struct to reset.
506*cc02d7e2SAndroid Build Coastguard Worker * @param seed The 32-bit seed to alter the hash result predictably.
507*cc02d7e2SAndroid Build Coastguard Worker *
508*cc02d7e2SAndroid Build Coastguard Worker * @pre
509*cc02d7e2SAndroid Build Coastguard Worker * @p statePtr must not be `NULL`.
510*cc02d7e2SAndroid Build Coastguard Worker *
511*cc02d7e2SAndroid Build Coastguard Worker * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
512*cc02d7e2SAndroid Build Coastguard Worker */
513*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed);
514*cc02d7e2SAndroid Build Coastguard Worker
515*cc02d7e2SAndroid Build Coastguard Worker /*!
516*cc02d7e2SAndroid Build Coastguard Worker * @brief Consumes a block of @p input to an @ref XXH32_state_t.
517*cc02d7e2SAndroid Build Coastguard Worker *
518*cc02d7e2SAndroid Build Coastguard Worker * Call this to incrementally consume blocks of data.
519*cc02d7e2SAndroid Build Coastguard Worker *
520*cc02d7e2SAndroid Build Coastguard Worker * @param statePtr The state struct to update.
521*cc02d7e2SAndroid Build Coastguard Worker * @param input The block of data to be hashed, at least @p length bytes in size.
522*cc02d7e2SAndroid Build Coastguard Worker * @param length The length of @p input, in bytes.
523*cc02d7e2SAndroid Build Coastguard Worker *
524*cc02d7e2SAndroid Build Coastguard Worker * @pre
525*cc02d7e2SAndroid Build Coastguard Worker * @p statePtr must not be `NULL`.
526*cc02d7e2SAndroid Build Coastguard Worker * @pre
527*cc02d7e2SAndroid Build Coastguard Worker * The memory between @p input and @p input + @p length must be valid,
528*cc02d7e2SAndroid Build Coastguard Worker * readable, contiguous memory. However, if @p length is `0`, @p input may be
529*cc02d7e2SAndroid Build Coastguard Worker * `NULL`. In C++, this also must be *TriviallyCopyable*.
530*cc02d7e2SAndroid Build Coastguard Worker *
531*cc02d7e2SAndroid Build Coastguard Worker * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
532*cc02d7e2SAndroid Build Coastguard Worker */
533*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
534*cc02d7e2SAndroid Build Coastguard Worker
535*cc02d7e2SAndroid Build Coastguard Worker /*!
536*cc02d7e2SAndroid Build Coastguard Worker * @brief Returns the calculated hash value from an @ref XXH32_state_t.
537*cc02d7e2SAndroid Build Coastguard Worker *
538*cc02d7e2SAndroid Build Coastguard Worker * @note
539*cc02d7e2SAndroid Build Coastguard Worker * Calling XXH32_digest() will not affect @p statePtr, so you can update,
540*cc02d7e2SAndroid Build Coastguard Worker * digest, and update again.
541*cc02d7e2SAndroid Build Coastguard Worker *
542*cc02d7e2SAndroid Build Coastguard Worker * @param statePtr The state struct to calculate the hash from.
543*cc02d7e2SAndroid Build Coastguard Worker *
544*cc02d7e2SAndroid Build Coastguard Worker * @pre
545*cc02d7e2SAndroid Build Coastguard Worker * @p statePtr must not be `NULL`.
546*cc02d7e2SAndroid Build Coastguard Worker *
547*cc02d7e2SAndroid Build Coastguard Worker * @return The calculated xxHash32 value from that state.
548*cc02d7e2SAndroid Build Coastguard Worker */
549*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
550*cc02d7e2SAndroid Build Coastguard Worker
551*cc02d7e2SAndroid Build Coastguard Worker /******* Canonical representation *******/
552*cc02d7e2SAndroid Build Coastguard Worker
553*cc02d7e2SAndroid Build Coastguard Worker /*
554*cc02d7e2SAndroid Build Coastguard Worker * The default return values from XXH functions are unsigned 32 and 64 bit
555*cc02d7e2SAndroid Build Coastguard Worker * integers.
556*cc02d7e2SAndroid Build Coastguard Worker * This the simplest and fastest format for further post-processing.
557*cc02d7e2SAndroid Build Coastguard Worker *
558*cc02d7e2SAndroid Build Coastguard Worker * However, this leaves open the question of what is the order on the byte level,
559*cc02d7e2SAndroid Build Coastguard Worker * since little and big endian conventions will store the same number differently.
560*cc02d7e2SAndroid Build Coastguard Worker *
561*cc02d7e2SAndroid Build Coastguard Worker * The canonical representation settles this issue by mandating big-endian
562*cc02d7e2SAndroid Build Coastguard Worker * convention, the same convention as human-readable numbers (large digits first).
563*cc02d7e2SAndroid Build Coastguard Worker *
564*cc02d7e2SAndroid Build Coastguard Worker * When writing hash values to storage, sending them over a network, or printing
565*cc02d7e2SAndroid Build Coastguard Worker * them, it's highly recommended to use the canonical representation to ensure
566*cc02d7e2SAndroid Build Coastguard Worker * portability across a wider range of systems, present and future.
567*cc02d7e2SAndroid Build Coastguard Worker *
568*cc02d7e2SAndroid Build Coastguard Worker * The following functions allow transformation of hash values to and from
569*cc02d7e2SAndroid Build Coastguard Worker * canonical format.
570*cc02d7e2SAndroid Build Coastguard Worker */
571*cc02d7e2SAndroid Build Coastguard Worker
572*cc02d7e2SAndroid Build Coastguard Worker /*!
573*cc02d7e2SAndroid Build Coastguard Worker * @brief Canonical (big endian) representation of @ref XXH32_hash_t.
574*cc02d7e2SAndroid Build Coastguard Worker */
575*cc02d7e2SAndroid Build Coastguard Worker typedef struct {
576*cc02d7e2SAndroid Build Coastguard Worker unsigned char digest[4]; /*!< Hash bytes, big endian */
577*cc02d7e2SAndroid Build Coastguard Worker } XXH32_canonical_t;
578*cc02d7e2SAndroid Build Coastguard Worker
579*cc02d7e2SAndroid Build Coastguard Worker /*!
580*cc02d7e2SAndroid Build Coastguard Worker * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t.
581*cc02d7e2SAndroid Build Coastguard Worker *
582*cc02d7e2SAndroid Build Coastguard Worker * @param dst The @ref XXH32_canonical_t pointer to be stored to.
583*cc02d7e2SAndroid Build Coastguard Worker * @param hash The @ref XXH32_hash_t to be converted.
584*cc02d7e2SAndroid Build Coastguard Worker *
585*cc02d7e2SAndroid Build Coastguard Worker * @pre
586*cc02d7e2SAndroid Build Coastguard Worker * @p dst must not be `NULL`.
587*cc02d7e2SAndroid Build Coastguard Worker */
588*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
589*cc02d7e2SAndroid Build Coastguard Worker
590*cc02d7e2SAndroid Build Coastguard Worker /*!
591*cc02d7e2SAndroid Build Coastguard Worker * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t.
592*cc02d7e2SAndroid Build Coastguard Worker *
593*cc02d7e2SAndroid Build Coastguard Worker * @param src The @ref XXH32_canonical_t to convert.
594*cc02d7e2SAndroid Build Coastguard Worker *
595*cc02d7e2SAndroid Build Coastguard Worker * @pre
596*cc02d7e2SAndroid Build Coastguard Worker * @p src must not be `NULL`.
597*cc02d7e2SAndroid Build Coastguard Worker *
598*cc02d7e2SAndroid Build Coastguard Worker * @return The converted hash.
599*cc02d7e2SAndroid Build Coastguard Worker */
600*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
601*cc02d7e2SAndroid Build Coastguard Worker
602*cc02d7e2SAndroid Build Coastguard Worker
603*cc02d7e2SAndroid Build Coastguard Worker #ifdef __has_attribute
604*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
605*cc02d7e2SAndroid Build Coastguard Worker #else
606*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_ATTRIBUTE(x) 0
607*cc02d7e2SAndroid Build Coastguard Worker #endif
608*cc02d7e2SAndroid Build Coastguard Worker
609*cc02d7e2SAndroid Build Coastguard Worker /* C-language Attributes are added in C23. */
610*cc02d7e2SAndroid Build Coastguard Worker #if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
611*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
612*cc02d7e2SAndroid Build Coastguard Worker #else
613*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_C_ATTRIBUTE(x) 0
614*cc02d7e2SAndroid Build Coastguard Worker #endif
615*cc02d7e2SAndroid Build Coastguard Worker
616*cc02d7e2SAndroid Build Coastguard Worker #if defined(__cplusplus) && defined(__has_cpp_attribute)
617*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
618*cc02d7e2SAndroid Build Coastguard Worker #else
619*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_CPP_ATTRIBUTE(x) 0
620*cc02d7e2SAndroid Build Coastguard Worker #endif
621*cc02d7e2SAndroid Build Coastguard Worker
622*cc02d7e2SAndroid Build Coastguard Worker /*
623*cc02d7e2SAndroid Build Coastguard Worker Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
624*cc02d7e2SAndroid Build Coastguard Worker introduced in CPP17 and C23.
625*cc02d7e2SAndroid Build Coastguard Worker CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
626*cc02d7e2SAndroid Build Coastguard Worker C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
627*cc02d7e2SAndroid Build Coastguard Worker */
628*cc02d7e2SAndroid Build Coastguard Worker #if XXH_HAS_C_ATTRIBUTE(x)
629*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FALLTHROUGH [[fallthrough]]
630*cc02d7e2SAndroid Build Coastguard Worker #elif XXH_HAS_CPP_ATTRIBUTE(x)
631*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FALLTHROUGH [[fallthrough]]
632*cc02d7e2SAndroid Build Coastguard Worker #elif XXH_HAS_ATTRIBUTE(__fallthrough__)
633*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FALLTHROUGH __attribute__ ((fallthrough))
634*cc02d7e2SAndroid Build Coastguard Worker #else
635*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FALLTHROUGH
636*cc02d7e2SAndroid Build Coastguard Worker #endif
637*cc02d7e2SAndroid Build Coastguard Worker
638*cc02d7e2SAndroid Build Coastguard Worker /*!
639*cc02d7e2SAndroid Build Coastguard Worker * @}
640*cc02d7e2SAndroid Build Coastguard Worker * @ingroup public
641*cc02d7e2SAndroid Build Coastguard Worker * @{
642*cc02d7e2SAndroid Build Coastguard Worker */
643*cc02d7e2SAndroid Build Coastguard Worker
644*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_NO_LONG_LONG
645*cc02d7e2SAndroid Build Coastguard Worker /*-**********************************************************************
646*cc02d7e2SAndroid Build Coastguard Worker * 64-bit hash
647*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************/
648*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_DOXYGEN) /* don't include <stdint.h> */
649*cc02d7e2SAndroid Build Coastguard Worker /*!
650*cc02d7e2SAndroid Build Coastguard Worker * @brief An unsigned 64-bit integer.
651*cc02d7e2SAndroid Build Coastguard Worker *
652*cc02d7e2SAndroid Build Coastguard Worker * Not necessarily defined to `uint64_t` but functionally equivalent.
653*cc02d7e2SAndroid Build Coastguard Worker */
654*cc02d7e2SAndroid Build Coastguard Worker typedef uint64_t XXH64_hash_t;
655*cc02d7e2SAndroid Build Coastguard Worker #elif !defined (__VMS) \
656*cc02d7e2SAndroid Build Coastguard Worker && (defined (__cplusplus) \
657*cc02d7e2SAndroid Build Coastguard Worker || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
658*cc02d7e2SAndroid Build Coastguard Worker # include <stdint.h>
659*cc02d7e2SAndroid Build Coastguard Worker typedef uint64_t XXH64_hash_t;
660*cc02d7e2SAndroid Build Coastguard Worker #else
661*cc02d7e2SAndroid Build Coastguard Worker # include <limits.h>
662*cc02d7e2SAndroid Build Coastguard Worker # if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL
663*cc02d7e2SAndroid Build Coastguard Worker /* LP64 ABI says uint64_t is unsigned long */
664*cc02d7e2SAndroid Build Coastguard Worker typedef unsigned long XXH64_hash_t;
665*cc02d7e2SAndroid Build Coastguard Worker # else
666*cc02d7e2SAndroid Build Coastguard Worker /* the following type must have a width of 64-bit */
667*cc02d7e2SAndroid Build Coastguard Worker typedef unsigned long long XXH64_hash_t;
668*cc02d7e2SAndroid Build Coastguard Worker # endif
669*cc02d7e2SAndroid Build Coastguard Worker #endif
670*cc02d7e2SAndroid Build Coastguard Worker
671*cc02d7e2SAndroid Build Coastguard Worker /*!
672*cc02d7e2SAndroid Build Coastguard Worker * @}
673*cc02d7e2SAndroid Build Coastguard Worker *
674*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh64_family XXH64 family
675*cc02d7e2SAndroid Build Coastguard Worker * @ingroup public
676*cc02d7e2SAndroid Build Coastguard Worker * @{
677*cc02d7e2SAndroid Build Coastguard Worker * Contains functions used in the classic 64-bit xxHash algorithm.
678*cc02d7e2SAndroid Build Coastguard Worker *
679*cc02d7e2SAndroid Build Coastguard Worker * @note
680*cc02d7e2SAndroid Build Coastguard Worker * XXH3 provides competitive speed for both 32-bit and 64-bit systems,
681*cc02d7e2SAndroid Build Coastguard Worker * and offers true 64/128 bit hash results.
682*cc02d7e2SAndroid Build Coastguard Worker * It provides better speed for systems with vector processing capabilities.
683*cc02d7e2SAndroid Build Coastguard Worker */
684*cc02d7e2SAndroid Build Coastguard Worker
685*cc02d7e2SAndroid Build Coastguard Worker
686*cc02d7e2SAndroid Build Coastguard Worker /*!
687*cc02d7e2SAndroid Build Coastguard Worker * @brief Calculates the 64-bit hash of @p input using xxHash64.
688*cc02d7e2SAndroid Build Coastguard Worker *
689*cc02d7e2SAndroid Build Coastguard Worker * This function usually runs faster on 64-bit systems, but slower on 32-bit
690*cc02d7e2SAndroid Build Coastguard Worker * systems (see benchmark).
691*cc02d7e2SAndroid Build Coastguard Worker *
692*cc02d7e2SAndroid Build Coastguard Worker * @param input The block of data to be hashed, at least @p length bytes in size.
693*cc02d7e2SAndroid Build Coastguard Worker * @param length The length of @p input, in bytes.
694*cc02d7e2SAndroid Build Coastguard Worker * @param seed The 64-bit seed to alter the hash's output predictably.
695*cc02d7e2SAndroid Build Coastguard Worker *
696*cc02d7e2SAndroid Build Coastguard Worker * @pre
697*cc02d7e2SAndroid Build Coastguard Worker * The memory between @p input and @p input + @p length must be valid,
698*cc02d7e2SAndroid Build Coastguard Worker * readable, contiguous memory. However, if @p length is `0`, @p input may be
699*cc02d7e2SAndroid Build Coastguard Worker * `NULL`. In C++, this also must be *TriviallyCopyable*.
700*cc02d7e2SAndroid Build Coastguard Worker *
701*cc02d7e2SAndroid Build Coastguard Worker * @return The calculated 64-bit hash.
702*cc02d7e2SAndroid Build Coastguard Worker *
703*cc02d7e2SAndroid Build Coastguard Worker * @see
704*cc02d7e2SAndroid Build Coastguard Worker * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
705*cc02d7e2SAndroid Build Coastguard Worker * Direct equivalents for the other variants of xxHash.
706*cc02d7e2SAndroid Build Coastguard Worker * @see
707*cc02d7e2SAndroid Build Coastguard Worker * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
708*cc02d7e2SAndroid Build Coastguard Worker */
709*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
710*cc02d7e2SAndroid Build Coastguard Worker
711*cc02d7e2SAndroid Build Coastguard Worker /******* Streaming *******/
712*cc02d7e2SAndroid Build Coastguard Worker /*!
713*cc02d7e2SAndroid Build Coastguard Worker * @brief The opaque state struct for the XXH64 streaming API.
714*cc02d7e2SAndroid Build Coastguard Worker *
715*cc02d7e2SAndroid Build Coastguard Worker * @see XXH64_state_s for details.
716*cc02d7e2SAndroid Build Coastguard Worker */
717*cc02d7e2SAndroid Build Coastguard Worker typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
718*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
719*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
720*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
721*cc02d7e2SAndroid Build Coastguard Worker
722*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);
723*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
724*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
725*cc02d7e2SAndroid Build Coastguard Worker
726*cc02d7e2SAndroid Build Coastguard Worker /******* Canonical representation *******/
727*cc02d7e2SAndroid Build Coastguard Worker typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
728*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
729*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
730*cc02d7e2SAndroid Build Coastguard Worker
731*cc02d7e2SAndroid Build Coastguard Worker /*!
732*cc02d7e2SAndroid Build Coastguard Worker * @}
733*cc02d7e2SAndroid Build Coastguard Worker * ************************************************************************
734*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh3_family XXH3 family
735*cc02d7e2SAndroid Build Coastguard Worker * @ingroup public
736*cc02d7e2SAndroid Build Coastguard Worker * @{
737*cc02d7e2SAndroid Build Coastguard Worker *
738*cc02d7e2SAndroid Build Coastguard Worker * XXH3 is a more recent hash algorithm featuring:
739*cc02d7e2SAndroid Build Coastguard Worker * - Improved speed for both small and large inputs
740*cc02d7e2SAndroid Build Coastguard Worker * - True 64-bit and 128-bit outputs
741*cc02d7e2SAndroid Build Coastguard Worker * - SIMD acceleration
742*cc02d7e2SAndroid Build Coastguard Worker * - Improved 32-bit viability
743*cc02d7e2SAndroid Build Coastguard Worker *
744*cc02d7e2SAndroid Build Coastguard Worker * Speed analysis methodology is explained here:
745*cc02d7e2SAndroid Build Coastguard Worker *
746*cc02d7e2SAndroid Build Coastguard Worker * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html
747*cc02d7e2SAndroid Build Coastguard Worker *
748*cc02d7e2SAndroid Build Coastguard Worker * Compared to XXH64, expect XXH3 to run approximately
749*cc02d7e2SAndroid Build Coastguard Worker * ~2x faster on large inputs and >3x faster on small ones,
750*cc02d7e2SAndroid Build Coastguard Worker * exact differences vary depending on platform.
751*cc02d7e2SAndroid Build Coastguard Worker *
752*cc02d7e2SAndroid Build Coastguard Worker * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,
753*cc02d7e2SAndroid Build Coastguard Worker * but does not require it.
754*cc02d7e2SAndroid Build Coastguard Worker * Any 32-bit and 64-bit targets that can run XXH32 smoothly
755*cc02d7e2SAndroid Build Coastguard Worker * can run XXH3 at competitive speeds, even without vector support.
756*cc02d7e2SAndroid Build Coastguard Worker * Further details are explained in the implementation.
757*cc02d7e2SAndroid Build Coastguard Worker *
758*cc02d7e2SAndroid Build Coastguard Worker * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
759*cc02d7e2SAndroid Build Coastguard Worker * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro.
760*cc02d7e2SAndroid Build Coastguard Worker *
761*cc02d7e2SAndroid Build Coastguard Worker * XXH3 implementation is portable:
762*cc02d7e2SAndroid Build Coastguard Worker * it has a generic C90 formulation that can be compiled on any platform,
763*cc02d7e2SAndroid Build Coastguard Worker * all implementations generage exactly the same hash value on all platforms.
764*cc02d7e2SAndroid Build Coastguard Worker * Starting from v0.8.0, it's also labelled "stable", meaning that
765*cc02d7e2SAndroid Build Coastguard Worker * any future version will also generate the same hash value.
766*cc02d7e2SAndroid Build Coastguard Worker *
767*cc02d7e2SAndroid Build Coastguard Worker * XXH3 offers 2 variants, _64bits and _128bits.
768*cc02d7e2SAndroid Build Coastguard Worker *
769*cc02d7e2SAndroid Build Coastguard Worker * When only 64 bits are needed, prefer invoking the _64bits variant, as it
770*cc02d7e2SAndroid Build Coastguard Worker * reduces the amount of mixing, resulting in faster speed on small inputs.
771*cc02d7e2SAndroid Build Coastguard Worker * It's also generally simpler to manipulate a scalar return type than a struct.
772*cc02d7e2SAndroid Build Coastguard Worker *
773*cc02d7e2SAndroid Build Coastguard Worker * The API supports one-shot hashing, streaming mode, and custom secrets.
774*cc02d7e2SAndroid Build Coastguard Worker */
775*cc02d7e2SAndroid Build Coastguard Worker
776*cc02d7e2SAndroid Build Coastguard Worker /*-**********************************************************************
777*cc02d7e2SAndroid Build Coastguard Worker * XXH3 64-bit variant
778*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************/
779*cc02d7e2SAndroid Build Coastguard Worker
780*cc02d7e2SAndroid Build Coastguard Worker /* XXH3_64bits():
781*cc02d7e2SAndroid Build Coastguard Worker * default 64-bit variant, using default secret and default seed of 0.
782*cc02d7e2SAndroid Build Coastguard Worker * It's the fastest variant. */
783*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
784*cc02d7e2SAndroid Build Coastguard Worker
785*cc02d7e2SAndroid Build Coastguard Worker /*
786*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_withSeed():
787*cc02d7e2SAndroid Build Coastguard Worker * This variant generates a custom secret on the fly
788*cc02d7e2SAndroid Build Coastguard Worker * based on default secret altered using the `seed` value.
789*cc02d7e2SAndroid Build Coastguard Worker * While this operation is decently fast, note that it's not completely free.
790*cc02d7e2SAndroid Build Coastguard Worker * Note: seed==0 produces the same results as XXH3_64bits().
791*cc02d7e2SAndroid Build Coastguard Worker */
792*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
793*cc02d7e2SAndroid Build Coastguard Worker
794*cc02d7e2SAndroid Build Coastguard Worker /*!
795*cc02d7e2SAndroid Build Coastguard Worker * The bare minimum size for a custom secret.
796*cc02d7e2SAndroid Build Coastguard Worker *
797*cc02d7e2SAndroid Build Coastguard Worker * @see
798*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(),
799*cc02d7e2SAndroid Build Coastguard Worker * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret().
800*cc02d7e2SAndroid Build Coastguard Worker */
801*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_SECRET_SIZE_MIN 136
802*cc02d7e2SAndroid Build Coastguard Worker
803*cc02d7e2SAndroid Build Coastguard Worker /*
804*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_withSecret():
805*cc02d7e2SAndroid Build Coastguard Worker * It's possible to provide any blob of bytes as a "secret" to generate the hash.
806*cc02d7e2SAndroid Build Coastguard Worker * This makes it more difficult for an external actor to prepare an intentional collision.
807*cc02d7e2SAndroid Build Coastguard Worker * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
808*cc02d7e2SAndroid Build Coastguard Worker * However, the quality of the secret impacts the dispersion of the hash algorithm.
809*cc02d7e2SAndroid Build Coastguard Worker * Therefore, the secret _must_ look like a bunch of random bytes.
810*cc02d7e2SAndroid Build Coastguard Worker * Avoid "trivial" or structured data such as repeated sequences or a text document.
811*cc02d7e2SAndroid Build Coastguard Worker * Whenever in doubt about the "randomness" of the blob of bytes,
812*cc02d7e2SAndroid Build Coastguard Worker * consider employing "XXH3_generateSecret()" instead (see below).
813*cc02d7e2SAndroid Build Coastguard Worker * It will generate a proper high entropy secret derived from the blob of bytes.
814*cc02d7e2SAndroid Build Coastguard Worker * Another advantage of using XXH3_generateSecret() is that
815*cc02d7e2SAndroid Build Coastguard Worker * it guarantees that all bits within the initial blob of bytes
816*cc02d7e2SAndroid Build Coastguard Worker * will impact every bit of the output.
817*cc02d7e2SAndroid Build Coastguard Worker * This is not necessarily the case when using the blob of bytes directly
818*cc02d7e2SAndroid Build Coastguard Worker * because, when hashing _small_ inputs, only a portion of the secret is employed.
819*cc02d7e2SAndroid Build Coastguard Worker */
820*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
821*cc02d7e2SAndroid Build Coastguard Worker
822*cc02d7e2SAndroid Build Coastguard Worker
823*cc02d7e2SAndroid Build Coastguard Worker /******* Streaming *******/
824*cc02d7e2SAndroid Build Coastguard Worker /*
825*cc02d7e2SAndroid Build Coastguard Worker * Streaming requires state maintenance.
826*cc02d7e2SAndroid Build Coastguard Worker * This operation costs memory and CPU.
827*cc02d7e2SAndroid Build Coastguard Worker * As a consequence, streaming is slower than one-shot hashing.
828*cc02d7e2SAndroid Build Coastguard Worker * For better performance, prefer one-shot functions whenever applicable.
829*cc02d7e2SAndroid Build Coastguard Worker */
830*cc02d7e2SAndroid Build Coastguard Worker
831*cc02d7e2SAndroid Build Coastguard Worker /*!
832*cc02d7e2SAndroid Build Coastguard Worker * @brief The state struct for the XXH3 streaming API.
833*cc02d7e2SAndroid Build Coastguard Worker *
834*cc02d7e2SAndroid Build Coastguard Worker * @see XXH3_state_s for details.
835*cc02d7e2SAndroid Build Coastguard Worker */
836*cc02d7e2SAndroid Build Coastguard Worker typedef struct XXH3_state_s XXH3_state_t;
837*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);
838*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
839*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
840*cc02d7e2SAndroid Build Coastguard Worker
841*cc02d7e2SAndroid Build Coastguard Worker /*
842*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_reset():
843*cc02d7e2SAndroid Build Coastguard Worker * Initialize with default parameters.
844*cc02d7e2SAndroid Build Coastguard Worker * digest will be equivalent to `XXH3_64bits()`.
845*cc02d7e2SAndroid Build Coastguard Worker */
846*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
847*cc02d7e2SAndroid Build Coastguard Worker /*
848*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_reset_withSeed():
849*cc02d7e2SAndroid Build Coastguard Worker * Generate a custom secret from `seed`, and store it into `statePtr`.
850*cc02d7e2SAndroid Build Coastguard Worker * digest will be equivalent to `XXH3_64bits_withSeed()`.
851*cc02d7e2SAndroid Build Coastguard Worker */
852*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
853*cc02d7e2SAndroid Build Coastguard Worker /*
854*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_reset_withSecret():
855*cc02d7e2SAndroid Build Coastguard Worker * `secret` is referenced, it _must outlive_ the hash streaming session.
856*cc02d7e2SAndroid Build Coastguard Worker * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
857*cc02d7e2SAndroid Build Coastguard Worker * and the quality of produced hash values depends on secret's entropy
858*cc02d7e2SAndroid Build Coastguard Worker * (secret's content should look like a bunch of random bytes).
859*cc02d7e2SAndroid Build Coastguard Worker * When in doubt about the randomness of a candidate `secret`,
860*cc02d7e2SAndroid Build Coastguard Worker * consider employing `XXH3_generateSecret()` instead (see below).
861*cc02d7e2SAndroid Build Coastguard Worker */
862*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
863*cc02d7e2SAndroid Build Coastguard Worker
864*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
865*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
866*cc02d7e2SAndroid Build Coastguard Worker
867*cc02d7e2SAndroid Build Coastguard Worker /* note : canonical representation of XXH3 is the same as XXH64
868*cc02d7e2SAndroid Build Coastguard Worker * since they both produce XXH64_hash_t values */
869*cc02d7e2SAndroid Build Coastguard Worker
870*cc02d7e2SAndroid Build Coastguard Worker
871*cc02d7e2SAndroid Build Coastguard Worker /*-**********************************************************************
872*cc02d7e2SAndroid Build Coastguard Worker * XXH3 128-bit variant
873*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************/
874*cc02d7e2SAndroid Build Coastguard Worker
875*cc02d7e2SAndroid Build Coastguard Worker /*!
876*cc02d7e2SAndroid Build Coastguard Worker * @brief The return value from 128-bit hashes.
877*cc02d7e2SAndroid Build Coastguard Worker *
878*cc02d7e2SAndroid Build Coastguard Worker * Stored in little endian order, although the fields themselves are in native
879*cc02d7e2SAndroid Build Coastguard Worker * endianness.
880*cc02d7e2SAndroid Build Coastguard Worker */
881*cc02d7e2SAndroid Build Coastguard Worker typedef struct {
882*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */
883*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t high64; /*!< `value >> 64` */
884*cc02d7e2SAndroid Build Coastguard Worker } XXH128_hash_t;
885*cc02d7e2SAndroid Build Coastguard Worker
886*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);
887*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
888*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
889*cc02d7e2SAndroid Build Coastguard Worker
890*cc02d7e2SAndroid Build Coastguard Worker /******* Streaming *******/
891*cc02d7e2SAndroid Build Coastguard Worker /*
892*cc02d7e2SAndroid Build Coastguard Worker * Streaming requires state maintenance.
893*cc02d7e2SAndroid Build Coastguard Worker * This operation costs memory and CPU.
894*cc02d7e2SAndroid Build Coastguard Worker * As a consequence, streaming is slower than one-shot hashing.
895*cc02d7e2SAndroid Build Coastguard Worker * For better performance, prefer one-shot functions whenever applicable.
896*cc02d7e2SAndroid Build Coastguard Worker *
897*cc02d7e2SAndroid Build Coastguard Worker * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits().
898*cc02d7e2SAndroid Build Coastguard Worker * Use already declared XXH3_createState() and XXH3_freeState().
899*cc02d7e2SAndroid Build Coastguard Worker *
900*cc02d7e2SAndroid Build Coastguard Worker * All reset and streaming functions have same meaning as their 64-bit counterpart.
901*cc02d7e2SAndroid Build Coastguard Worker */
902*cc02d7e2SAndroid Build Coastguard Worker
903*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr);
904*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
905*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
906*cc02d7e2SAndroid Build Coastguard Worker
907*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
908*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
909*cc02d7e2SAndroid Build Coastguard Worker
910*cc02d7e2SAndroid Build Coastguard Worker /* Following helper functions make it possible to compare XXH128_hast_t values.
911*cc02d7e2SAndroid Build Coastguard Worker * Since XXH128_hash_t is a structure, this capability is not offered by the language.
912*cc02d7e2SAndroid Build Coastguard Worker * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */
913*cc02d7e2SAndroid Build Coastguard Worker
914*cc02d7e2SAndroid Build Coastguard Worker /*!
915*cc02d7e2SAndroid Build Coastguard Worker * XXH128_isEqual():
916*cc02d7e2SAndroid Build Coastguard Worker * Return: 1 if `h1` and `h2` are equal, 0 if they are not.
917*cc02d7e2SAndroid Build Coastguard Worker */
918*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
919*cc02d7e2SAndroid Build Coastguard Worker
920*cc02d7e2SAndroid Build Coastguard Worker /*!
921*cc02d7e2SAndroid Build Coastguard Worker * XXH128_cmp():
922*cc02d7e2SAndroid Build Coastguard Worker *
923*cc02d7e2SAndroid Build Coastguard Worker * This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
924*cc02d7e2SAndroid Build Coastguard Worker *
925*cc02d7e2SAndroid Build Coastguard Worker * return: >0 if *h128_1 > *h128_2
926*cc02d7e2SAndroid Build Coastguard Worker * =0 if *h128_1 == *h128_2
927*cc02d7e2SAndroid Build Coastguard Worker * <0 if *h128_1 < *h128_2
928*cc02d7e2SAndroid Build Coastguard Worker */
929*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
930*cc02d7e2SAndroid Build Coastguard Worker
931*cc02d7e2SAndroid Build Coastguard Worker
932*cc02d7e2SAndroid Build Coastguard Worker /******* Canonical representation *******/
933*cc02d7e2SAndroid Build Coastguard Worker typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
934*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
935*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
936*cc02d7e2SAndroid Build Coastguard Worker
937*cc02d7e2SAndroid Build Coastguard Worker
938*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_NO_LONG_LONG */
939*cc02d7e2SAndroid Build Coastguard Worker
940*cc02d7e2SAndroid Build Coastguard Worker /*!
941*cc02d7e2SAndroid Build Coastguard Worker * @}
942*cc02d7e2SAndroid Build Coastguard Worker */
943*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXHASH_H_5627135585666179 */
944*cc02d7e2SAndroid Build Coastguard Worker
945*cc02d7e2SAndroid Build Coastguard Worker
946*cc02d7e2SAndroid Build Coastguard Worker
947*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)
948*cc02d7e2SAndroid Build Coastguard Worker #define XXHASH_H_STATIC_13879238742
949*cc02d7e2SAndroid Build Coastguard Worker /* ****************************************************************************
950*cc02d7e2SAndroid Build Coastguard Worker * This section contains declarations which are not guaranteed to remain stable.
951*cc02d7e2SAndroid Build Coastguard Worker * They may change in future versions, becoming incompatible with a different
952*cc02d7e2SAndroid Build Coastguard Worker * version of the library.
953*cc02d7e2SAndroid Build Coastguard Worker * These declarations should only be used with static linking.
954*cc02d7e2SAndroid Build Coastguard Worker * Never use them in association with dynamic linking!
955*cc02d7e2SAndroid Build Coastguard Worker ***************************************************************************** */
956*cc02d7e2SAndroid Build Coastguard Worker
957*cc02d7e2SAndroid Build Coastguard Worker /*
958*cc02d7e2SAndroid Build Coastguard Worker * These definitions are only present to allow static allocation
959*cc02d7e2SAndroid Build Coastguard Worker * of XXH states, on stack or in a struct, for example.
960*cc02d7e2SAndroid Build Coastguard Worker * Never **ever** access their members directly.
961*cc02d7e2SAndroid Build Coastguard Worker */
962*cc02d7e2SAndroid Build Coastguard Worker
963*cc02d7e2SAndroid Build Coastguard Worker /*!
964*cc02d7e2SAndroid Build Coastguard Worker * @internal
965*cc02d7e2SAndroid Build Coastguard Worker * @brief Structure for XXH32 streaming API.
966*cc02d7e2SAndroid Build Coastguard Worker *
967*cc02d7e2SAndroid Build Coastguard Worker * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
968*cc02d7e2SAndroid Build Coastguard Worker * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
969*cc02d7e2SAndroid Build Coastguard Worker * an opaque type. This allows fields to safely be changed.
970*cc02d7e2SAndroid Build Coastguard Worker *
971*cc02d7e2SAndroid Build Coastguard Worker * Typedef'd to @ref XXH32_state_t.
972*cc02d7e2SAndroid Build Coastguard Worker * Do not access the members of this struct directly.
973*cc02d7e2SAndroid Build Coastguard Worker * @see XXH64_state_s, XXH3_state_s
974*cc02d7e2SAndroid Build Coastguard Worker */
975*cc02d7e2SAndroid Build Coastguard Worker struct XXH32_state_s {
976*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */
977*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */
978*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t v[4]; /*!< Accumulator lanes */
979*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */
980*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */
981*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t reserved; /*!< Reserved field. Do not read or write to it, it may be removed. */
982*cc02d7e2SAndroid Build Coastguard Worker }; /* typedef'd to XXH32_state_t */
983*cc02d7e2SAndroid Build Coastguard Worker
984*cc02d7e2SAndroid Build Coastguard Worker
985*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */
986*cc02d7e2SAndroid Build Coastguard Worker
987*cc02d7e2SAndroid Build Coastguard Worker /*!
988*cc02d7e2SAndroid Build Coastguard Worker * @internal
989*cc02d7e2SAndroid Build Coastguard Worker * @brief Structure for XXH64 streaming API.
990*cc02d7e2SAndroid Build Coastguard Worker *
991*cc02d7e2SAndroid Build Coastguard Worker * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
992*cc02d7e2SAndroid Build Coastguard Worker * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
993*cc02d7e2SAndroid Build Coastguard Worker * an opaque type. This allows fields to safely be changed.
994*cc02d7e2SAndroid Build Coastguard Worker *
995*cc02d7e2SAndroid Build Coastguard Worker * Typedef'd to @ref XXH64_state_t.
996*cc02d7e2SAndroid Build Coastguard Worker * Do not access the members of this struct directly.
997*cc02d7e2SAndroid Build Coastguard Worker * @see XXH32_state_s, XXH3_state_s
998*cc02d7e2SAndroid Build Coastguard Worker */
999*cc02d7e2SAndroid Build Coastguard Worker struct XXH64_state_s {
1000*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */
1001*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t v[4]; /*!< Accumulator lanes */
1002*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */
1003*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */
1004*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/
1005*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it, it may be removed. */
1006*cc02d7e2SAndroid Build Coastguard Worker }; /* typedef'd to XXH64_state_t */
1007*cc02d7e2SAndroid Build Coastguard Worker
1008*cc02d7e2SAndroid Build Coastguard Worker #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
1009*cc02d7e2SAndroid Build Coastguard Worker # include <stdalign.h>
1010*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN(n) alignas(n)
1011*cc02d7e2SAndroid Build Coastguard Worker #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
1012*cc02d7e2SAndroid Build Coastguard Worker /* In C++ alignas() is a keyword */
1013*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN(n) alignas(n)
1014*cc02d7e2SAndroid Build Coastguard Worker #elif defined(__GNUC__)
1015*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN(n) __attribute__ ((aligned(n)))
1016*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
1017*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN(n) __declspec(align(n))
1018*cc02d7e2SAndroid Build Coastguard Worker #else
1019*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN(n) /* disabled */
1020*cc02d7e2SAndroid Build Coastguard Worker #endif
1021*cc02d7e2SAndroid Build Coastguard Worker
1022*cc02d7e2SAndroid Build Coastguard Worker /* Old GCC versions only accept the attribute after the type in structures. */
1023*cc02d7e2SAndroid Build Coastguard Worker #if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \
1024*cc02d7e2SAndroid Build Coastguard Worker && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \
1025*cc02d7e2SAndroid Build Coastguard Worker && defined(__GNUC__)
1026*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
1027*cc02d7e2SAndroid Build Coastguard Worker #else
1028*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type
1029*cc02d7e2SAndroid Build Coastguard Worker #endif
1030*cc02d7e2SAndroid Build Coastguard Worker
1031*cc02d7e2SAndroid Build Coastguard Worker /*!
1032*cc02d7e2SAndroid Build Coastguard Worker * @brief The size of the internal XXH3 buffer.
1033*cc02d7e2SAndroid Build Coastguard Worker *
1034*cc02d7e2SAndroid Build Coastguard Worker * This is the optimal update size for incremental hashing.
1035*cc02d7e2SAndroid Build Coastguard Worker *
1036*cc02d7e2SAndroid Build Coastguard Worker * @see XXH3_64b_update(), XXH3_128b_update().
1037*cc02d7e2SAndroid Build Coastguard Worker */
1038*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_INTERNALBUFFER_SIZE 256
1039*cc02d7e2SAndroid Build Coastguard Worker
1040*cc02d7e2SAndroid Build Coastguard Worker /*!
1041*cc02d7e2SAndroid Build Coastguard Worker * @brief Default size of the secret buffer (and @ref XXH3_kSecret).
1042*cc02d7e2SAndroid Build Coastguard Worker *
1043*cc02d7e2SAndroid Build Coastguard Worker * This is the size used in @ref XXH3_kSecret and the seeded functions.
1044*cc02d7e2SAndroid Build Coastguard Worker *
1045*cc02d7e2SAndroid Build Coastguard Worker * Not to be confused with @ref XXH3_SECRET_SIZE_MIN.
1046*cc02d7e2SAndroid Build Coastguard Worker */
1047*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_SECRET_DEFAULT_SIZE 192
1048*cc02d7e2SAndroid Build Coastguard Worker
1049*cc02d7e2SAndroid Build Coastguard Worker /*!
1050*cc02d7e2SAndroid Build Coastguard Worker * @internal
1051*cc02d7e2SAndroid Build Coastguard Worker * @brief Structure for XXH3 streaming API.
1052*cc02d7e2SAndroid Build Coastguard Worker *
1053*cc02d7e2SAndroid Build Coastguard Worker * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
1054*cc02d7e2SAndroid Build Coastguard Worker * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined.
1055*cc02d7e2SAndroid Build Coastguard Worker * Otherwise it is an opaque type.
1056*cc02d7e2SAndroid Build Coastguard Worker * Never use this definition in combination with dynamic library.
1057*cc02d7e2SAndroid Build Coastguard Worker * This allows fields to safely be changed in the future.
1058*cc02d7e2SAndroid Build Coastguard Worker *
1059*cc02d7e2SAndroid Build Coastguard Worker * @note ** This structure has a strict alignment requirement of 64 bytes!! **
1060*cc02d7e2SAndroid Build Coastguard Worker * Do not allocate this with `malloc()` or `new`,
1061*cc02d7e2SAndroid Build Coastguard Worker * it will not be sufficiently aligned.
1062*cc02d7e2SAndroid Build Coastguard Worker * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation.
1063*cc02d7e2SAndroid Build Coastguard Worker *
1064*cc02d7e2SAndroid Build Coastguard Worker * Typedef'd to @ref XXH3_state_t.
1065*cc02d7e2SAndroid Build Coastguard Worker * Do never access the members of this struct directly.
1066*cc02d7e2SAndroid Build Coastguard Worker *
1067*cc02d7e2SAndroid Build Coastguard Worker * @see XXH3_INITSTATE() for stack initialization.
1068*cc02d7e2SAndroid Build Coastguard Worker * @see XXH3_createState(), XXH3_freeState().
1069*cc02d7e2SAndroid Build Coastguard Worker * @see XXH32_state_s, XXH64_state_s
1070*cc02d7e2SAndroid Build Coastguard Worker */
1071*cc02d7e2SAndroid Build Coastguard Worker struct XXH3_state_s {
1072*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
1073*cc02d7e2SAndroid Build Coastguard Worker /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */
1074*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
1075*cc02d7e2SAndroid Build Coastguard Worker /*!< Used to store a custom secret generated from a seed. */
1076*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
1077*cc02d7e2SAndroid Build Coastguard Worker /*!< The internal buffer. @see XXH32_state_s::mem32 */
1078*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t bufferedSize;
1079*cc02d7e2SAndroid Build Coastguard Worker /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */
1080*cc02d7e2SAndroid Build Coastguard Worker XXH32_hash_t useSeed;
1081*cc02d7e2SAndroid Build Coastguard Worker /*!< Reserved field. Needed for padding on 64-bit. */
1082*cc02d7e2SAndroid Build Coastguard Worker size_t nbStripesSoFar;
1083*cc02d7e2SAndroid Build Coastguard Worker /*!< Number or stripes processed. */
1084*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t totalLen;
1085*cc02d7e2SAndroid Build Coastguard Worker /*!< Total length hashed. 64-bit even on 32-bit targets. */
1086*cc02d7e2SAndroid Build Coastguard Worker size_t nbStripesPerBlock;
1087*cc02d7e2SAndroid Build Coastguard Worker /*!< Number of stripes per block. */
1088*cc02d7e2SAndroid Build Coastguard Worker size_t secretLimit;
1089*cc02d7e2SAndroid Build Coastguard Worker /*!< Size of @ref customSecret or @ref extSecret */
1090*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed;
1091*cc02d7e2SAndroid Build Coastguard Worker /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */
1092*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t reserved64;
1093*cc02d7e2SAndroid Build Coastguard Worker /*!< Reserved field. */
1094*cc02d7e2SAndroid Build Coastguard Worker const unsigned char* extSecret;
1095*cc02d7e2SAndroid Build Coastguard Worker /*!< Reference to an external secret for the _withSecret variants, NULL
1096*cc02d7e2SAndroid Build Coastguard Worker * for other variants. */
1097*cc02d7e2SAndroid Build Coastguard Worker /* note: there may be some padding at the end due to alignment on 64 bytes */
1098*cc02d7e2SAndroid Build Coastguard Worker }; /* typedef'd to XXH3_state_t */
1099*cc02d7e2SAndroid Build Coastguard Worker
1100*cc02d7e2SAndroid Build Coastguard Worker #undef XXH_ALIGN_MEMBER
1101*cc02d7e2SAndroid Build Coastguard Worker
1102*cc02d7e2SAndroid Build Coastguard Worker /*!
1103*cc02d7e2SAndroid Build Coastguard Worker * @brief Initializes a stack-allocated `XXH3_state_s`.
1104*cc02d7e2SAndroid Build Coastguard Worker *
1105*cc02d7e2SAndroid Build Coastguard Worker * When the @ref XXH3_state_t structure is merely emplaced on stack,
1106*cc02d7e2SAndroid Build Coastguard Worker * it should be initialized with XXH3_INITSTATE() or a memset()
1107*cc02d7e2SAndroid Build Coastguard Worker * in case its first reset uses XXH3_NNbits_reset_withSeed().
1108*cc02d7e2SAndroid Build Coastguard Worker * This init can be omitted if the first reset uses default or _withSecret mode.
1109*cc02d7e2SAndroid Build Coastguard Worker * This operation isn't necessary when the state is created with XXH3_createState().
1110*cc02d7e2SAndroid Build Coastguard Worker * Note that this doesn't prepare the state for a streaming operation,
1111*cc02d7e2SAndroid Build Coastguard Worker * it's still necessary to use XXH3_NNbits_reset*() afterwards.
1112*cc02d7e2SAndroid Build Coastguard Worker */
1113*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
1114*cc02d7e2SAndroid Build Coastguard Worker
1115*cc02d7e2SAndroid Build Coastguard Worker
1116*cc02d7e2SAndroid Build Coastguard Worker /* XXH128() :
1117*cc02d7e2SAndroid Build Coastguard Worker * simple alias to pre-selected XXH3_128bits variant
1118*cc02d7e2SAndroid Build Coastguard Worker */
1119*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1120*cc02d7e2SAndroid Build Coastguard Worker
1121*cc02d7e2SAndroid Build Coastguard Worker
1122*cc02d7e2SAndroid Build Coastguard Worker /* === Experimental API === */
1123*cc02d7e2SAndroid Build Coastguard Worker /* Symbols defined below must be considered tied to a specific library version. */
1124*cc02d7e2SAndroid Build Coastguard Worker
1125*cc02d7e2SAndroid Build Coastguard Worker /*
1126*cc02d7e2SAndroid Build Coastguard Worker * XXH3_generateSecret():
1127*cc02d7e2SAndroid Build Coastguard Worker *
1128*cc02d7e2SAndroid Build Coastguard Worker * Derive a high-entropy secret from any user-defined content, named customSeed.
1129*cc02d7e2SAndroid Build Coastguard Worker * The generated secret can be used in combination with `*_withSecret()` functions.
1130*cc02d7e2SAndroid Build Coastguard Worker * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,
1131*cc02d7e2SAndroid Build Coastguard Worker * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
1132*cc02d7e2SAndroid Build Coastguard Worker *
1133*cc02d7e2SAndroid Build Coastguard Worker * The function accepts as input a custom seed of any length and any content,
1134*cc02d7e2SAndroid Build Coastguard Worker * and derives from it a high-entropy secret of length @secretSize
1135*cc02d7e2SAndroid Build Coastguard Worker * into an already allocated buffer @secretBuffer.
1136*cc02d7e2SAndroid Build Coastguard Worker * @secretSize must be >= XXH3_SECRET_SIZE_MIN
1137*cc02d7e2SAndroid Build Coastguard Worker *
1138*cc02d7e2SAndroid Build Coastguard Worker * The generated secret can then be used with any `*_withSecret()` variant.
1139*cc02d7e2SAndroid Build Coastguard Worker * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
1140*cc02d7e2SAndroid Build Coastguard Worker * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
1141*cc02d7e2SAndroid Build Coastguard Worker * are part of this list. They all accept a `secret` parameter
1142*cc02d7e2SAndroid Build Coastguard Worker * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
1143*cc02d7e2SAndroid Build Coastguard Worker * _and_ feature very high entropy (consist of random-looking bytes).
1144*cc02d7e2SAndroid Build Coastguard Worker * These conditions can be a high bar to meet, so
1145*cc02d7e2SAndroid Build Coastguard Worker * XXH3_generateSecret() can be employed to ensure proper quality.
1146*cc02d7e2SAndroid Build Coastguard Worker *
1147*cc02d7e2SAndroid Build Coastguard Worker * customSeed can be anything. It can have any size, even small ones,
1148*cc02d7e2SAndroid Build Coastguard Worker * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
1149*cc02d7e2SAndroid Build Coastguard Worker * The resulting `secret` will nonetheless provide all required qualities.
1150*cc02d7e2SAndroid Build Coastguard Worker *
1151*cc02d7e2SAndroid Build Coastguard Worker * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
1152*cc02d7e2SAndroid Build Coastguard Worker */
1153*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
1154*cc02d7e2SAndroid Build Coastguard Worker
1155*cc02d7e2SAndroid Build Coastguard Worker
1156*cc02d7e2SAndroid Build Coastguard Worker /*
1157*cc02d7e2SAndroid Build Coastguard Worker * XXH3_generateSecret_fromSeed():
1158*cc02d7e2SAndroid Build Coastguard Worker *
1159*cc02d7e2SAndroid Build Coastguard Worker * Generate the same secret as the _withSeed() variants.
1160*cc02d7e2SAndroid Build Coastguard Worker *
1161*cc02d7e2SAndroid Build Coastguard Worker * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
1162*cc02d7e2SAndroid Build Coastguard Worker * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
1163*cc02d7e2SAndroid Build Coastguard Worker *
1164*cc02d7e2SAndroid Build Coastguard Worker * The generated secret can be used in combination with
1165*cc02d7e2SAndroid Build Coastguard Worker *`*_withSecret()` and `_withSecretandSeed()` variants.
1166*cc02d7e2SAndroid Build Coastguard Worker * This generator is notably useful in combination with `_withSecretandSeed()`,
1167*cc02d7e2SAndroid Build Coastguard Worker * as a way to emulate a faster `_withSeed()` variant.
1168*cc02d7e2SAndroid Build Coastguard Worker */
1169*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
1170*cc02d7e2SAndroid Build Coastguard Worker
1171*cc02d7e2SAndroid Build Coastguard Worker /*
1172*cc02d7e2SAndroid Build Coastguard Worker * *_withSecretandSeed() :
1173*cc02d7e2SAndroid Build Coastguard Worker * These variants generate hash values using either
1174*cc02d7e2SAndroid Build Coastguard Worker * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1175*cc02d7e2SAndroid Build Coastguard Worker * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
1176*cc02d7e2SAndroid Build Coastguard Worker *
1177*cc02d7e2SAndroid Build Coastguard Worker * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
1178*cc02d7e2SAndroid Build Coastguard Worker * `_withSeed()` has to generate the secret on the fly for "large" keys.
1179*cc02d7e2SAndroid Build Coastguard Worker * It's fast, but can be perceptible for "not so large" keys (< 1 KB).
1180*cc02d7e2SAndroid Build Coastguard Worker * `_withSecret()` has to generate the masks on the fly for "small" keys,
1181*cc02d7e2SAndroid Build Coastguard Worker * which requires more instructions than _withSeed() variants.
1182*cc02d7e2SAndroid Build Coastguard Worker * Therefore, _withSecretandSeed variant combines the best of both worlds.
1183*cc02d7e2SAndroid Build Coastguard Worker *
1184*cc02d7e2SAndroid Build Coastguard Worker * When @secret has been generated by XXH3_generateSecret_fromSeed(),
1185*cc02d7e2SAndroid Build Coastguard Worker * this variant produces *exactly* the same results as `_withSeed()` variant,
1186*cc02d7e2SAndroid Build Coastguard Worker * hence offering only a pure speed benefit on "large" input,
1187*cc02d7e2SAndroid Build Coastguard Worker * by skipping the need to regenerate the secret for every large input.
1188*cc02d7e2SAndroid Build Coastguard Worker *
1189*cc02d7e2SAndroid Build Coastguard Worker * Another usage scenario is to hash the secret to a 64-bit hash value,
1190*cc02d7e2SAndroid Build Coastguard Worker * for example with XXH3_64bits(), which then becomes the seed,
1191*cc02d7e2SAndroid Build Coastguard Worker * and then employ both the seed and the secret in _withSecretandSeed().
1192*cc02d7e2SAndroid Build Coastguard Worker * On top of speed, an added benefit is that each bit in the secret
1193*cc02d7e2SAndroid Build Coastguard Worker * has a 50% chance to swap each bit in the output,
1194*cc02d7e2SAndroid Build Coastguard Worker * via its impact to the seed.
1195*cc02d7e2SAndroid Build Coastguard Worker * This is not guaranteed when using the secret directly in "small data" scenarios,
1196*cc02d7e2SAndroid Build Coastguard Worker * because only portions of the secret are employed for small data.
1197*cc02d7e2SAndroid Build Coastguard Worker */
1198*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t
1199*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_withSecretandSeed(const void* data, size_t len,
1200*cc02d7e2SAndroid Build Coastguard Worker const void* secret, size_t secretSize,
1201*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed);
1202*cc02d7e2SAndroid Build Coastguard Worker
1203*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
1204*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_withSecretandSeed(const void* data, size_t len,
1205*cc02d7e2SAndroid Build Coastguard Worker const void* secret, size_t secretSize,
1206*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64);
1207*cc02d7e2SAndroid Build Coastguard Worker
1208*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
1209*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1210*cc02d7e2SAndroid Build Coastguard Worker const void* secret, size_t secretSize,
1211*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64);
1212*cc02d7e2SAndroid Build Coastguard Worker
1213*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
1214*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1215*cc02d7e2SAndroid Build Coastguard Worker const void* secret, size_t secretSize,
1216*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64);
1217*cc02d7e2SAndroid Build Coastguard Worker
1218*cc02d7e2SAndroid Build Coastguard Worker
1219*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_NO_LONG_LONG */
1220*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
1221*cc02d7e2SAndroid Build Coastguard Worker # define XXH_IMPLEMENTATION
1222*cc02d7e2SAndroid Build Coastguard Worker #endif
1223*cc02d7e2SAndroid Build Coastguard Worker
1224*cc02d7e2SAndroid Build Coastguard Worker #endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */
1225*cc02d7e2SAndroid Build Coastguard Worker
1226*cc02d7e2SAndroid Build Coastguard Worker
1227*cc02d7e2SAndroid Build Coastguard Worker /* ======================================================================== */
1228*cc02d7e2SAndroid Build Coastguard Worker /* ======================================================================== */
1229*cc02d7e2SAndroid Build Coastguard Worker /* ======================================================================== */
1230*cc02d7e2SAndroid Build Coastguard Worker
1231*cc02d7e2SAndroid Build Coastguard Worker
1232*cc02d7e2SAndroid Build Coastguard Worker /*-**********************************************************************
1233*cc02d7e2SAndroid Build Coastguard Worker * xxHash implementation
1234*cc02d7e2SAndroid Build Coastguard Worker *-**********************************************************************
1235*cc02d7e2SAndroid Build Coastguard Worker * xxHash's implementation used to be hosted inside xxhash.c.
1236*cc02d7e2SAndroid Build Coastguard Worker *
1237*cc02d7e2SAndroid Build Coastguard Worker * However, inlining requires implementation to be visible to the compiler,
1238*cc02d7e2SAndroid Build Coastguard Worker * hence be included alongside the header.
1239*cc02d7e2SAndroid Build Coastguard Worker * Previously, implementation was hosted inside xxhash.c,
1240*cc02d7e2SAndroid Build Coastguard Worker * which was then #included when inlining was activated.
1241*cc02d7e2SAndroid Build Coastguard Worker * This construction created issues with a few build and install systems,
1242*cc02d7e2SAndroid Build Coastguard Worker * as it required xxhash.c to be stored in /include directory.
1243*cc02d7e2SAndroid Build Coastguard Worker *
1244*cc02d7e2SAndroid Build Coastguard Worker * xxHash implementation is now directly integrated within xxhash.h.
1245*cc02d7e2SAndroid Build Coastguard Worker * As a consequence, xxhash.c is no longer needed in /include.
1246*cc02d7e2SAndroid Build Coastguard Worker *
1247*cc02d7e2SAndroid Build Coastguard Worker * xxhash.c is still available and is still useful.
1248*cc02d7e2SAndroid Build Coastguard Worker * In a "normal" setup, when xxhash is not inlined,
1249*cc02d7e2SAndroid Build Coastguard Worker * xxhash.h only exposes the prototypes and public symbols,
1250*cc02d7e2SAndroid Build Coastguard Worker * while xxhash.c can be built into an object file xxhash.o
1251*cc02d7e2SAndroid Build Coastguard Worker * which can then be linked into the final binary.
1252*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************/
1253*cc02d7e2SAndroid Build Coastguard Worker
1254*cc02d7e2SAndroid Build Coastguard Worker #if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \
1255*cc02d7e2SAndroid Build Coastguard Worker || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)
1256*cc02d7e2SAndroid Build Coastguard Worker # define XXH_IMPLEM_13a8737387
1257*cc02d7e2SAndroid Build Coastguard Worker
1258*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1259*cc02d7e2SAndroid Build Coastguard Worker * Tuning parameters
1260*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1261*cc02d7e2SAndroid Build Coastguard Worker
1262*cc02d7e2SAndroid Build Coastguard Worker /*!
1263*cc02d7e2SAndroid Build Coastguard Worker * @defgroup tuning Tuning parameters
1264*cc02d7e2SAndroid Build Coastguard Worker * @{
1265*cc02d7e2SAndroid Build Coastguard Worker *
1266*cc02d7e2SAndroid Build Coastguard Worker * Various macros to control xxHash's behavior.
1267*cc02d7e2SAndroid Build Coastguard Worker */
1268*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_DOXYGEN
1269*cc02d7e2SAndroid Build Coastguard Worker /*!
1270*cc02d7e2SAndroid Build Coastguard Worker * @brief Define this to disable 64-bit code.
1271*cc02d7e2SAndroid Build Coastguard Worker *
1272*cc02d7e2SAndroid Build Coastguard Worker * Useful if only using the @ref xxh32_family and you have a strict C90 compiler.
1273*cc02d7e2SAndroid Build Coastguard Worker */
1274*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_LONG_LONG
1275*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_NO_LONG_LONG /* don't actually */
1276*cc02d7e2SAndroid Build Coastguard Worker /*!
1277*cc02d7e2SAndroid Build Coastguard Worker * @brief Controls how unaligned memory is accessed.
1278*cc02d7e2SAndroid Build Coastguard Worker *
1279*cc02d7e2SAndroid Build Coastguard Worker * By default, access to unaligned memory is controlled by `memcpy()`, which is
1280*cc02d7e2SAndroid Build Coastguard Worker * safe and portable.
1281*cc02d7e2SAndroid Build Coastguard Worker *
1282*cc02d7e2SAndroid Build Coastguard Worker * Unfortunately, on some target/compiler combinations, the generated assembly
1283*cc02d7e2SAndroid Build Coastguard Worker * is sub-optimal.
1284*cc02d7e2SAndroid Build Coastguard Worker *
1285*cc02d7e2SAndroid Build Coastguard Worker * The below switch allow selection of a different access method
1286*cc02d7e2SAndroid Build Coastguard Worker * in the search for improved performance.
1287*cc02d7e2SAndroid Build Coastguard Worker *
1288*cc02d7e2SAndroid Build Coastguard Worker * @par Possible options:
1289*cc02d7e2SAndroid Build Coastguard Worker *
1290*cc02d7e2SAndroid Build Coastguard Worker * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy`
1291*cc02d7e2SAndroid Build Coastguard Worker * @par
1292*cc02d7e2SAndroid Build Coastguard Worker * Use `memcpy()`. Safe and portable. Note that most modern compilers will
1293*cc02d7e2SAndroid Build Coastguard Worker * eliminate the function call and treat it as an unaligned access.
1294*cc02d7e2SAndroid Build Coastguard Worker *
1295*cc02d7e2SAndroid Build Coastguard Worker * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))`
1296*cc02d7e2SAndroid Build Coastguard Worker * @par
1297*cc02d7e2SAndroid Build Coastguard Worker * Depends on compiler extensions and is therefore not portable.
1298*cc02d7e2SAndroid Build Coastguard Worker * This method is safe _if_ your compiler supports it,
1299*cc02d7e2SAndroid Build Coastguard Worker * and *generally* as fast or faster than `memcpy`.
1300*cc02d7e2SAndroid Build Coastguard Worker *
1301*cc02d7e2SAndroid Build Coastguard Worker * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast
1302*cc02d7e2SAndroid Build Coastguard Worker * @par
1303*cc02d7e2SAndroid Build Coastguard Worker * Casts directly and dereferences. This method doesn't depend on the
1304*cc02d7e2SAndroid Build Coastguard Worker * compiler, but it violates the C standard as it directly dereferences an
1305*cc02d7e2SAndroid Build Coastguard Worker * unaligned pointer. It can generate buggy code on targets which do not
1306*cc02d7e2SAndroid Build Coastguard Worker * support unaligned memory accesses, but in some circumstances, it's the
1307*cc02d7e2SAndroid Build Coastguard Worker * only known way to get the most performance.
1308*cc02d7e2SAndroid Build Coastguard Worker *
1309*cc02d7e2SAndroid Build Coastguard Worker * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift
1310*cc02d7e2SAndroid Build Coastguard Worker * @par
1311*cc02d7e2SAndroid Build Coastguard Worker * Also portable. This can generate the best code on old compilers which don't
1312*cc02d7e2SAndroid Build Coastguard Worker * inline small `memcpy()` calls, and it might also be faster on big-endian
1313*cc02d7e2SAndroid Build Coastguard Worker * systems which lack a native byteswap instruction. However, some compilers
1314*cc02d7e2SAndroid Build Coastguard Worker * will emit literal byteshifts even if the target supports unaligned access.
1315*cc02d7e2SAndroid Build Coastguard Worker * .
1316*cc02d7e2SAndroid Build Coastguard Worker *
1317*cc02d7e2SAndroid Build Coastguard Worker * @warning
1318*cc02d7e2SAndroid Build Coastguard Worker * Methods 1 and 2 rely on implementation-defined behavior. Use these with
1319*cc02d7e2SAndroid Build Coastguard Worker * care, as what works on one compiler/platform/optimization level may cause
1320*cc02d7e2SAndroid Build Coastguard Worker * another to read garbage data or even crash.
1321*cc02d7e2SAndroid Build Coastguard Worker *
1322*cc02d7e2SAndroid Build Coastguard Worker * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details.
1323*cc02d7e2SAndroid Build Coastguard Worker *
1324*cc02d7e2SAndroid Build Coastguard Worker * Prefer these methods in priority order (0 > 3 > 1 > 2)
1325*cc02d7e2SAndroid Build Coastguard Worker */
1326*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_MEMORY_ACCESS 0
1327*cc02d7e2SAndroid Build Coastguard Worker
1328*cc02d7e2SAndroid Build Coastguard Worker /*!
1329*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_FORCE_ALIGN_CHECK
1330*cc02d7e2SAndroid Build Coastguard Worker * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()
1331*cc02d7e2SAndroid Build Coastguard Worker * and XXH64() only).
1332*cc02d7e2SAndroid Build Coastguard Worker *
1333*cc02d7e2SAndroid Build Coastguard Worker * This is an important performance trick for architectures without decent
1334*cc02d7e2SAndroid Build Coastguard Worker * unaligned memory access performance.
1335*cc02d7e2SAndroid Build Coastguard Worker *
1336*cc02d7e2SAndroid Build Coastguard Worker * It checks for input alignment, and when conditions are met, uses a "fast
1337*cc02d7e2SAndroid Build Coastguard Worker * path" employing direct 32-bit/64-bit reads, resulting in _dramatically
1338*cc02d7e2SAndroid Build Coastguard Worker * faster_ read speed.
1339*cc02d7e2SAndroid Build Coastguard Worker *
1340*cc02d7e2SAndroid Build Coastguard Worker * The check costs one initial branch per hash, which is generally negligible,
1341*cc02d7e2SAndroid Build Coastguard Worker * but not zero.
1342*cc02d7e2SAndroid Build Coastguard Worker *
1343*cc02d7e2SAndroid Build Coastguard Worker * Moreover, it's not useful to generate an additional code path if memory
1344*cc02d7e2SAndroid Build Coastguard Worker * access uses the same instruction for both aligned and unaligned
1345*cc02d7e2SAndroid Build Coastguard Worker * addresses (e.g. x86 and aarch64).
1346*cc02d7e2SAndroid Build Coastguard Worker *
1347*cc02d7e2SAndroid Build Coastguard Worker * In these cases, the alignment check can be removed by setting this macro to 0.
1348*cc02d7e2SAndroid Build Coastguard Worker * Then the code will always use unaligned memory access.
1349*cc02d7e2SAndroid Build Coastguard Worker * Align check is automatically disabled on x86, x64 & arm64,
1350*cc02d7e2SAndroid Build Coastguard Worker * which are platforms known to offer good unaligned memory accesses performance.
1351*cc02d7e2SAndroid Build Coastguard Worker *
1352*cc02d7e2SAndroid Build Coastguard Worker * This option does not affect XXH3 (only XXH32 and XXH64).
1353*cc02d7e2SAndroid Build Coastguard Worker */
1354*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_ALIGN_CHECK 0
1355*cc02d7e2SAndroid Build Coastguard Worker
1356*cc02d7e2SAndroid Build Coastguard Worker /*!
1357*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_NO_INLINE_HINTS
1358*cc02d7e2SAndroid Build Coastguard Worker * @brief When non-zero, sets all functions to `static`.
1359*cc02d7e2SAndroid Build Coastguard Worker *
1360*cc02d7e2SAndroid Build Coastguard Worker * By default, xxHash tries to force the compiler to inline almost all internal
1361*cc02d7e2SAndroid Build Coastguard Worker * functions.
1362*cc02d7e2SAndroid Build Coastguard Worker *
1363*cc02d7e2SAndroid Build Coastguard Worker * This can usually improve performance due to reduced jumping and improved
1364*cc02d7e2SAndroid Build Coastguard Worker * constant folding, but significantly increases the size of the binary which
1365*cc02d7e2SAndroid Build Coastguard Worker * might not be favorable.
1366*cc02d7e2SAndroid Build Coastguard Worker *
1367*cc02d7e2SAndroid Build Coastguard Worker * Additionally, sometimes the forced inlining can be detrimental to performance,
1368*cc02d7e2SAndroid Build Coastguard Worker * depending on the architecture.
1369*cc02d7e2SAndroid Build Coastguard Worker *
1370*cc02d7e2SAndroid Build Coastguard Worker * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the
1371*cc02d7e2SAndroid Build Coastguard Worker * compiler full control on whether to inline or not.
1372*cc02d7e2SAndroid Build Coastguard Worker *
1373*cc02d7e2SAndroid Build Coastguard Worker * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using
1374*cc02d7e2SAndroid Build Coastguard Worker * -fno-inline with GCC or Clang, this will automatically be defined.
1375*cc02d7e2SAndroid Build Coastguard Worker */
1376*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE_HINTS 0
1377*cc02d7e2SAndroid Build Coastguard Worker
1378*cc02d7e2SAndroid Build Coastguard Worker /*!
1379*cc02d7e2SAndroid Build Coastguard Worker * @def XXH32_ENDJMP
1380*cc02d7e2SAndroid Build Coastguard Worker * @brief Whether to use a jump for `XXH32_finalize`.
1381*cc02d7e2SAndroid Build Coastguard Worker *
1382*cc02d7e2SAndroid Build Coastguard Worker * For performance, `XXH32_finalize` uses multiple branches in the finalizer.
1383*cc02d7e2SAndroid Build Coastguard Worker * This is generally preferable for performance,
1384*cc02d7e2SAndroid Build Coastguard Worker * but depending on exact architecture, a jmp may be preferable.
1385*cc02d7e2SAndroid Build Coastguard Worker *
1386*cc02d7e2SAndroid Build Coastguard Worker * This setting is only possibly making a difference for very small inputs.
1387*cc02d7e2SAndroid Build Coastguard Worker */
1388*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_ENDJMP 0
1389*cc02d7e2SAndroid Build Coastguard Worker
1390*cc02d7e2SAndroid Build Coastguard Worker /*!
1391*cc02d7e2SAndroid Build Coastguard Worker * @internal
1392*cc02d7e2SAndroid Build Coastguard Worker * @brief Redefines old internal names.
1393*cc02d7e2SAndroid Build Coastguard Worker *
1394*cc02d7e2SAndroid Build Coastguard Worker * For compatibility with code that uses xxHash's internals before the names
1395*cc02d7e2SAndroid Build Coastguard Worker * were changed to improve namespacing. There is no other reason to use this.
1396*cc02d7e2SAndroid Build Coastguard Worker */
1397*cc02d7e2SAndroid Build Coastguard Worker # define XXH_OLD_NAMES
1398*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_OLD_NAMES /* don't actually use, it is ugly. */
1399*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_DOXYGEN */
1400*cc02d7e2SAndroid Build Coastguard Worker /*!
1401*cc02d7e2SAndroid Build Coastguard Worker * @}
1402*cc02d7e2SAndroid Build Coastguard Worker */
1403*cc02d7e2SAndroid Build Coastguard Worker
1404*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
1405*cc02d7e2SAndroid Build Coastguard Worker /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */
1406*cc02d7e2SAndroid Build Coastguard Worker # if !defined(__clang__) && \
1407*cc02d7e2SAndroid Build Coastguard Worker ( \
1408*cc02d7e2SAndroid Build Coastguard Worker (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
1409*cc02d7e2SAndroid Build Coastguard Worker ( \
1410*cc02d7e2SAndroid Build Coastguard Worker defined(__GNUC__) && ( \
1411*cc02d7e2SAndroid Build Coastguard Worker (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
1412*cc02d7e2SAndroid Build Coastguard Worker ( \
1413*cc02d7e2SAndroid Build Coastguard Worker defined(__mips__) && \
1414*cc02d7e2SAndroid Build Coastguard Worker (__mips <= 5 || __mips_isa_rev < 6) && \
1415*cc02d7e2SAndroid Build Coastguard Worker (!defined(__mips16) || defined(__mips_mips16e2)) \
1416*cc02d7e2SAndroid Build Coastguard Worker ) \
1417*cc02d7e2SAndroid Build Coastguard Worker ) \
1418*cc02d7e2SAndroid Build Coastguard Worker ) \
1419*cc02d7e2SAndroid Build Coastguard Worker )
1420*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_MEMORY_ACCESS 1
1421*cc02d7e2SAndroid Build Coastguard Worker # endif
1422*cc02d7e2SAndroid Build Coastguard Worker #endif
1423*cc02d7e2SAndroid Build Coastguard Worker
1424*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
1425*cc02d7e2SAndroid Build Coastguard Worker # if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \
1426*cc02d7e2SAndroid Build Coastguard Worker || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */
1427*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_ALIGN_CHECK 0
1428*cc02d7e2SAndroid Build Coastguard Worker # else
1429*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_ALIGN_CHECK 1
1430*cc02d7e2SAndroid Build Coastguard Worker # endif
1431*cc02d7e2SAndroid Build Coastguard Worker #endif
1432*cc02d7e2SAndroid Build Coastguard Worker
1433*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_NO_INLINE_HINTS
1434*cc02d7e2SAndroid Build Coastguard Worker # if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \
1435*cc02d7e2SAndroid Build Coastguard Worker || defined(__NO_INLINE__) /* -O0, -fno-inline */
1436*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE_HINTS 1
1437*cc02d7e2SAndroid Build Coastguard Worker # else
1438*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE_HINTS 0
1439*cc02d7e2SAndroid Build Coastguard Worker # endif
1440*cc02d7e2SAndroid Build Coastguard Worker #endif
1441*cc02d7e2SAndroid Build Coastguard Worker
1442*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH32_ENDJMP
1443*cc02d7e2SAndroid Build Coastguard Worker /* generally preferable for performance */
1444*cc02d7e2SAndroid Build Coastguard Worker # define XXH32_ENDJMP 0
1445*cc02d7e2SAndroid Build Coastguard Worker #endif
1446*cc02d7e2SAndroid Build Coastguard Worker
1447*cc02d7e2SAndroid Build Coastguard Worker /*!
1448*cc02d7e2SAndroid Build Coastguard Worker * @defgroup impl Implementation
1449*cc02d7e2SAndroid Build Coastguard Worker * @{
1450*cc02d7e2SAndroid Build Coastguard Worker */
1451*cc02d7e2SAndroid Build Coastguard Worker
1452*cc02d7e2SAndroid Build Coastguard Worker
1453*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1454*cc02d7e2SAndroid Build Coastguard Worker * Includes & Memory related functions
1455*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1456*cc02d7e2SAndroid Build Coastguard Worker /*
1457*cc02d7e2SAndroid Build Coastguard Worker * Modify the local functions below should you wish to use
1458*cc02d7e2SAndroid Build Coastguard Worker * different memory routines for malloc() and free()
1459*cc02d7e2SAndroid Build Coastguard Worker */
1460*cc02d7e2SAndroid Build Coastguard Worker #include <stdlib.h>
1461*cc02d7e2SAndroid Build Coastguard Worker
1462*cc02d7e2SAndroid Build Coastguard Worker /*!
1463*cc02d7e2SAndroid Build Coastguard Worker * @internal
1464*cc02d7e2SAndroid Build Coastguard Worker * @brief Modify this function to use a different routine than malloc().
1465*cc02d7e2SAndroid Build Coastguard Worker */
XXH_malloc(size_t s)1466*cc02d7e2SAndroid Build Coastguard Worker static void* XXH_malloc(size_t s) { return malloc(s); }
1467*cc02d7e2SAndroid Build Coastguard Worker
1468*cc02d7e2SAndroid Build Coastguard Worker /*!
1469*cc02d7e2SAndroid Build Coastguard Worker * @internal
1470*cc02d7e2SAndroid Build Coastguard Worker * @brief Modify this function to use a different routine than free().
1471*cc02d7e2SAndroid Build Coastguard Worker */
XXH_free(void * p)1472*cc02d7e2SAndroid Build Coastguard Worker static void XXH_free(void* p) { free(p); }
1473*cc02d7e2SAndroid Build Coastguard Worker
1474*cc02d7e2SAndroid Build Coastguard Worker #include <string.h>
1475*cc02d7e2SAndroid Build Coastguard Worker
1476*cc02d7e2SAndroid Build Coastguard Worker /*!
1477*cc02d7e2SAndroid Build Coastguard Worker * @internal
1478*cc02d7e2SAndroid Build Coastguard Worker * @brief Modify this function to use a different routine than memcpy().
1479*cc02d7e2SAndroid Build Coastguard Worker */
XXH_memcpy(void * dest,const void * src,size_t size)1480*cc02d7e2SAndroid Build Coastguard Worker static void* XXH_memcpy(void* dest, const void* src, size_t size)
1481*cc02d7e2SAndroid Build Coastguard Worker {
1482*cc02d7e2SAndroid Build Coastguard Worker return memcpy(dest,src,size);
1483*cc02d7e2SAndroid Build Coastguard Worker }
1484*cc02d7e2SAndroid Build Coastguard Worker
1485*cc02d7e2SAndroid Build Coastguard Worker #include <limits.h> /* ULLONG_MAX */
1486*cc02d7e2SAndroid Build Coastguard Worker
1487*cc02d7e2SAndroid Build Coastguard Worker
1488*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1489*cc02d7e2SAndroid Build Coastguard Worker * Compiler Specific Options
1490*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1491*cc02d7e2SAndroid Build Coastguard Worker #ifdef _MSC_VER /* Visual Studio warning fix */
1492*cc02d7e2SAndroid Build Coastguard Worker # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
1493*cc02d7e2SAndroid Build Coastguard Worker #endif
1494*cc02d7e2SAndroid Build Coastguard Worker
1495*cc02d7e2SAndroid Build Coastguard Worker #if XXH_NO_INLINE_HINTS /* disable inlining hints */
1496*cc02d7e2SAndroid Build Coastguard Worker # if defined(__GNUC__) || defined(__clang__)
1497*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static __attribute__((unused))
1498*cc02d7e2SAndroid Build Coastguard Worker # else
1499*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static
1500*cc02d7e2SAndroid Build Coastguard Worker # endif
1501*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE static
1502*cc02d7e2SAndroid Build Coastguard Worker /* enable inlining hints */
1503*cc02d7e2SAndroid Build Coastguard Worker #elif defined(__GNUC__) || defined(__clang__)
1504*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
1505*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE static __attribute__((noinline))
1506*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_MSC_VER) /* Visual Studio */
1507*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static __forceinline
1508*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE static __declspec(noinline)
1509*cc02d7e2SAndroid Build Coastguard Worker #elif defined (__cplusplus) \
1510*cc02d7e2SAndroid Build Coastguard Worker || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */
1511*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static inline
1512*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE static
1513*cc02d7e2SAndroid Build Coastguard Worker #else
1514*cc02d7e2SAndroid Build Coastguard Worker # define XXH_FORCE_INLINE static
1515*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NO_INLINE static
1516*cc02d7e2SAndroid Build Coastguard Worker #endif
1517*cc02d7e2SAndroid Build Coastguard Worker
1518*cc02d7e2SAndroid Build Coastguard Worker
1519*cc02d7e2SAndroid Build Coastguard Worker
1520*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1521*cc02d7e2SAndroid Build Coastguard Worker * Debug
1522*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1523*cc02d7e2SAndroid Build Coastguard Worker /*!
1524*cc02d7e2SAndroid Build Coastguard Worker * @ingroup tuning
1525*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_DEBUGLEVEL
1526*cc02d7e2SAndroid Build Coastguard Worker * @brief Sets the debugging level.
1527*cc02d7e2SAndroid Build Coastguard Worker *
1528*cc02d7e2SAndroid Build Coastguard Worker * XXH_DEBUGLEVEL is expected to be defined externally, typically via the
1529*cc02d7e2SAndroid Build Coastguard Worker * compiler's command line options. The value must be a number.
1530*cc02d7e2SAndroid Build Coastguard Worker */
1531*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_DEBUGLEVEL
1532*cc02d7e2SAndroid Build Coastguard Worker # ifdef DEBUGLEVEL /* backwards compat */
1533*cc02d7e2SAndroid Build Coastguard Worker # define XXH_DEBUGLEVEL DEBUGLEVEL
1534*cc02d7e2SAndroid Build Coastguard Worker # else
1535*cc02d7e2SAndroid Build Coastguard Worker # define XXH_DEBUGLEVEL 0
1536*cc02d7e2SAndroid Build Coastguard Worker # endif
1537*cc02d7e2SAndroid Build Coastguard Worker #endif
1538*cc02d7e2SAndroid Build Coastguard Worker
1539*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_DEBUGLEVEL>=1)
1540*cc02d7e2SAndroid Build Coastguard Worker # include <assert.h> /* note: can still be disabled with NDEBUG */
1541*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ASSERT(c) assert(c)
1542*cc02d7e2SAndroid Build Coastguard Worker #else
1543*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ASSERT(c) ((void)0)
1544*cc02d7e2SAndroid Build Coastguard Worker #endif
1545*cc02d7e2SAndroid Build Coastguard Worker
1546*cc02d7e2SAndroid Build Coastguard Worker /* note: use after variable declarations */
1547*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_STATIC_ASSERT
1548*cc02d7e2SAndroid Build Coastguard Worker # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
1549*cc02d7e2SAndroid Build Coastguard Worker # include <assert.h>
1550*cc02d7e2SAndroid Build Coastguard Worker # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1551*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
1552*cc02d7e2SAndroid Build Coastguard Worker # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1553*cc02d7e2SAndroid Build Coastguard Worker # else
1554*cc02d7e2SAndroid Build Coastguard Worker # define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
1555*cc02d7e2SAndroid Build Coastguard Worker # endif
1556*cc02d7e2SAndroid Build Coastguard Worker # define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
1557*cc02d7e2SAndroid Build Coastguard Worker #endif
1558*cc02d7e2SAndroid Build Coastguard Worker
1559*cc02d7e2SAndroid Build Coastguard Worker /*!
1560*cc02d7e2SAndroid Build Coastguard Worker * @internal
1561*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_COMPILER_GUARD(var)
1562*cc02d7e2SAndroid Build Coastguard Worker * @brief Used to prevent unwanted optimizations for @p var.
1563*cc02d7e2SAndroid Build Coastguard Worker *
1564*cc02d7e2SAndroid Build Coastguard Worker * It uses an empty GCC inline assembly statement with a register constraint
1565*cc02d7e2SAndroid Build Coastguard Worker * which forces @p var into a general purpose register (eg eax, ebx, ecx
1566*cc02d7e2SAndroid Build Coastguard Worker * on x86) and marks it as modified.
1567*cc02d7e2SAndroid Build Coastguard Worker *
1568*cc02d7e2SAndroid Build Coastguard Worker * This is used in a few places to avoid unwanted autovectorization (e.g.
1569*cc02d7e2SAndroid Build Coastguard Worker * XXH32_round()). All vectorization we want is explicit via intrinsics,
1570*cc02d7e2SAndroid Build Coastguard Worker * and _usually_ isn't wanted elsewhere.
1571*cc02d7e2SAndroid Build Coastguard Worker *
1572*cc02d7e2SAndroid Build Coastguard Worker * We also use it to prevent unwanted constant folding for AArch64 in
1573*cc02d7e2SAndroid Build Coastguard Worker * XXH3_initCustomSecret_scalar().
1574*cc02d7e2SAndroid Build Coastguard Worker */
1575*cc02d7e2SAndroid Build Coastguard Worker #if defined(__GNUC__) || defined(__clang__)
1576*cc02d7e2SAndroid Build Coastguard Worker # define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))
1577*cc02d7e2SAndroid Build Coastguard Worker #else
1578*cc02d7e2SAndroid Build Coastguard Worker # define XXH_COMPILER_GUARD(var) ((void)0)
1579*cc02d7e2SAndroid Build Coastguard Worker #endif
1580*cc02d7e2SAndroid Build Coastguard Worker
1581*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1582*cc02d7e2SAndroid Build Coastguard Worker * Basic Types
1583*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1584*cc02d7e2SAndroid Build Coastguard Worker #if !defined (__VMS) \
1585*cc02d7e2SAndroid Build Coastguard Worker && (defined (__cplusplus) \
1586*cc02d7e2SAndroid Build Coastguard Worker || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
1587*cc02d7e2SAndroid Build Coastguard Worker # include <stdint.h>
1588*cc02d7e2SAndroid Build Coastguard Worker typedef uint8_t xxh_u8;
1589*cc02d7e2SAndroid Build Coastguard Worker #else
1590*cc02d7e2SAndroid Build Coastguard Worker typedef unsigned char xxh_u8;
1591*cc02d7e2SAndroid Build Coastguard Worker #endif
1592*cc02d7e2SAndroid Build Coastguard Worker typedef XXH32_hash_t xxh_u32;
1593*cc02d7e2SAndroid Build Coastguard Worker
1594*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
1595*cc02d7e2SAndroid Build Coastguard Worker # define BYTE xxh_u8
1596*cc02d7e2SAndroid Build Coastguard Worker # define U8 xxh_u8
1597*cc02d7e2SAndroid Build Coastguard Worker # define U32 xxh_u32
1598*cc02d7e2SAndroid Build Coastguard Worker #endif
1599*cc02d7e2SAndroid Build Coastguard Worker
1600*cc02d7e2SAndroid Build Coastguard Worker /* *** Memory access *** */
1601*cc02d7e2SAndroid Build Coastguard Worker
1602*cc02d7e2SAndroid Build Coastguard Worker /*!
1603*cc02d7e2SAndroid Build Coastguard Worker * @internal
1604*cc02d7e2SAndroid Build Coastguard Worker * @fn xxh_u32 XXH_read32(const void* ptr)
1605*cc02d7e2SAndroid Build Coastguard Worker * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness.
1606*cc02d7e2SAndroid Build Coastguard Worker *
1607*cc02d7e2SAndroid Build Coastguard Worker * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1608*cc02d7e2SAndroid Build Coastguard Worker *
1609*cc02d7e2SAndroid Build Coastguard Worker * @param ptr The pointer to read from.
1610*cc02d7e2SAndroid Build Coastguard Worker * @return The 32-bit native endian integer from the bytes at @p ptr.
1611*cc02d7e2SAndroid Build Coastguard Worker */
1612*cc02d7e2SAndroid Build Coastguard Worker
1613*cc02d7e2SAndroid Build Coastguard Worker /*!
1614*cc02d7e2SAndroid Build Coastguard Worker * @internal
1615*cc02d7e2SAndroid Build Coastguard Worker * @fn xxh_u32 XXH_readLE32(const void* ptr)
1616*cc02d7e2SAndroid Build Coastguard Worker * @brief Reads an unaligned 32-bit little endian integer from @p ptr.
1617*cc02d7e2SAndroid Build Coastguard Worker *
1618*cc02d7e2SAndroid Build Coastguard Worker * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1619*cc02d7e2SAndroid Build Coastguard Worker *
1620*cc02d7e2SAndroid Build Coastguard Worker * @param ptr The pointer to read from.
1621*cc02d7e2SAndroid Build Coastguard Worker * @return The 32-bit little endian integer from the bytes at @p ptr.
1622*cc02d7e2SAndroid Build Coastguard Worker */
1623*cc02d7e2SAndroid Build Coastguard Worker
1624*cc02d7e2SAndroid Build Coastguard Worker /*!
1625*cc02d7e2SAndroid Build Coastguard Worker * @internal
1626*cc02d7e2SAndroid Build Coastguard Worker * @fn xxh_u32 XXH_readBE32(const void* ptr)
1627*cc02d7e2SAndroid Build Coastguard Worker * @brief Reads an unaligned 32-bit big endian integer from @p ptr.
1628*cc02d7e2SAndroid Build Coastguard Worker *
1629*cc02d7e2SAndroid Build Coastguard Worker * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1630*cc02d7e2SAndroid Build Coastguard Worker *
1631*cc02d7e2SAndroid Build Coastguard Worker * @param ptr The pointer to read from.
1632*cc02d7e2SAndroid Build Coastguard Worker * @return The 32-bit big endian integer from the bytes at @p ptr.
1633*cc02d7e2SAndroid Build Coastguard Worker */
1634*cc02d7e2SAndroid Build Coastguard Worker
1635*cc02d7e2SAndroid Build Coastguard Worker /*!
1636*cc02d7e2SAndroid Build Coastguard Worker * @internal
1637*cc02d7e2SAndroid Build Coastguard Worker * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align)
1638*cc02d7e2SAndroid Build Coastguard Worker * @brief Like @ref XXH_readLE32(), but has an option for aligned reads.
1639*cc02d7e2SAndroid Build Coastguard Worker *
1640*cc02d7e2SAndroid Build Coastguard Worker * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1641*cc02d7e2SAndroid Build Coastguard Worker * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is
1642*cc02d7e2SAndroid Build Coastguard Worker * always @ref XXH_alignment::XXH_unaligned.
1643*cc02d7e2SAndroid Build Coastguard Worker *
1644*cc02d7e2SAndroid Build Coastguard Worker * @param ptr The pointer to read from.
1645*cc02d7e2SAndroid Build Coastguard Worker * @param align Whether @p ptr is aligned.
1646*cc02d7e2SAndroid Build Coastguard Worker * @pre
1647*cc02d7e2SAndroid Build Coastguard Worker * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte
1648*cc02d7e2SAndroid Build Coastguard Worker * aligned.
1649*cc02d7e2SAndroid Build Coastguard Worker * @return The 32-bit little endian integer from the bytes at @p ptr.
1650*cc02d7e2SAndroid Build Coastguard Worker */
1651*cc02d7e2SAndroid Build Coastguard Worker
1652*cc02d7e2SAndroid Build Coastguard Worker #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
1653*cc02d7e2SAndroid Build Coastguard Worker /*
1654*cc02d7e2SAndroid Build Coastguard Worker * Manual byteshift. Best for old compilers which don't inline memcpy.
1655*cc02d7e2SAndroid Build Coastguard Worker * We actually directly use XXH_readLE32 and XXH_readBE32.
1656*cc02d7e2SAndroid Build Coastguard Worker */
1657*cc02d7e2SAndroid Build Coastguard Worker #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
1658*cc02d7e2SAndroid Build Coastguard Worker
1659*cc02d7e2SAndroid Build Coastguard Worker /*
1660*cc02d7e2SAndroid Build Coastguard Worker * Force direct memory access. Only works on CPU which support unaligned memory
1661*cc02d7e2SAndroid Build Coastguard Worker * access in hardware.
1662*cc02d7e2SAndroid Build Coastguard Worker */
XXH_read32(const void * memPtr)1663*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }
1664*cc02d7e2SAndroid Build Coastguard Worker
1665*cc02d7e2SAndroid Build Coastguard Worker #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
1666*cc02d7e2SAndroid Build Coastguard Worker
1667*cc02d7e2SAndroid Build Coastguard Worker /*
1668*cc02d7e2SAndroid Build Coastguard Worker * __pack instructions are safer but compiler specific, hence potentially
1669*cc02d7e2SAndroid Build Coastguard Worker * problematic for some compilers.
1670*cc02d7e2SAndroid Build Coastguard Worker *
1671*cc02d7e2SAndroid Build Coastguard Worker * Currently only defined for GCC and ICC.
1672*cc02d7e2SAndroid Build Coastguard Worker */
1673*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
1674*cc02d7e2SAndroid Build Coastguard Worker typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;
1675*cc02d7e2SAndroid Build Coastguard Worker #endif
XXH_read32(const void * ptr)1676*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH_read32(const void* ptr)
1677*cc02d7e2SAndroid Build Coastguard Worker {
1678*cc02d7e2SAndroid Build Coastguard Worker typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign;
1679*cc02d7e2SAndroid Build Coastguard Worker return ((const xxh_unalign*)ptr)->u32;
1680*cc02d7e2SAndroid Build Coastguard Worker }
1681*cc02d7e2SAndroid Build Coastguard Worker
1682*cc02d7e2SAndroid Build Coastguard Worker #else
1683*cc02d7e2SAndroid Build Coastguard Worker
1684*cc02d7e2SAndroid Build Coastguard Worker /*
1685*cc02d7e2SAndroid Build Coastguard Worker * Portable and safe solution. Generally efficient.
1686*cc02d7e2SAndroid Build Coastguard Worker * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
1687*cc02d7e2SAndroid Build Coastguard Worker */
XXH_read32(const void * memPtr)1688*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH_read32(const void* memPtr)
1689*cc02d7e2SAndroid Build Coastguard Worker {
1690*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 val;
1691*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(&val, memPtr, sizeof(val));
1692*cc02d7e2SAndroid Build Coastguard Worker return val;
1693*cc02d7e2SAndroid Build Coastguard Worker }
1694*cc02d7e2SAndroid Build Coastguard Worker
1695*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
1696*cc02d7e2SAndroid Build Coastguard Worker
1697*cc02d7e2SAndroid Build Coastguard Worker
1698*cc02d7e2SAndroid Build Coastguard Worker /* *** Endianness *** */
1699*cc02d7e2SAndroid Build Coastguard Worker
1700*cc02d7e2SAndroid Build Coastguard Worker /*!
1701*cc02d7e2SAndroid Build Coastguard Worker * @ingroup tuning
1702*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_CPU_LITTLE_ENDIAN
1703*cc02d7e2SAndroid Build Coastguard Worker * @brief Whether the target is little endian.
1704*cc02d7e2SAndroid Build Coastguard Worker *
1705*cc02d7e2SAndroid Build Coastguard Worker * Defined to 1 if the target is little endian, or 0 if it is big endian.
1706*cc02d7e2SAndroid Build Coastguard Worker * It can be defined externally, for example on the compiler command line.
1707*cc02d7e2SAndroid Build Coastguard Worker *
1708*cc02d7e2SAndroid Build Coastguard Worker * If it is not defined,
1709*cc02d7e2SAndroid Build Coastguard Worker * a runtime check (which is usually constant folded) is used instead.
1710*cc02d7e2SAndroid Build Coastguard Worker *
1711*cc02d7e2SAndroid Build Coastguard Worker * @note
1712*cc02d7e2SAndroid Build Coastguard Worker * This is not necessarily defined to an integer constant.
1713*cc02d7e2SAndroid Build Coastguard Worker *
1714*cc02d7e2SAndroid Build Coastguard Worker * @see XXH_isLittleEndian() for the runtime check.
1715*cc02d7e2SAndroid Build Coastguard Worker */
1716*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_CPU_LITTLE_ENDIAN
1717*cc02d7e2SAndroid Build Coastguard Worker /*
1718*cc02d7e2SAndroid Build Coastguard Worker * Try to detect endianness automatically, to avoid the nonstandard behavior
1719*cc02d7e2SAndroid Build Coastguard Worker * in `XXH_isLittleEndian()`
1720*cc02d7e2SAndroid Build Coastguard Worker */
1721*cc02d7e2SAndroid Build Coastguard Worker # if defined(_WIN32) /* Windows is always little endian */ \
1722*cc02d7e2SAndroid Build Coastguard Worker || defined(__LITTLE_ENDIAN__) \
1723*cc02d7e2SAndroid Build Coastguard Worker || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1724*cc02d7e2SAndroid Build Coastguard Worker # define XXH_CPU_LITTLE_ENDIAN 1
1725*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__BIG_ENDIAN__) \
1726*cc02d7e2SAndroid Build Coastguard Worker || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1727*cc02d7e2SAndroid Build Coastguard Worker # define XXH_CPU_LITTLE_ENDIAN 0
1728*cc02d7e2SAndroid Build Coastguard Worker # else
1729*cc02d7e2SAndroid Build Coastguard Worker /*!
1730*cc02d7e2SAndroid Build Coastguard Worker * @internal
1731*cc02d7e2SAndroid Build Coastguard Worker * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN.
1732*cc02d7e2SAndroid Build Coastguard Worker *
1733*cc02d7e2SAndroid Build Coastguard Worker * Most compilers will constant fold this.
1734*cc02d7e2SAndroid Build Coastguard Worker */
XXH_isLittleEndian(void)1735*cc02d7e2SAndroid Build Coastguard Worker static int XXH_isLittleEndian(void)
1736*cc02d7e2SAndroid Build Coastguard Worker {
1737*cc02d7e2SAndroid Build Coastguard Worker /*
1738*cc02d7e2SAndroid Build Coastguard Worker * Portable and well-defined behavior.
1739*cc02d7e2SAndroid Build Coastguard Worker * Don't use static: it is detrimental to performance.
1740*cc02d7e2SAndroid Build Coastguard Worker */
1741*cc02d7e2SAndroid Build Coastguard Worker const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };
1742*cc02d7e2SAndroid Build Coastguard Worker return one.c[0];
1743*cc02d7e2SAndroid Build Coastguard Worker }
1744*cc02d7e2SAndroid Build Coastguard Worker # define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
1745*cc02d7e2SAndroid Build Coastguard Worker # endif
1746*cc02d7e2SAndroid Build Coastguard Worker #endif
1747*cc02d7e2SAndroid Build Coastguard Worker
1748*cc02d7e2SAndroid Build Coastguard Worker
1749*cc02d7e2SAndroid Build Coastguard Worker
1750*cc02d7e2SAndroid Build Coastguard Worker
1751*cc02d7e2SAndroid Build Coastguard Worker /* ****************************************
1752*cc02d7e2SAndroid Build Coastguard Worker * Compiler-specific Functions and Macros
1753*cc02d7e2SAndroid Build Coastguard Worker ******************************************/
1754*cc02d7e2SAndroid Build Coastguard Worker #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
1755*cc02d7e2SAndroid Build Coastguard Worker
1756*cc02d7e2SAndroid Build Coastguard Worker #ifdef __has_builtin
1757*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_BUILTIN(x) __has_builtin(x)
1758*cc02d7e2SAndroid Build Coastguard Worker #else
1759*cc02d7e2SAndroid Build Coastguard Worker # define XXH_HAS_BUILTIN(x) 0
1760*cc02d7e2SAndroid Build Coastguard Worker #endif
1761*cc02d7e2SAndroid Build Coastguard Worker
1762*cc02d7e2SAndroid Build Coastguard Worker /*!
1763*cc02d7e2SAndroid Build Coastguard Worker * @internal
1764*cc02d7e2SAndroid Build Coastguard Worker * @def XXH_rotl32(x,r)
1765*cc02d7e2SAndroid Build Coastguard Worker * @brief 32-bit rotate left.
1766*cc02d7e2SAndroid Build Coastguard Worker *
1767*cc02d7e2SAndroid Build Coastguard Worker * @param x The 32-bit integer to be rotated.
1768*cc02d7e2SAndroid Build Coastguard Worker * @param r The number of bits to rotate.
1769*cc02d7e2SAndroid Build Coastguard Worker * @pre
1770*cc02d7e2SAndroid Build Coastguard Worker * @p r > 0 && @p r < 32
1771*cc02d7e2SAndroid Build Coastguard Worker * @note
1772*cc02d7e2SAndroid Build Coastguard Worker * @p x and @p r may be evaluated multiple times.
1773*cc02d7e2SAndroid Build Coastguard Worker * @return The rotated result.
1774*cc02d7e2SAndroid Build Coastguard Worker */
1775*cc02d7e2SAndroid Build Coastguard Worker #if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \
1776*cc02d7e2SAndroid Build Coastguard Worker && XXH_HAS_BUILTIN(__builtin_rotateleft64)
1777*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl32 __builtin_rotateleft32
1778*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl64 __builtin_rotateleft64
1779*cc02d7e2SAndroid Build Coastguard Worker /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */
1780*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
1781*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl32(x,r) _rotl(x,r)
1782*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl64(x,r) _rotl64(x,r)
1783*cc02d7e2SAndroid Build Coastguard Worker #else
1784*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
1785*cc02d7e2SAndroid Build Coastguard Worker # define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
1786*cc02d7e2SAndroid Build Coastguard Worker #endif
1787*cc02d7e2SAndroid Build Coastguard Worker
1788*cc02d7e2SAndroid Build Coastguard Worker /*!
1789*cc02d7e2SAndroid Build Coastguard Worker * @internal
1790*cc02d7e2SAndroid Build Coastguard Worker * @fn xxh_u32 XXH_swap32(xxh_u32 x)
1791*cc02d7e2SAndroid Build Coastguard Worker * @brief A 32-bit byteswap.
1792*cc02d7e2SAndroid Build Coastguard Worker *
1793*cc02d7e2SAndroid Build Coastguard Worker * @param x The 32-bit integer to byteswap.
1794*cc02d7e2SAndroid Build Coastguard Worker * @return @p x, byteswapped.
1795*cc02d7e2SAndroid Build Coastguard Worker */
1796*cc02d7e2SAndroid Build Coastguard Worker #if defined(_MSC_VER) /* Visual Studio */
1797*cc02d7e2SAndroid Build Coastguard Worker # define XXH_swap32 _byteswap_ulong
1798*cc02d7e2SAndroid Build Coastguard Worker #elif XXH_GCC_VERSION >= 403
1799*cc02d7e2SAndroid Build Coastguard Worker # define XXH_swap32 __builtin_bswap32
1800*cc02d7e2SAndroid Build Coastguard Worker #else
XXH_swap32(xxh_u32 x)1801*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH_swap32 (xxh_u32 x)
1802*cc02d7e2SAndroid Build Coastguard Worker {
1803*cc02d7e2SAndroid Build Coastguard Worker return ((x << 24) & 0xff000000 ) |
1804*cc02d7e2SAndroid Build Coastguard Worker ((x << 8) & 0x00ff0000 ) |
1805*cc02d7e2SAndroid Build Coastguard Worker ((x >> 8) & 0x0000ff00 ) |
1806*cc02d7e2SAndroid Build Coastguard Worker ((x >> 24) & 0x000000ff );
1807*cc02d7e2SAndroid Build Coastguard Worker }
1808*cc02d7e2SAndroid Build Coastguard Worker #endif
1809*cc02d7e2SAndroid Build Coastguard Worker
1810*cc02d7e2SAndroid Build Coastguard Worker
1811*cc02d7e2SAndroid Build Coastguard Worker /* ***************************
1812*cc02d7e2SAndroid Build Coastguard Worker * Memory reads
1813*cc02d7e2SAndroid Build Coastguard Worker *****************************/
1814*cc02d7e2SAndroid Build Coastguard Worker
1815*cc02d7e2SAndroid Build Coastguard Worker /*!
1816*cc02d7e2SAndroid Build Coastguard Worker * @internal
1817*cc02d7e2SAndroid Build Coastguard Worker * @brief Enum to indicate whether a pointer is aligned.
1818*cc02d7e2SAndroid Build Coastguard Worker */
1819*cc02d7e2SAndroid Build Coastguard Worker typedef enum {
1820*cc02d7e2SAndroid Build Coastguard Worker XXH_aligned, /*!< Aligned */
1821*cc02d7e2SAndroid Build Coastguard Worker XXH_unaligned /*!< Possibly unaligned */
1822*cc02d7e2SAndroid Build Coastguard Worker } XXH_alignment;
1823*cc02d7e2SAndroid Build Coastguard Worker
1824*cc02d7e2SAndroid Build Coastguard Worker /*
1825*cc02d7e2SAndroid Build Coastguard Worker * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load.
1826*cc02d7e2SAndroid Build Coastguard Worker *
1827*cc02d7e2SAndroid Build Coastguard Worker * This is ideal for older compilers which don't inline memcpy.
1828*cc02d7e2SAndroid Build Coastguard Worker */
1829*cc02d7e2SAndroid Build Coastguard Worker #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
1830*cc02d7e2SAndroid Build Coastguard Worker
XXH_readLE32(const void * memPtr)1831*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)
1832*cc02d7e2SAndroid Build Coastguard Worker {
1833*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
1834*cc02d7e2SAndroid Build Coastguard Worker return bytePtr[0]
1835*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[1] << 8)
1836*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[2] << 16)
1837*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[3] << 24);
1838*cc02d7e2SAndroid Build Coastguard Worker }
1839*cc02d7e2SAndroid Build Coastguard Worker
XXH_readBE32(const void * memPtr)1840*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)
1841*cc02d7e2SAndroid Build Coastguard Worker {
1842*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
1843*cc02d7e2SAndroid Build Coastguard Worker return bytePtr[3]
1844*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[2] << 8)
1845*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[1] << 16)
1846*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)bytePtr[0] << 24);
1847*cc02d7e2SAndroid Build Coastguard Worker }
1848*cc02d7e2SAndroid Build Coastguard Worker
1849*cc02d7e2SAndroid Build Coastguard Worker #else
XXH_readLE32(const void * ptr)1850*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)
1851*cc02d7e2SAndroid Build Coastguard Worker {
1852*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
1853*cc02d7e2SAndroid Build Coastguard Worker }
1854*cc02d7e2SAndroid Build Coastguard Worker
XXH_readBE32(const void * ptr)1855*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH_readBE32(const void* ptr)
1856*cc02d7e2SAndroid Build Coastguard Worker {
1857*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
1858*cc02d7e2SAndroid Build Coastguard Worker }
1859*cc02d7e2SAndroid Build Coastguard Worker #endif
1860*cc02d7e2SAndroid Build Coastguard Worker
1861*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u32
XXH_readLE32_align(const void * ptr,XXH_alignment align)1862*cc02d7e2SAndroid Build Coastguard Worker XXH_readLE32_align(const void* ptr, XXH_alignment align)
1863*cc02d7e2SAndroid Build Coastguard Worker {
1864*cc02d7e2SAndroid Build Coastguard Worker if (align==XXH_unaligned) {
1865*cc02d7e2SAndroid Build Coastguard Worker return XXH_readLE32(ptr);
1866*cc02d7e2SAndroid Build Coastguard Worker } else {
1867*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
1868*cc02d7e2SAndroid Build Coastguard Worker }
1869*cc02d7e2SAndroid Build Coastguard Worker }
1870*cc02d7e2SAndroid Build Coastguard Worker
1871*cc02d7e2SAndroid Build Coastguard Worker
1872*cc02d7e2SAndroid Build Coastguard Worker /* *************************************
1873*cc02d7e2SAndroid Build Coastguard Worker * Misc
1874*cc02d7e2SAndroid Build Coastguard Worker ***************************************/
1875*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup public */
XXH_versionNumber(void)1876*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
1877*cc02d7e2SAndroid Build Coastguard Worker
1878*cc02d7e2SAndroid Build Coastguard Worker
1879*cc02d7e2SAndroid Build Coastguard Worker /* *******************************************************************
1880*cc02d7e2SAndroid Build Coastguard Worker * 32-bit hash functions
1881*cc02d7e2SAndroid Build Coastguard Worker *********************************************************************/
1882*cc02d7e2SAndroid Build Coastguard Worker /*!
1883*cc02d7e2SAndroid Build Coastguard Worker * @}
1884*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh32_impl XXH32 implementation
1885*cc02d7e2SAndroid Build Coastguard Worker * @ingroup impl
1886*cc02d7e2SAndroid Build Coastguard Worker * @{
1887*cc02d7e2SAndroid Build Coastguard Worker */
1888*cc02d7e2SAndroid Build Coastguard Worker /* #define instead of static const, to be used as initializers */
1889*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */
1890*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */
1891*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */
1892*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */
1893*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */
1894*cc02d7e2SAndroid Build Coastguard Worker
1895*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
1896*cc02d7e2SAndroid Build Coastguard Worker # define PRIME32_1 XXH_PRIME32_1
1897*cc02d7e2SAndroid Build Coastguard Worker # define PRIME32_2 XXH_PRIME32_2
1898*cc02d7e2SAndroid Build Coastguard Worker # define PRIME32_3 XXH_PRIME32_3
1899*cc02d7e2SAndroid Build Coastguard Worker # define PRIME32_4 XXH_PRIME32_4
1900*cc02d7e2SAndroid Build Coastguard Worker # define PRIME32_5 XXH_PRIME32_5
1901*cc02d7e2SAndroid Build Coastguard Worker #endif
1902*cc02d7e2SAndroid Build Coastguard Worker
1903*cc02d7e2SAndroid Build Coastguard Worker /*!
1904*cc02d7e2SAndroid Build Coastguard Worker * @internal
1905*cc02d7e2SAndroid Build Coastguard Worker * @brief Normal stripe processing routine.
1906*cc02d7e2SAndroid Build Coastguard Worker *
1907*cc02d7e2SAndroid Build Coastguard Worker * This shuffles the bits so that any bit from @p input impacts several bits in
1908*cc02d7e2SAndroid Build Coastguard Worker * @p acc.
1909*cc02d7e2SAndroid Build Coastguard Worker *
1910*cc02d7e2SAndroid Build Coastguard Worker * @param acc The accumulator lane.
1911*cc02d7e2SAndroid Build Coastguard Worker * @param input The stripe of input to mix.
1912*cc02d7e2SAndroid Build Coastguard Worker * @return The mixed accumulator lane.
1913*cc02d7e2SAndroid Build Coastguard Worker */
XXH32_round(xxh_u32 acc,xxh_u32 input)1914*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
1915*cc02d7e2SAndroid Build Coastguard Worker {
1916*cc02d7e2SAndroid Build Coastguard Worker acc += input * XXH_PRIME32_2;
1917*cc02d7e2SAndroid Build Coastguard Worker acc = XXH_rotl32(acc, 13);
1918*cc02d7e2SAndroid Build Coastguard Worker acc *= XXH_PRIME32_1;
1919*cc02d7e2SAndroid Build Coastguard Worker #if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
1920*cc02d7e2SAndroid Build Coastguard Worker /*
1921*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
1922*cc02d7e2SAndroid Build Coastguard Worker * A compiler fence is the only thing that prevents GCC and Clang from
1923*cc02d7e2SAndroid Build Coastguard Worker * autovectorizing the XXH32 loop (pragmas and attributes don't work for some
1924*cc02d7e2SAndroid Build Coastguard Worker * reason) without globally disabling SSE4.1.
1925*cc02d7e2SAndroid Build Coastguard Worker *
1926*cc02d7e2SAndroid Build Coastguard Worker * The reason we want to avoid vectorization is because despite working on
1927*cc02d7e2SAndroid Build Coastguard Worker * 4 integers at a time, there are multiple factors slowing XXH32 down on
1928*cc02d7e2SAndroid Build Coastguard Worker * SSE4:
1929*cc02d7e2SAndroid Build Coastguard Worker * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on
1930*cc02d7e2SAndroid Build Coastguard Worker * newer chips!) making it slightly slower to multiply four integers at
1931*cc02d7e2SAndroid Build Coastguard Worker * once compared to four integers independently. Even when pmulld was
1932*cc02d7e2SAndroid Build Coastguard Worker * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE
1933*cc02d7e2SAndroid Build Coastguard Worker * just to multiply unless doing a long operation.
1934*cc02d7e2SAndroid Build Coastguard Worker *
1935*cc02d7e2SAndroid Build Coastguard Worker * - Four instructions are required to rotate,
1936*cc02d7e2SAndroid Build Coastguard Worker * movqda tmp, v // not required with VEX encoding
1937*cc02d7e2SAndroid Build Coastguard Worker * pslld tmp, 13 // tmp <<= 13
1938*cc02d7e2SAndroid Build Coastguard Worker * psrld v, 19 // x >>= 19
1939*cc02d7e2SAndroid Build Coastguard Worker * por v, tmp // x |= tmp
1940*cc02d7e2SAndroid Build Coastguard Worker * compared to one for scalar:
1941*cc02d7e2SAndroid Build Coastguard Worker * roll v, 13 // reliably fast across the board
1942*cc02d7e2SAndroid Build Coastguard Worker * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason
1943*cc02d7e2SAndroid Build Coastguard Worker *
1944*cc02d7e2SAndroid Build Coastguard Worker * - Instruction level parallelism is actually more beneficial here because
1945*cc02d7e2SAndroid Build Coastguard Worker * the SIMD actually serializes this operation: While v1 is rotating, v2
1946*cc02d7e2SAndroid Build Coastguard Worker * can load data, while v3 can multiply. SSE forces them to operate
1947*cc02d7e2SAndroid Build Coastguard Worker * together.
1948*cc02d7e2SAndroid Build Coastguard Worker *
1949*cc02d7e2SAndroid Build Coastguard Worker * This is also enabled on AArch64, as Clang autovectorizes it incorrectly
1950*cc02d7e2SAndroid Build Coastguard Worker * and it is pointless writing a NEON implementation that is basically the
1951*cc02d7e2SAndroid Build Coastguard Worker * same speed as scalar for XXH32.
1952*cc02d7e2SAndroid Build Coastguard Worker */
1953*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(acc);
1954*cc02d7e2SAndroid Build Coastguard Worker #endif
1955*cc02d7e2SAndroid Build Coastguard Worker return acc;
1956*cc02d7e2SAndroid Build Coastguard Worker }
1957*cc02d7e2SAndroid Build Coastguard Worker
1958*cc02d7e2SAndroid Build Coastguard Worker /*!
1959*cc02d7e2SAndroid Build Coastguard Worker * @internal
1960*cc02d7e2SAndroid Build Coastguard Worker * @brief Mixes all bits to finalize the hash.
1961*cc02d7e2SAndroid Build Coastguard Worker *
1962*cc02d7e2SAndroid Build Coastguard Worker * The final mix ensures that all input bits have a chance to impact any bit in
1963*cc02d7e2SAndroid Build Coastguard Worker * the output digest, resulting in an unbiased distribution.
1964*cc02d7e2SAndroid Build Coastguard Worker *
1965*cc02d7e2SAndroid Build Coastguard Worker * @param h32 The hash to avalanche.
1966*cc02d7e2SAndroid Build Coastguard Worker * @return The avalanched hash.
1967*cc02d7e2SAndroid Build Coastguard Worker */
XXH32_avalanche(xxh_u32 h32)1968*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32 XXH32_avalanche(xxh_u32 h32)
1969*cc02d7e2SAndroid Build Coastguard Worker {
1970*cc02d7e2SAndroid Build Coastguard Worker h32 ^= h32 >> 15;
1971*cc02d7e2SAndroid Build Coastguard Worker h32 *= XXH_PRIME32_2;
1972*cc02d7e2SAndroid Build Coastguard Worker h32 ^= h32 >> 13;
1973*cc02d7e2SAndroid Build Coastguard Worker h32 *= XXH_PRIME32_3;
1974*cc02d7e2SAndroid Build Coastguard Worker h32 ^= h32 >> 16;
1975*cc02d7e2SAndroid Build Coastguard Worker return(h32);
1976*cc02d7e2SAndroid Build Coastguard Worker }
1977*cc02d7e2SAndroid Build Coastguard Worker
1978*cc02d7e2SAndroid Build Coastguard Worker #define XXH_get32bits(p) XXH_readLE32_align(p, align)
1979*cc02d7e2SAndroid Build Coastguard Worker
1980*cc02d7e2SAndroid Build Coastguard Worker /*!
1981*cc02d7e2SAndroid Build Coastguard Worker * @internal
1982*cc02d7e2SAndroid Build Coastguard Worker * @brief Processes the last 0-15 bytes of @p ptr.
1983*cc02d7e2SAndroid Build Coastguard Worker *
1984*cc02d7e2SAndroid Build Coastguard Worker * There may be up to 15 bytes remaining to consume from the input.
1985*cc02d7e2SAndroid Build Coastguard Worker * This final stage will digest them to ensure that all input bytes are present
1986*cc02d7e2SAndroid Build Coastguard Worker * in the final mix.
1987*cc02d7e2SAndroid Build Coastguard Worker *
1988*cc02d7e2SAndroid Build Coastguard Worker * @param h32 The hash to finalize.
1989*cc02d7e2SAndroid Build Coastguard Worker * @param ptr The pointer to the remaining input.
1990*cc02d7e2SAndroid Build Coastguard Worker * @param len The remaining length, modulo 16.
1991*cc02d7e2SAndroid Build Coastguard Worker * @param align Whether @p ptr is aligned.
1992*cc02d7e2SAndroid Build Coastguard Worker * @return The finalized hash.
1993*cc02d7e2SAndroid Build Coastguard Worker */
1994*cc02d7e2SAndroid Build Coastguard Worker static xxh_u32
XXH32_finalize(xxh_u32 h32,const xxh_u8 * ptr,size_t len,XXH_alignment align)1995*cc02d7e2SAndroid Build Coastguard Worker XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
1996*cc02d7e2SAndroid Build Coastguard Worker {
1997*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PROCESS1 do { \
1998*cc02d7e2SAndroid Build Coastguard Worker h32 += (*ptr++) * XXH_PRIME32_5; \
1999*cc02d7e2SAndroid Build Coastguard Worker h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \
2000*cc02d7e2SAndroid Build Coastguard Worker } while (0)
2001*cc02d7e2SAndroid Build Coastguard Worker
2002*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PROCESS4 do { \
2003*cc02d7e2SAndroid Build Coastguard Worker h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \
2004*cc02d7e2SAndroid Build Coastguard Worker ptr += 4; \
2005*cc02d7e2SAndroid Build Coastguard Worker h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
2006*cc02d7e2SAndroid Build Coastguard Worker } while (0)
2007*cc02d7e2SAndroid Build Coastguard Worker
2008*cc02d7e2SAndroid Build Coastguard Worker if (ptr==NULL) XXH_ASSERT(len == 0);
2009*cc02d7e2SAndroid Build Coastguard Worker
2010*cc02d7e2SAndroid Build Coastguard Worker /* Compact rerolled version; generally faster */
2011*cc02d7e2SAndroid Build Coastguard Worker if (!XXH32_ENDJMP) {
2012*cc02d7e2SAndroid Build Coastguard Worker len &= 15;
2013*cc02d7e2SAndroid Build Coastguard Worker while (len >= 4) {
2014*cc02d7e2SAndroid Build Coastguard Worker XXH_PROCESS4;
2015*cc02d7e2SAndroid Build Coastguard Worker len -= 4;
2016*cc02d7e2SAndroid Build Coastguard Worker }
2017*cc02d7e2SAndroid Build Coastguard Worker while (len > 0) {
2018*cc02d7e2SAndroid Build Coastguard Worker XXH_PROCESS1;
2019*cc02d7e2SAndroid Build Coastguard Worker --len;
2020*cc02d7e2SAndroid Build Coastguard Worker }
2021*cc02d7e2SAndroid Build Coastguard Worker return XXH32_avalanche(h32);
2022*cc02d7e2SAndroid Build Coastguard Worker } else {
2023*cc02d7e2SAndroid Build Coastguard Worker switch(len&15) /* or switch(bEnd - p) */ {
2024*cc02d7e2SAndroid Build Coastguard Worker case 12: XXH_PROCESS4;
2025*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2026*cc02d7e2SAndroid Build Coastguard Worker case 8: XXH_PROCESS4;
2027*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2028*cc02d7e2SAndroid Build Coastguard Worker case 4: XXH_PROCESS4;
2029*cc02d7e2SAndroid Build Coastguard Worker return XXH32_avalanche(h32);
2030*cc02d7e2SAndroid Build Coastguard Worker
2031*cc02d7e2SAndroid Build Coastguard Worker case 13: XXH_PROCESS4;
2032*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2033*cc02d7e2SAndroid Build Coastguard Worker case 9: XXH_PROCESS4;
2034*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2035*cc02d7e2SAndroid Build Coastguard Worker case 5: XXH_PROCESS4;
2036*cc02d7e2SAndroid Build Coastguard Worker XXH_PROCESS1;
2037*cc02d7e2SAndroid Build Coastguard Worker return XXH32_avalanche(h32);
2038*cc02d7e2SAndroid Build Coastguard Worker
2039*cc02d7e2SAndroid Build Coastguard Worker case 14: XXH_PROCESS4;
2040*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2041*cc02d7e2SAndroid Build Coastguard Worker case 10: XXH_PROCESS4;
2042*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2043*cc02d7e2SAndroid Build Coastguard Worker case 6: XXH_PROCESS4;
2044*cc02d7e2SAndroid Build Coastguard Worker XXH_PROCESS1;
2045*cc02d7e2SAndroid Build Coastguard Worker XXH_PROCESS1;
2046*cc02d7e2SAndroid Build Coastguard Worker return XXH32_avalanche(h32);
2047*cc02d7e2SAndroid Build Coastguard Worker
2048*cc02d7e2SAndroid Build Coastguard Worker case 15: XXH_PROCESS4;
2049*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2050*cc02d7e2SAndroid Build Coastguard Worker case 11: XXH_PROCESS4;
2051*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2052*cc02d7e2SAndroid Build Coastguard Worker case 7: XXH_PROCESS4;
2053*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2054*cc02d7e2SAndroid Build Coastguard Worker case 3: XXH_PROCESS1;
2055*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2056*cc02d7e2SAndroid Build Coastguard Worker case 2: XXH_PROCESS1;
2057*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2058*cc02d7e2SAndroid Build Coastguard Worker case 1: XXH_PROCESS1;
2059*cc02d7e2SAndroid Build Coastguard Worker XXH_FALLTHROUGH;
2060*cc02d7e2SAndroid Build Coastguard Worker case 0: return XXH32_avalanche(h32);
2061*cc02d7e2SAndroid Build Coastguard Worker }
2062*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(0);
2063*cc02d7e2SAndroid Build Coastguard Worker return h32; /* reaching this point is deemed impossible */
2064*cc02d7e2SAndroid Build Coastguard Worker }
2065*cc02d7e2SAndroid Build Coastguard Worker }
2066*cc02d7e2SAndroid Build Coastguard Worker
2067*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
2068*cc02d7e2SAndroid Build Coastguard Worker # define PROCESS1 XXH_PROCESS1
2069*cc02d7e2SAndroid Build Coastguard Worker # define PROCESS4 XXH_PROCESS4
2070*cc02d7e2SAndroid Build Coastguard Worker #else
2071*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PROCESS1
2072*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PROCESS4
2073*cc02d7e2SAndroid Build Coastguard Worker #endif
2074*cc02d7e2SAndroid Build Coastguard Worker
2075*cc02d7e2SAndroid Build Coastguard Worker /*!
2076*cc02d7e2SAndroid Build Coastguard Worker * @internal
2077*cc02d7e2SAndroid Build Coastguard Worker * @brief The implementation for @ref XXH32().
2078*cc02d7e2SAndroid Build Coastguard Worker *
2079*cc02d7e2SAndroid Build Coastguard Worker * @param input , len , seed Directly passed from @ref XXH32().
2080*cc02d7e2SAndroid Build Coastguard Worker * @param align Whether @p input is aligned.
2081*cc02d7e2SAndroid Build Coastguard Worker * @return The calculated hash.
2082*cc02d7e2SAndroid Build Coastguard Worker */
2083*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u32
XXH32_endian_align(const xxh_u8 * input,size_t len,xxh_u32 seed,XXH_alignment align)2084*cc02d7e2SAndroid Build Coastguard Worker XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
2085*cc02d7e2SAndroid Build Coastguard Worker {
2086*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 h32;
2087*cc02d7e2SAndroid Build Coastguard Worker
2088*cc02d7e2SAndroid Build Coastguard Worker if (input==NULL) XXH_ASSERT(len == 0);
2089*cc02d7e2SAndroid Build Coastguard Worker
2090*cc02d7e2SAndroid Build Coastguard Worker if (len>=16) {
2091*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const bEnd = input + len;
2092*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const limit = bEnd - 15;
2093*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2094*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 v2 = seed + XXH_PRIME32_2;
2095*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 v3 = seed + 0;
2096*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 v4 = seed - XXH_PRIME32_1;
2097*cc02d7e2SAndroid Build Coastguard Worker
2098*cc02d7e2SAndroid Build Coastguard Worker do {
2099*cc02d7e2SAndroid Build Coastguard Worker v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
2100*cc02d7e2SAndroid Build Coastguard Worker v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
2101*cc02d7e2SAndroid Build Coastguard Worker v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
2102*cc02d7e2SAndroid Build Coastguard Worker v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
2103*cc02d7e2SAndroid Build Coastguard Worker } while (input < limit);
2104*cc02d7e2SAndroid Build Coastguard Worker
2105*cc02d7e2SAndroid Build Coastguard Worker h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
2106*cc02d7e2SAndroid Build Coastguard Worker + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
2107*cc02d7e2SAndroid Build Coastguard Worker } else {
2108*cc02d7e2SAndroid Build Coastguard Worker h32 = seed + XXH_PRIME32_5;
2109*cc02d7e2SAndroid Build Coastguard Worker }
2110*cc02d7e2SAndroid Build Coastguard Worker
2111*cc02d7e2SAndroid Build Coastguard Worker h32 += (xxh_u32)len;
2112*cc02d7e2SAndroid Build Coastguard Worker
2113*cc02d7e2SAndroid Build Coastguard Worker return XXH32_finalize(h32, input, len&15, align);
2114*cc02d7e2SAndroid Build Coastguard Worker }
2115*cc02d7e2SAndroid Build Coastguard Worker
2116*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32(const void * input,size_t len,XXH32_hash_t seed)2117*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
2118*cc02d7e2SAndroid Build Coastguard Worker {
2119*cc02d7e2SAndroid Build Coastguard Worker #if 0
2120*cc02d7e2SAndroid Build Coastguard Worker /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2121*cc02d7e2SAndroid Build Coastguard Worker XXH32_state_t state;
2122*cc02d7e2SAndroid Build Coastguard Worker XXH32_reset(&state, seed);
2123*cc02d7e2SAndroid Build Coastguard Worker XXH32_update(&state, (const xxh_u8*)input, len);
2124*cc02d7e2SAndroid Build Coastguard Worker return XXH32_digest(&state);
2125*cc02d7e2SAndroid Build Coastguard Worker #else
2126*cc02d7e2SAndroid Build Coastguard Worker if (XXH_FORCE_ALIGN_CHECK) {
2127*cc02d7e2SAndroid Build Coastguard Worker if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
2128*cc02d7e2SAndroid Build Coastguard Worker return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
2129*cc02d7e2SAndroid Build Coastguard Worker } }
2130*cc02d7e2SAndroid Build Coastguard Worker
2131*cc02d7e2SAndroid Build Coastguard Worker return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
2132*cc02d7e2SAndroid Build Coastguard Worker #endif
2133*cc02d7e2SAndroid Build Coastguard Worker }
2134*cc02d7e2SAndroid Build Coastguard Worker
2135*cc02d7e2SAndroid Build Coastguard Worker
2136*cc02d7e2SAndroid Build Coastguard Worker
2137*cc02d7e2SAndroid Build Coastguard Worker /******* Hash streaming *******/
2138*cc02d7e2SAndroid Build Coastguard Worker /*!
2139*cc02d7e2SAndroid Build Coastguard Worker * @ingroup xxh32_family
2140*cc02d7e2SAndroid Build Coastguard Worker */
XXH32_createState(void)2141*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
2142*cc02d7e2SAndroid Build Coastguard Worker {
2143*cc02d7e2SAndroid Build Coastguard Worker return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
2144*cc02d7e2SAndroid Build Coastguard Worker }
2145*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32_freeState(XXH32_state_t * statePtr)2146*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
2147*cc02d7e2SAndroid Build Coastguard Worker {
2148*cc02d7e2SAndroid Build Coastguard Worker XXH_free(statePtr);
2149*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2150*cc02d7e2SAndroid Build Coastguard Worker }
2151*cc02d7e2SAndroid Build Coastguard Worker
2152*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32_copyState(XXH32_state_t * dstState,const XXH32_state_t * srcState)2153*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
2154*cc02d7e2SAndroid Build Coastguard Worker {
2155*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dstState, srcState, sizeof(*dstState));
2156*cc02d7e2SAndroid Build Coastguard Worker }
2157*cc02d7e2SAndroid Build Coastguard Worker
2158*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32_reset(XXH32_state_t * statePtr,XXH32_hash_t seed)2159*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
2160*cc02d7e2SAndroid Build Coastguard Worker {
2161*cc02d7e2SAndroid Build Coastguard Worker XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
2162*cc02d7e2SAndroid Build Coastguard Worker memset(&state, 0, sizeof(state));
2163*cc02d7e2SAndroid Build Coastguard Worker state.v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2164*cc02d7e2SAndroid Build Coastguard Worker state.v[1] = seed + XXH_PRIME32_2;
2165*cc02d7e2SAndroid Build Coastguard Worker state.v[2] = seed + 0;
2166*cc02d7e2SAndroid Build Coastguard Worker state.v[3] = seed - XXH_PRIME32_1;
2167*cc02d7e2SAndroid Build Coastguard Worker /* do not write into reserved, planned to be removed in a future version */
2168*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
2169*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2170*cc02d7e2SAndroid Build Coastguard Worker }
2171*cc02d7e2SAndroid Build Coastguard Worker
2172*cc02d7e2SAndroid Build Coastguard Worker
2173*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
2174*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH32_update(XXH32_state_t * state,const void * input,size_t len)2175*cc02d7e2SAndroid Build Coastguard Worker XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2176*cc02d7e2SAndroid Build Coastguard Worker {
2177*cc02d7e2SAndroid Build Coastguard Worker if (input==NULL) {
2178*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len == 0);
2179*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2180*cc02d7e2SAndroid Build Coastguard Worker }
2181*cc02d7e2SAndroid Build Coastguard Worker
2182*cc02d7e2SAndroid Build Coastguard Worker { const xxh_u8* p = (const xxh_u8*)input;
2183*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const bEnd = p + len;
2184*cc02d7e2SAndroid Build Coastguard Worker
2185*cc02d7e2SAndroid Build Coastguard Worker state->total_len_32 += (XXH32_hash_t)len;
2186*cc02d7e2SAndroid Build Coastguard Worker state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
2187*cc02d7e2SAndroid Build Coastguard Worker
2188*cc02d7e2SAndroid Build Coastguard Worker if (state->memsize + len < 16) { /* fill in tmp buffer */
2189*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
2190*cc02d7e2SAndroid Build Coastguard Worker state->memsize += (XXH32_hash_t)len;
2191*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2192*cc02d7e2SAndroid Build Coastguard Worker }
2193*cc02d7e2SAndroid Build Coastguard Worker
2194*cc02d7e2SAndroid Build Coastguard Worker if (state->memsize) { /* some data left from previous update */
2195*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
2196*cc02d7e2SAndroid Build Coastguard Worker { const xxh_u32* p32 = state->mem32;
2197*cc02d7e2SAndroid Build Coastguard Worker state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
2198*cc02d7e2SAndroid Build Coastguard Worker state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
2199*cc02d7e2SAndroid Build Coastguard Worker state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
2200*cc02d7e2SAndroid Build Coastguard Worker state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
2201*cc02d7e2SAndroid Build Coastguard Worker }
2202*cc02d7e2SAndroid Build Coastguard Worker p += 16-state->memsize;
2203*cc02d7e2SAndroid Build Coastguard Worker state->memsize = 0;
2204*cc02d7e2SAndroid Build Coastguard Worker }
2205*cc02d7e2SAndroid Build Coastguard Worker
2206*cc02d7e2SAndroid Build Coastguard Worker if (p <= bEnd-16) {
2207*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const limit = bEnd - 16;
2208*cc02d7e2SAndroid Build Coastguard Worker
2209*cc02d7e2SAndroid Build Coastguard Worker do {
2210*cc02d7e2SAndroid Build Coastguard Worker state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
2211*cc02d7e2SAndroid Build Coastguard Worker state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
2212*cc02d7e2SAndroid Build Coastguard Worker state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
2213*cc02d7e2SAndroid Build Coastguard Worker state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
2214*cc02d7e2SAndroid Build Coastguard Worker } while (p<=limit);
2215*cc02d7e2SAndroid Build Coastguard Worker
2216*cc02d7e2SAndroid Build Coastguard Worker }
2217*cc02d7e2SAndroid Build Coastguard Worker
2218*cc02d7e2SAndroid Build Coastguard Worker if (p < bEnd) {
2219*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
2220*cc02d7e2SAndroid Build Coastguard Worker state->memsize = (unsigned)(bEnd-p);
2221*cc02d7e2SAndroid Build Coastguard Worker }
2222*cc02d7e2SAndroid Build Coastguard Worker }
2223*cc02d7e2SAndroid Build Coastguard Worker
2224*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2225*cc02d7e2SAndroid Build Coastguard Worker }
2226*cc02d7e2SAndroid Build Coastguard Worker
2227*cc02d7e2SAndroid Build Coastguard Worker
2228*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32_digest(const XXH32_state_t * state)2229*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
2230*cc02d7e2SAndroid Build Coastguard Worker {
2231*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 h32;
2232*cc02d7e2SAndroid Build Coastguard Worker
2233*cc02d7e2SAndroid Build Coastguard Worker if (state->large_len) {
2234*cc02d7e2SAndroid Build Coastguard Worker h32 = XXH_rotl32(state->v[0], 1)
2235*cc02d7e2SAndroid Build Coastguard Worker + XXH_rotl32(state->v[1], 7)
2236*cc02d7e2SAndroid Build Coastguard Worker + XXH_rotl32(state->v[2], 12)
2237*cc02d7e2SAndroid Build Coastguard Worker + XXH_rotl32(state->v[3], 18);
2238*cc02d7e2SAndroid Build Coastguard Worker } else {
2239*cc02d7e2SAndroid Build Coastguard Worker h32 = state->v[2] /* == seed */ + XXH_PRIME32_5;
2240*cc02d7e2SAndroid Build Coastguard Worker }
2241*cc02d7e2SAndroid Build Coastguard Worker
2242*cc02d7e2SAndroid Build Coastguard Worker h32 += state->total_len_32;
2243*cc02d7e2SAndroid Build Coastguard Worker
2244*cc02d7e2SAndroid Build Coastguard Worker return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
2245*cc02d7e2SAndroid Build Coastguard Worker }
2246*cc02d7e2SAndroid Build Coastguard Worker
2247*cc02d7e2SAndroid Build Coastguard Worker
2248*cc02d7e2SAndroid Build Coastguard Worker /******* Canonical representation *******/
2249*cc02d7e2SAndroid Build Coastguard Worker
2250*cc02d7e2SAndroid Build Coastguard Worker /*!
2251*cc02d7e2SAndroid Build Coastguard Worker * @ingroup xxh32_family
2252*cc02d7e2SAndroid Build Coastguard Worker * The default return values from XXH functions are unsigned 32 and 64 bit
2253*cc02d7e2SAndroid Build Coastguard Worker * integers.
2254*cc02d7e2SAndroid Build Coastguard Worker *
2255*cc02d7e2SAndroid Build Coastguard Worker * The canonical representation uses big endian convention, the same convention
2256*cc02d7e2SAndroid Build Coastguard Worker * as human-readable numbers (large digits first).
2257*cc02d7e2SAndroid Build Coastguard Worker *
2258*cc02d7e2SAndroid Build Coastguard Worker * This way, hash values can be written into a file or buffer, remaining
2259*cc02d7e2SAndroid Build Coastguard Worker * comparable across different systems.
2260*cc02d7e2SAndroid Build Coastguard Worker *
2261*cc02d7e2SAndroid Build Coastguard Worker * The following functions allow transformation of hash values to and from their
2262*cc02d7e2SAndroid Build Coastguard Worker * canonical format.
2263*cc02d7e2SAndroid Build Coastguard Worker */
XXH32_canonicalFromHash(XXH32_canonical_t * dst,XXH32_hash_t hash)2264*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
2265*cc02d7e2SAndroid Build Coastguard Worker {
2266*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
2267*cc02d7e2SAndroid Build Coastguard Worker if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
2268*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dst, &hash, sizeof(*dst));
2269*cc02d7e2SAndroid Build Coastguard Worker }
2270*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh32_family */
XXH32_hashFromCanonical(const XXH32_canonical_t * src)2271*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
2272*cc02d7e2SAndroid Build Coastguard Worker {
2273*cc02d7e2SAndroid Build Coastguard Worker return XXH_readBE32(src);
2274*cc02d7e2SAndroid Build Coastguard Worker }
2275*cc02d7e2SAndroid Build Coastguard Worker
2276*cc02d7e2SAndroid Build Coastguard Worker
2277*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_NO_LONG_LONG
2278*cc02d7e2SAndroid Build Coastguard Worker
2279*cc02d7e2SAndroid Build Coastguard Worker /* *******************************************************************
2280*cc02d7e2SAndroid Build Coastguard Worker * 64-bit hash functions
2281*cc02d7e2SAndroid Build Coastguard Worker *********************************************************************/
2282*cc02d7e2SAndroid Build Coastguard Worker /*!
2283*cc02d7e2SAndroid Build Coastguard Worker * @}
2284*cc02d7e2SAndroid Build Coastguard Worker * @ingroup impl
2285*cc02d7e2SAndroid Build Coastguard Worker * @{
2286*cc02d7e2SAndroid Build Coastguard Worker */
2287*cc02d7e2SAndroid Build Coastguard Worker /******* Memory access *******/
2288*cc02d7e2SAndroid Build Coastguard Worker
2289*cc02d7e2SAndroid Build Coastguard Worker typedef XXH64_hash_t xxh_u64;
2290*cc02d7e2SAndroid Build Coastguard Worker
2291*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
2292*cc02d7e2SAndroid Build Coastguard Worker # define U64 xxh_u64
2293*cc02d7e2SAndroid Build Coastguard Worker #endif
2294*cc02d7e2SAndroid Build Coastguard Worker
2295*cc02d7e2SAndroid Build Coastguard Worker #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2296*cc02d7e2SAndroid Build Coastguard Worker /*
2297*cc02d7e2SAndroid Build Coastguard Worker * Manual byteshift. Best for old compilers which don't inline memcpy.
2298*cc02d7e2SAndroid Build Coastguard Worker * We actually directly use XXH_readLE64 and XXH_readBE64.
2299*cc02d7e2SAndroid Build Coastguard Worker */
2300*cc02d7e2SAndroid Build Coastguard Worker #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
2301*cc02d7e2SAndroid Build Coastguard Worker
2302*cc02d7e2SAndroid Build Coastguard Worker /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
XXH_read64(const void * memPtr)2303*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH_read64(const void* memPtr)
2304*cc02d7e2SAndroid Build Coastguard Worker {
2305*cc02d7e2SAndroid Build Coastguard Worker return *(const xxh_u64*) memPtr;
2306*cc02d7e2SAndroid Build Coastguard Worker }
2307*cc02d7e2SAndroid Build Coastguard Worker
2308*cc02d7e2SAndroid Build Coastguard Worker #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
2309*cc02d7e2SAndroid Build Coastguard Worker
2310*cc02d7e2SAndroid Build Coastguard Worker /*
2311*cc02d7e2SAndroid Build Coastguard Worker * __pack instructions are safer, but compiler specific, hence potentially
2312*cc02d7e2SAndroid Build Coastguard Worker * problematic for some compilers.
2313*cc02d7e2SAndroid Build Coastguard Worker *
2314*cc02d7e2SAndroid Build Coastguard Worker * Currently only defined for GCC and ICC.
2315*cc02d7e2SAndroid Build Coastguard Worker */
2316*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
2317*cc02d7e2SAndroid Build Coastguard Worker typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64;
2318*cc02d7e2SAndroid Build Coastguard Worker #endif
XXH_read64(const void * ptr)2319*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH_read64(const void* ptr)
2320*cc02d7e2SAndroid Build Coastguard Worker {
2321*cc02d7e2SAndroid Build Coastguard Worker typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64;
2322*cc02d7e2SAndroid Build Coastguard Worker return ((const xxh_unalign64*)ptr)->u64;
2323*cc02d7e2SAndroid Build Coastguard Worker }
2324*cc02d7e2SAndroid Build Coastguard Worker
2325*cc02d7e2SAndroid Build Coastguard Worker #else
2326*cc02d7e2SAndroid Build Coastguard Worker
2327*cc02d7e2SAndroid Build Coastguard Worker /*
2328*cc02d7e2SAndroid Build Coastguard Worker * Portable and safe solution. Generally efficient.
2329*cc02d7e2SAndroid Build Coastguard Worker * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
2330*cc02d7e2SAndroid Build Coastguard Worker */
XXH_read64(const void * memPtr)2331*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH_read64(const void* memPtr)
2332*cc02d7e2SAndroid Build Coastguard Worker {
2333*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 val;
2334*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(&val, memPtr, sizeof(val));
2335*cc02d7e2SAndroid Build Coastguard Worker return val;
2336*cc02d7e2SAndroid Build Coastguard Worker }
2337*cc02d7e2SAndroid Build Coastguard Worker
2338*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
2339*cc02d7e2SAndroid Build Coastguard Worker
2340*cc02d7e2SAndroid Build Coastguard Worker #if defined(_MSC_VER) /* Visual Studio */
2341*cc02d7e2SAndroid Build Coastguard Worker # define XXH_swap64 _byteswap_uint64
2342*cc02d7e2SAndroid Build Coastguard Worker #elif XXH_GCC_VERSION >= 403
2343*cc02d7e2SAndroid Build Coastguard Worker # define XXH_swap64 __builtin_bswap64
2344*cc02d7e2SAndroid Build Coastguard Worker #else
XXH_swap64(xxh_u64 x)2345*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH_swap64(xxh_u64 x)
2346*cc02d7e2SAndroid Build Coastguard Worker {
2347*cc02d7e2SAndroid Build Coastguard Worker return ((x << 56) & 0xff00000000000000ULL) |
2348*cc02d7e2SAndroid Build Coastguard Worker ((x << 40) & 0x00ff000000000000ULL) |
2349*cc02d7e2SAndroid Build Coastguard Worker ((x << 24) & 0x0000ff0000000000ULL) |
2350*cc02d7e2SAndroid Build Coastguard Worker ((x << 8) & 0x000000ff00000000ULL) |
2351*cc02d7e2SAndroid Build Coastguard Worker ((x >> 8) & 0x00000000ff000000ULL) |
2352*cc02d7e2SAndroid Build Coastguard Worker ((x >> 24) & 0x0000000000ff0000ULL) |
2353*cc02d7e2SAndroid Build Coastguard Worker ((x >> 40) & 0x000000000000ff00ULL) |
2354*cc02d7e2SAndroid Build Coastguard Worker ((x >> 56) & 0x00000000000000ffULL);
2355*cc02d7e2SAndroid Build Coastguard Worker }
2356*cc02d7e2SAndroid Build Coastguard Worker #endif
2357*cc02d7e2SAndroid Build Coastguard Worker
2358*cc02d7e2SAndroid Build Coastguard Worker
2359*cc02d7e2SAndroid Build Coastguard Worker /* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */
2360*cc02d7e2SAndroid Build Coastguard Worker #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2361*cc02d7e2SAndroid Build Coastguard Worker
XXH_readLE64(const void * memPtr)2362*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr)
2363*cc02d7e2SAndroid Build Coastguard Worker {
2364*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
2365*cc02d7e2SAndroid Build Coastguard Worker return bytePtr[0]
2366*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[1] << 8)
2367*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[2] << 16)
2368*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[3] << 24)
2369*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[4] << 32)
2370*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[5] << 40)
2371*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[6] << 48)
2372*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[7] << 56);
2373*cc02d7e2SAndroid Build Coastguard Worker }
2374*cc02d7e2SAndroid Build Coastguard Worker
XXH_readBE64(const void * memPtr)2375*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr)
2376*cc02d7e2SAndroid Build Coastguard Worker {
2377*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
2378*cc02d7e2SAndroid Build Coastguard Worker return bytePtr[7]
2379*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[6] << 8)
2380*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[5] << 16)
2381*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[4] << 24)
2382*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[3] << 32)
2383*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[2] << 40)
2384*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[1] << 48)
2385*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u64)bytePtr[0] << 56);
2386*cc02d7e2SAndroid Build Coastguard Worker }
2387*cc02d7e2SAndroid Build Coastguard Worker
2388*cc02d7e2SAndroid Build Coastguard Worker #else
XXH_readLE64(const void * ptr)2389*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr)
2390*cc02d7e2SAndroid Build Coastguard Worker {
2391*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
2392*cc02d7e2SAndroid Build Coastguard Worker }
2393*cc02d7e2SAndroid Build Coastguard Worker
XXH_readBE64(const void * ptr)2394*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH_readBE64(const void* ptr)
2395*cc02d7e2SAndroid Build Coastguard Worker {
2396*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
2397*cc02d7e2SAndroid Build Coastguard Worker }
2398*cc02d7e2SAndroid Build Coastguard Worker #endif
2399*cc02d7e2SAndroid Build Coastguard Worker
2400*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64
XXH_readLE64_align(const void * ptr,XXH_alignment align)2401*cc02d7e2SAndroid Build Coastguard Worker XXH_readLE64_align(const void* ptr, XXH_alignment align)
2402*cc02d7e2SAndroid Build Coastguard Worker {
2403*cc02d7e2SAndroid Build Coastguard Worker if (align==XXH_unaligned)
2404*cc02d7e2SAndroid Build Coastguard Worker return XXH_readLE64(ptr);
2405*cc02d7e2SAndroid Build Coastguard Worker else
2406*cc02d7e2SAndroid Build Coastguard Worker return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
2407*cc02d7e2SAndroid Build Coastguard Worker }
2408*cc02d7e2SAndroid Build Coastguard Worker
2409*cc02d7e2SAndroid Build Coastguard Worker
2410*cc02d7e2SAndroid Build Coastguard Worker /******* xxh64 *******/
2411*cc02d7e2SAndroid Build Coastguard Worker /*!
2412*cc02d7e2SAndroid Build Coastguard Worker * @}
2413*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh64_impl XXH64 implementation
2414*cc02d7e2SAndroid Build Coastguard Worker * @ingroup impl
2415*cc02d7e2SAndroid Build Coastguard Worker * @{
2416*cc02d7e2SAndroid Build Coastguard Worker */
2417*cc02d7e2SAndroid Build Coastguard Worker /* #define rather that static const, to be used as initializers */
2418*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME64_1 0x9E3779B185EBCA87ULL /*!< 0b1001111000110111011110011011000110000101111010111100101010000111 */
2419*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL /*!< 0b1100001010110010101011100011110100100111110101001110101101001111 */
2420*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME64_3 0x165667B19E3779F9ULL /*!< 0b0001011001010110011001111011000110011110001101110111100111111001 */
2421*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL /*!< 0b1000010111101011110010100111011111000010101100101010111001100011 */
2422*cc02d7e2SAndroid Build Coastguard Worker #define XXH_PRIME64_5 0x27D4EB2F165667C5ULL /*!< 0b0010011111010100111010110010111100010110010101100110011111000101 */
2423*cc02d7e2SAndroid Build Coastguard Worker
2424*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
2425*cc02d7e2SAndroid Build Coastguard Worker # define PRIME64_1 XXH_PRIME64_1
2426*cc02d7e2SAndroid Build Coastguard Worker # define PRIME64_2 XXH_PRIME64_2
2427*cc02d7e2SAndroid Build Coastguard Worker # define PRIME64_3 XXH_PRIME64_3
2428*cc02d7e2SAndroid Build Coastguard Worker # define PRIME64_4 XXH_PRIME64_4
2429*cc02d7e2SAndroid Build Coastguard Worker # define PRIME64_5 XXH_PRIME64_5
2430*cc02d7e2SAndroid Build Coastguard Worker #endif
2431*cc02d7e2SAndroid Build Coastguard Worker
XXH64_round(xxh_u64 acc,xxh_u64 input)2432*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
2433*cc02d7e2SAndroid Build Coastguard Worker {
2434*cc02d7e2SAndroid Build Coastguard Worker acc += input * XXH_PRIME64_2;
2435*cc02d7e2SAndroid Build Coastguard Worker acc = XXH_rotl64(acc, 31);
2436*cc02d7e2SAndroid Build Coastguard Worker acc *= XXH_PRIME64_1;
2437*cc02d7e2SAndroid Build Coastguard Worker return acc;
2438*cc02d7e2SAndroid Build Coastguard Worker }
2439*cc02d7e2SAndroid Build Coastguard Worker
XXH64_mergeRound(xxh_u64 acc,xxh_u64 val)2440*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
2441*cc02d7e2SAndroid Build Coastguard Worker {
2442*cc02d7e2SAndroid Build Coastguard Worker val = XXH64_round(0, val);
2443*cc02d7e2SAndroid Build Coastguard Worker acc ^= val;
2444*cc02d7e2SAndroid Build Coastguard Worker acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
2445*cc02d7e2SAndroid Build Coastguard Worker return acc;
2446*cc02d7e2SAndroid Build Coastguard Worker }
2447*cc02d7e2SAndroid Build Coastguard Worker
XXH64_avalanche(xxh_u64 h64)2448*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64 XXH64_avalanche(xxh_u64 h64)
2449*cc02d7e2SAndroid Build Coastguard Worker {
2450*cc02d7e2SAndroid Build Coastguard Worker h64 ^= h64 >> 33;
2451*cc02d7e2SAndroid Build Coastguard Worker h64 *= XXH_PRIME64_2;
2452*cc02d7e2SAndroid Build Coastguard Worker h64 ^= h64 >> 29;
2453*cc02d7e2SAndroid Build Coastguard Worker h64 *= XXH_PRIME64_3;
2454*cc02d7e2SAndroid Build Coastguard Worker h64 ^= h64 >> 32;
2455*cc02d7e2SAndroid Build Coastguard Worker return h64;
2456*cc02d7e2SAndroid Build Coastguard Worker }
2457*cc02d7e2SAndroid Build Coastguard Worker
2458*cc02d7e2SAndroid Build Coastguard Worker
2459*cc02d7e2SAndroid Build Coastguard Worker #define XXH_get64bits(p) XXH_readLE64_align(p, align)
2460*cc02d7e2SAndroid Build Coastguard Worker
2461*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64
XXH64_finalize(xxh_u64 h64,const xxh_u8 * ptr,size_t len,XXH_alignment align)2462*cc02d7e2SAndroid Build Coastguard Worker XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2463*cc02d7e2SAndroid Build Coastguard Worker {
2464*cc02d7e2SAndroid Build Coastguard Worker if (ptr==NULL) XXH_ASSERT(len == 0);
2465*cc02d7e2SAndroid Build Coastguard Worker len &= 31;
2466*cc02d7e2SAndroid Build Coastguard Worker while (len >= 8) {
2467*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
2468*cc02d7e2SAndroid Build Coastguard Worker ptr += 8;
2469*cc02d7e2SAndroid Build Coastguard Worker h64 ^= k1;
2470*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
2471*cc02d7e2SAndroid Build Coastguard Worker len -= 8;
2472*cc02d7e2SAndroid Build Coastguard Worker }
2473*cc02d7e2SAndroid Build Coastguard Worker if (len >= 4) {
2474*cc02d7e2SAndroid Build Coastguard Worker h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
2475*cc02d7e2SAndroid Build Coastguard Worker ptr += 4;
2476*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
2477*cc02d7e2SAndroid Build Coastguard Worker len -= 4;
2478*cc02d7e2SAndroid Build Coastguard Worker }
2479*cc02d7e2SAndroid Build Coastguard Worker while (len > 0) {
2480*cc02d7e2SAndroid Build Coastguard Worker h64 ^= (*ptr++) * XXH_PRIME64_5;
2481*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1;
2482*cc02d7e2SAndroid Build Coastguard Worker --len;
2483*cc02d7e2SAndroid Build Coastguard Worker }
2484*cc02d7e2SAndroid Build Coastguard Worker return XXH64_avalanche(h64);
2485*cc02d7e2SAndroid Build Coastguard Worker }
2486*cc02d7e2SAndroid Build Coastguard Worker
2487*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
2488*cc02d7e2SAndroid Build Coastguard Worker # define PROCESS1_64 XXH_PROCESS1_64
2489*cc02d7e2SAndroid Build Coastguard Worker # define PROCESS4_64 XXH_PROCESS4_64
2490*cc02d7e2SAndroid Build Coastguard Worker # define PROCESS8_64 XXH_PROCESS8_64
2491*cc02d7e2SAndroid Build Coastguard Worker #else
2492*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PROCESS1_64
2493*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PROCESS4_64
2494*cc02d7e2SAndroid Build Coastguard Worker # undef XXH_PROCESS8_64
2495*cc02d7e2SAndroid Build Coastguard Worker #endif
2496*cc02d7e2SAndroid Build Coastguard Worker
2497*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64
XXH64_endian_align(const xxh_u8 * input,size_t len,xxh_u64 seed,XXH_alignment align)2498*cc02d7e2SAndroid Build Coastguard Worker XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
2499*cc02d7e2SAndroid Build Coastguard Worker {
2500*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 h64;
2501*cc02d7e2SAndroid Build Coastguard Worker if (input==NULL) XXH_ASSERT(len == 0);
2502*cc02d7e2SAndroid Build Coastguard Worker
2503*cc02d7e2SAndroid Build Coastguard Worker if (len>=32) {
2504*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const bEnd = input + len;
2505*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const limit = bEnd - 31;
2506*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2507*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 v2 = seed + XXH_PRIME64_2;
2508*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 v3 = seed + 0;
2509*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 v4 = seed - XXH_PRIME64_1;
2510*cc02d7e2SAndroid Build Coastguard Worker
2511*cc02d7e2SAndroid Build Coastguard Worker do {
2512*cc02d7e2SAndroid Build Coastguard Worker v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
2513*cc02d7e2SAndroid Build Coastguard Worker v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
2514*cc02d7e2SAndroid Build Coastguard Worker v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
2515*cc02d7e2SAndroid Build Coastguard Worker v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
2516*cc02d7e2SAndroid Build Coastguard Worker } while (input<limit);
2517*cc02d7e2SAndroid Build Coastguard Worker
2518*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
2519*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, v1);
2520*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, v2);
2521*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, v3);
2522*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, v4);
2523*cc02d7e2SAndroid Build Coastguard Worker
2524*cc02d7e2SAndroid Build Coastguard Worker } else {
2525*cc02d7e2SAndroid Build Coastguard Worker h64 = seed + XXH_PRIME64_5;
2526*cc02d7e2SAndroid Build Coastguard Worker }
2527*cc02d7e2SAndroid Build Coastguard Worker
2528*cc02d7e2SAndroid Build Coastguard Worker h64 += (xxh_u64) len;
2529*cc02d7e2SAndroid Build Coastguard Worker
2530*cc02d7e2SAndroid Build Coastguard Worker return XXH64_finalize(h64, input, len, align);
2531*cc02d7e2SAndroid Build Coastguard Worker }
2532*cc02d7e2SAndroid Build Coastguard Worker
2533*cc02d7e2SAndroid Build Coastguard Worker
2534*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64(const void * input,size_t len,XXH64_hash_t seed)2535*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
2536*cc02d7e2SAndroid Build Coastguard Worker {
2537*cc02d7e2SAndroid Build Coastguard Worker #if 0
2538*cc02d7e2SAndroid Build Coastguard Worker /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2539*cc02d7e2SAndroid Build Coastguard Worker XXH64_state_t state;
2540*cc02d7e2SAndroid Build Coastguard Worker XXH64_reset(&state, seed);
2541*cc02d7e2SAndroid Build Coastguard Worker XXH64_update(&state, (const xxh_u8*)input, len);
2542*cc02d7e2SAndroid Build Coastguard Worker return XXH64_digest(&state);
2543*cc02d7e2SAndroid Build Coastguard Worker #else
2544*cc02d7e2SAndroid Build Coastguard Worker if (XXH_FORCE_ALIGN_CHECK) {
2545*cc02d7e2SAndroid Build Coastguard Worker if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
2546*cc02d7e2SAndroid Build Coastguard Worker return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
2547*cc02d7e2SAndroid Build Coastguard Worker } }
2548*cc02d7e2SAndroid Build Coastguard Worker
2549*cc02d7e2SAndroid Build Coastguard Worker return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
2550*cc02d7e2SAndroid Build Coastguard Worker
2551*cc02d7e2SAndroid Build Coastguard Worker #endif
2552*cc02d7e2SAndroid Build Coastguard Worker }
2553*cc02d7e2SAndroid Build Coastguard Worker
2554*cc02d7e2SAndroid Build Coastguard Worker /******* Hash Streaming *******/
2555*cc02d7e2SAndroid Build Coastguard Worker
2556*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family*/
XXH64_createState(void)2557*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
2558*cc02d7e2SAndroid Build Coastguard Worker {
2559*cc02d7e2SAndroid Build Coastguard Worker return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
2560*cc02d7e2SAndroid Build Coastguard Worker }
2561*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_freeState(XXH64_state_t * statePtr)2562*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
2563*cc02d7e2SAndroid Build Coastguard Worker {
2564*cc02d7e2SAndroid Build Coastguard Worker XXH_free(statePtr);
2565*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2566*cc02d7e2SAndroid Build Coastguard Worker }
2567*cc02d7e2SAndroid Build Coastguard Worker
2568*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_copyState(XXH64_state_t * dstState,const XXH64_state_t * srcState)2569*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
2570*cc02d7e2SAndroid Build Coastguard Worker {
2571*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dstState, srcState, sizeof(*dstState));
2572*cc02d7e2SAndroid Build Coastguard Worker }
2573*cc02d7e2SAndroid Build Coastguard Worker
2574*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_reset(XXH64_state_t * statePtr,XXH64_hash_t seed)2575*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
2576*cc02d7e2SAndroid Build Coastguard Worker {
2577*cc02d7e2SAndroid Build Coastguard Worker XXH64_state_t state; /* use a local state to memcpy() in order to avoid strict-aliasing warnings */
2578*cc02d7e2SAndroid Build Coastguard Worker memset(&state, 0, sizeof(state));
2579*cc02d7e2SAndroid Build Coastguard Worker state.v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2580*cc02d7e2SAndroid Build Coastguard Worker state.v[1] = seed + XXH_PRIME64_2;
2581*cc02d7e2SAndroid Build Coastguard Worker state.v[2] = seed + 0;
2582*cc02d7e2SAndroid Build Coastguard Worker state.v[3] = seed - XXH_PRIME64_1;
2583*cc02d7e2SAndroid Build Coastguard Worker /* do not write into reserved64, might be removed in a future version */
2584*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved64));
2585*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2586*cc02d7e2SAndroid Build Coastguard Worker }
2587*cc02d7e2SAndroid Build Coastguard Worker
2588*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
2589*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH64_update(XXH64_state_t * state,const void * input,size_t len)2590*cc02d7e2SAndroid Build Coastguard Worker XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2591*cc02d7e2SAndroid Build Coastguard Worker {
2592*cc02d7e2SAndroid Build Coastguard Worker if (input==NULL) {
2593*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len == 0);
2594*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2595*cc02d7e2SAndroid Build Coastguard Worker }
2596*cc02d7e2SAndroid Build Coastguard Worker
2597*cc02d7e2SAndroid Build Coastguard Worker { const xxh_u8* p = (const xxh_u8*)input;
2598*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const bEnd = p + len;
2599*cc02d7e2SAndroid Build Coastguard Worker
2600*cc02d7e2SAndroid Build Coastguard Worker state->total_len += len;
2601*cc02d7e2SAndroid Build Coastguard Worker
2602*cc02d7e2SAndroid Build Coastguard Worker if (state->memsize + len < 32) { /* fill in tmp buffer */
2603*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
2604*cc02d7e2SAndroid Build Coastguard Worker state->memsize += (xxh_u32)len;
2605*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2606*cc02d7e2SAndroid Build Coastguard Worker }
2607*cc02d7e2SAndroid Build Coastguard Worker
2608*cc02d7e2SAndroid Build Coastguard Worker if (state->memsize) { /* tmp buffer is full */
2609*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
2610*cc02d7e2SAndroid Build Coastguard Worker state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
2611*cc02d7e2SAndroid Build Coastguard Worker state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
2612*cc02d7e2SAndroid Build Coastguard Worker state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
2613*cc02d7e2SAndroid Build Coastguard Worker state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
2614*cc02d7e2SAndroid Build Coastguard Worker p += 32 - state->memsize;
2615*cc02d7e2SAndroid Build Coastguard Worker state->memsize = 0;
2616*cc02d7e2SAndroid Build Coastguard Worker }
2617*cc02d7e2SAndroid Build Coastguard Worker
2618*cc02d7e2SAndroid Build Coastguard Worker if (p+32 <= bEnd) {
2619*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const limit = bEnd - 32;
2620*cc02d7e2SAndroid Build Coastguard Worker
2621*cc02d7e2SAndroid Build Coastguard Worker do {
2622*cc02d7e2SAndroid Build Coastguard Worker state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
2623*cc02d7e2SAndroid Build Coastguard Worker state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
2624*cc02d7e2SAndroid Build Coastguard Worker state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
2625*cc02d7e2SAndroid Build Coastguard Worker state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
2626*cc02d7e2SAndroid Build Coastguard Worker } while (p<=limit);
2627*cc02d7e2SAndroid Build Coastguard Worker
2628*cc02d7e2SAndroid Build Coastguard Worker }
2629*cc02d7e2SAndroid Build Coastguard Worker
2630*cc02d7e2SAndroid Build Coastguard Worker if (p < bEnd) {
2631*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
2632*cc02d7e2SAndroid Build Coastguard Worker state->memsize = (unsigned)(bEnd-p);
2633*cc02d7e2SAndroid Build Coastguard Worker }
2634*cc02d7e2SAndroid Build Coastguard Worker }
2635*cc02d7e2SAndroid Build Coastguard Worker
2636*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
2637*cc02d7e2SAndroid Build Coastguard Worker }
2638*cc02d7e2SAndroid Build Coastguard Worker
2639*cc02d7e2SAndroid Build Coastguard Worker
2640*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_digest(const XXH64_state_t * state)2641*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
2642*cc02d7e2SAndroid Build Coastguard Worker {
2643*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 h64;
2644*cc02d7e2SAndroid Build Coastguard Worker
2645*cc02d7e2SAndroid Build Coastguard Worker if (state->total_len >= 32) {
2646*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
2647*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, state->v[0]);
2648*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, state->v[1]);
2649*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, state->v[2]);
2650*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH64_mergeRound(h64, state->v[3]);
2651*cc02d7e2SAndroid Build Coastguard Worker } else {
2652*cc02d7e2SAndroid Build Coastguard Worker h64 = state->v[2] /*seed*/ + XXH_PRIME64_5;
2653*cc02d7e2SAndroid Build Coastguard Worker }
2654*cc02d7e2SAndroid Build Coastguard Worker
2655*cc02d7e2SAndroid Build Coastguard Worker h64 += (xxh_u64) state->total_len;
2656*cc02d7e2SAndroid Build Coastguard Worker
2657*cc02d7e2SAndroid Build Coastguard Worker return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
2658*cc02d7e2SAndroid Build Coastguard Worker }
2659*cc02d7e2SAndroid Build Coastguard Worker
2660*cc02d7e2SAndroid Build Coastguard Worker
2661*cc02d7e2SAndroid Build Coastguard Worker /******* Canonical representation *******/
2662*cc02d7e2SAndroid Build Coastguard Worker
2663*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_canonicalFromHash(XXH64_canonical_t * dst,XXH64_hash_t hash)2664*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
2665*cc02d7e2SAndroid Build Coastguard Worker {
2666*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
2667*cc02d7e2SAndroid Build Coastguard Worker if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
2668*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dst, &hash, sizeof(*dst));
2669*cc02d7e2SAndroid Build Coastguard Worker }
2670*cc02d7e2SAndroid Build Coastguard Worker
2671*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh64_family */
XXH64_hashFromCanonical(const XXH64_canonical_t * src)2672*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
2673*cc02d7e2SAndroid Build Coastguard Worker {
2674*cc02d7e2SAndroid Build Coastguard Worker return XXH_readBE64(src);
2675*cc02d7e2SAndroid Build Coastguard Worker }
2676*cc02d7e2SAndroid Build Coastguard Worker
2677*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_NO_XXH3
2678*cc02d7e2SAndroid Build Coastguard Worker
2679*cc02d7e2SAndroid Build Coastguard Worker /* *********************************************************************
2680*cc02d7e2SAndroid Build Coastguard Worker * XXH3
2681*cc02d7e2SAndroid Build Coastguard Worker * New generation hash designed for speed on small keys and vectorization
2682*cc02d7e2SAndroid Build Coastguard Worker ************************************************************************ */
2683*cc02d7e2SAndroid Build Coastguard Worker /*!
2684*cc02d7e2SAndroid Build Coastguard Worker * @}
2685*cc02d7e2SAndroid Build Coastguard Worker * @defgroup xxh3_impl XXH3 implementation
2686*cc02d7e2SAndroid Build Coastguard Worker * @ingroup impl
2687*cc02d7e2SAndroid Build Coastguard Worker * @{
2688*cc02d7e2SAndroid Build Coastguard Worker */
2689*cc02d7e2SAndroid Build Coastguard Worker
2690*cc02d7e2SAndroid Build Coastguard Worker /* === Compiler specifics === */
2691*cc02d7e2SAndroid Build Coastguard Worker
2692*cc02d7e2SAndroid Build Coastguard Worker #if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
2693*cc02d7e2SAndroid Build Coastguard Worker # define XXH_RESTRICT /* disable */
2694*cc02d7e2SAndroid Build Coastguard Worker #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
2695*cc02d7e2SAndroid Build Coastguard Worker # define XXH_RESTRICT restrict
2696*cc02d7e2SAndroid Build Coastguard Worker #else
2697*cc02d7e2SAndroid Build Coastguard Worker /* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */
2698*cc02d7e2SAndroid Build Coastguard Worker # define XXH_RESTRICT /* disable */
2699*cc02d7e2SAndroid Build Coastguard Worker #endif
2700*cc02d7e2SAndroid Build Coastguard Worker
2701*cc02d7e2SAndroid Build Coastguard Worker #if (defined(__GNUC__) && (__GNUC__ >= 3)) \
2702*cc02d7e2SAndroid Build Coastguard Worker || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
2703*cc02d7e2SAndroid Build Coastguard Worker || defined(__clang__)
2704*cc02d7e2SAndroid Build Coastguard Worker # define XXH_likely(x) __builtin_expect(x, 1)
2705*cc02d7e2SAndroid Build Coastguard Worker # define XXH_unlikely(x) __builtin_expect(x, 0)
2706*cc02d7e2SAndroid Build Coastguard Worker #else
2707*cc02d7e2SAndroid Build Coastguard Worker # define XXH_likely(x) (x)
2708*cc02d7e2SAndroid Build Coastguard Worker # define XXH_unlikely(x) (x)
2709*cc02d7e2SAndroid Build Coastguard Worker #endif
2710*cc02d7e2SAndroid Build Coastguard Worker
2711*cc02d7e2SAndroid Build Coastguard Worker #if defined(__GNUC__)
2712*cc02d7e2SAndroid Build Coastguard Worker # if defined(__AVX2__)
2713*cc02d7e2SAndroid Build Coastguard Worker # include <immintrin.h>
2714*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__SSE2__)
2715*cc02d7e2SAndroid Build Coastguard Worker # include <emmintrin.h>
2716*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__ARM_NEON__) || defined(__ARM_NEON)
2717*cc02d7e2SAndroid Build Coastguard Worker # define inline __inline__ /* circumvent a clang bug */
2718*cc02d7e2SAndroid Build Coastguard Worker # include <arm_neon.h>
2719*cc02d7e2SAndroid Build Coastguard Worker # undef inline
2720*cc02d7e2SAndroid Build Coastguard Worker # endif
2721*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
2722*cc02d7e2SAndroid Build Coastguard Worker # include <intrin.h>
2723*cc02d7e2SAndroid Build Coastguard Worker #endif
2724*cc02d7e2SAndroid Build Coastguard Worker
2725*cc02d7e2SAndroid Build Coastguard Worker /*
2726*cc02d7e2SAndroid Build Coastguard Worker * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
2727*cc02d7e2SAndroid Build Coastguard Worker * remaining a true 64-bit/128-bit hash function.
2728*cc02d7e2SAndroid Build Coastguard Worker *
2729*cc02d7e2SAndroid Build Coastguard Worker * This is done by prioritizing a subset of 64-bit operations that can be
2730*cc02d7e2SAndroid Build Coastguard Worker * emulated without too many steps on the average 32-bit machine.
2731*cc02d7e2SAndroid Build Coastguard Worker *
2732*cc02d7e2SAndroid Build Coastguard Worker * For example, these two lines seem similar, and run equally fast on 64-bit:
2733*cc02d7e2SAndroid Build Coastguard Worker *
2734*cc02d7e2SAndroid Build Coastguard Worker * xxh_u64 x;
2735*cc02d7e2SAndroid Build Coastguard Worker * x ^= (x >> 47); // good
2736*cc02d7e2SAndroid Build Coastguard Worker * x ^= (x >> 13); // bad
2737*cc02d7e2SAndroid Build Coastguard Worker *
2738*cc02d7e2SAndroid Build Coastguard Worker * However, to a 32-bit machine, there is a major difference.
2739*cc02d7e2SAndroid Build Coastguard Worker *
2740*cc02d7e2SAndroid Build Coastguard Worker * x ^= (x >> 47) looks like this:
2741*cc02d7e2SAndroid Build Coastguard Worker *
2742*cc02d7e2SAndroid Build Coastguard Worker * x.lo ^= (x.hi >> (47 - 32));
2743*cc02d7e2SAndroid Build Coastguard Worker *
2744*cc02d7e2SAndroid Build Coastguard Worker * while x ^= (x >> 13) looks like this:
2745*cc02d7e2SAndroid Build Coastguard Worker *
2746*cc02d7e2SAndroid Build Coastguard Worker * // note: funnel shifts are not usually cheap.
2747*cc02d7e2SAndroid Build Coastguard Worker * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
2748*cc02d7e2SAndroid Build Coastguard Worker * x.hi ^= (x.hi >> 13);
2749*cc02d7e2SAndroid Build Coastguard Worker *
2750*cc02d7e2SAndroid Build Coastguard Worker * The first one is significantly faster than the second, simply because the
2751*cc02d7e2SAndroid Build Coastguard Worker * shift is larger than 32. This means:
2752*cc02d7e2SAndroid Build Coastguard Worker * - All the bits we need are in the upper 32 bits, so we can ignore the lower
2753*cc02d7e2SAndroid Build Coastguard Worker * 32 bits in the shift.
2754*cc02d7e2SAndroid Build Coastguard Worker * - The shift result will always fit in the lower 32 bits, and therefore,
2755*cc02d7e2SAndroid Build Coastguard Worker * we can ignore the upper 32 bits in the xor.
2756*cc02d7e2SAndroid Build Coastguard Worker *
2757*cc02d7e2SAndroid Build Coastguard Worker * Thanks to this optimization, XXH3 only requires these features to be efficient:
2758*cc02d7e2SAndroid Build Coastguard Worker *
2759*cc02d7e2SAndroid Build Coastguard Worker * - Usable unaligned access
2760*cc02d7e2SAndroid Build Coastguard Worker * - A 32-bit or 64-bit ALU
2761*cc02d7e2SAndroid Build Coastguard Worker * - If 32-bit, a decent ADC instruction
2762*cc02d7e2SAndroid Build Coastguard Worker * - A 32 or 64-bit multiply with a 64-bit result
2763*cc02d7e2SAndroid Build Coastguard Worker * - For the 128-bit variant, a decent byteswap helps short inputs.
2764*cc02d7e2SAndroid Build Coastguard Worker *
2765*cc02d7e2SAndroid Build Coastguard Worker * The first two are already required by XXH32, and almost all 32-bit and 64-bit
2766*cc02d7e2SAndroid Build Coastguard Worker * platforms which can run XXH32 can run XXH3 efficiently.
2767*cc02d7e2SAndroid Build Coastguard Worker *
2768*cc02d7e2SAndroid Build Coastguard Worker * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
2769*cc02d7e2SAndroid Build Coastguard Worker * notable exception.
2770*cc02d7e2SAndroid Build Coastguard Worker *
2771*cc02d7e2SAndroid Build Coastguard Worker * First of all, Thumb-1 lacks support for the UMULL instruction which
2772*cc02d7e2SAndroid Build Coastguard Worker * performs the important long multiply. This means numerous __aeabi_lmul
2773*cc02d7e2SAndroid Build Coastguard Worker * calls.
2774*cc02d7e2SAndroid Build Coastguard Worker *
2775*cc02d7e2SAndroid Build Coastguard Worker * Second of all, the 8 functional registers are just not enough.
2776*cc02d7e2SAndroid Build Coastguard Worker * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
2777*cc02d7e2SAndroid Build Coastguard Worker * Lo registers, and this shuffling results in thousands more MOVs than A32.
2778*cc02d7e2SAndroid Build Coastguard Worker *
2779*cc02d7e2SAndroid Build Coastguard Worker * A32 and T32 don't have this limitation. They can access all 14 registers,
2780*cc02d7e2SAndroid Build Coastguard Worker * do a 32->64 multiply with UMULL, and the flexible operand allowing free
2781*cc02d7e2SAndroid Build Coastguard Worker * shifts is helpful, too.
2782*cc02d7e2SAndroid Build Coastguard Worker *
2783*cc02d7e2SAndroid Build Coastguard Worker * Therefore, we do a quick sanity check.
2784*cc02d7e2SAndroid Build Coastguard Worker *
2785*cc02d7e2SAndroid Build Coastguard Worker * If compiling Thumb-1 for a target which supports ARM instructions, we will
2786*cc02d7e2SAndroid Build Coastguard Worker * emit a warning, as it is not a "sane" platform to compile for.
2787*cc02d7e2SAndroid Build Coastguard Worker *
2788*cc02d7e2SAndroid Build Coastguard Worker * Usually, if this happens, it is because of an accident and you probably need
2789*cc02d7e2SAndroid Build Coastguard Worker * to specify -march, as you likely meant to compile for a newer architecture.
2790*cc02d7e2SAndroid Build Coastguard Worker *
2791*cc02d7e2SAndroid Build Coastguard Worker * Credit: large sections of the vectorial and asm source code paths
2792*cc02d7e2SAndroid Build Coastguard Worker * have been contributed by @easyaspi314
2793*cc02d7e2SAndroid Build Coastguard Worker */
2794*cc02d7e2SAndroid Build Coastguard Worker #if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM)
2795*cc02d7e2SAndroid Build Coastguard Worker # warning "XXH3 is highly inefficient without ARM or Thumb-2."
2796*cc02d7e2SAndroid Build Coastguard Worker #endif
2797*cc02d7e2SAndroid Build Coastguard Worker
2798*cc02d7e2SAndroid Build Coastguard Worker /* ==========================================
2799*cc02d7e2SAndroid Build Coastguard Worker * Vectorization detection
2800*cc02d7e2SAndroid Build Coastguard Worker * ========================================== */
2801*cc02d7e2SAndroid Build Coastguard Worker
2802*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_DOXYGEN
2803*cc02d7e2SAndroid Build Coastguard Worker /*!
2804*cc02d7e2SAndroid Build Coastguard Worker * @ingroup tuning
2805*cc02d7e2SAndroid Build Coastguard Worker * @brief Overrides the vectorization implementation chosen for XXH3.
2806*cc02d7e2SAndroid Build Coastguard Worker *
2807*cc02d7e2SAndroid Build Coastguard Worker * Can be defined to 0 to disable SIMD or any of the values mentioned in
2808*cc02d7e2SAndroid Build Coastguard Worker * @ref XXH_VECTOR_TYPE.
2809*cc02d7e2SAndroid Build Coastguard Worker *
2810*cc02d7e2SAndroid Build Coastguard Worker * If this is not defined, it uses predefined macros to determine the best
2811*cc02d7e2SAndroid Build Coastguard Worker * implementation.
2812*cc02d7e2SAndroid Build Coastguard Worker */
2813*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_SCALAR
2814*cc02d7e2SAndroid Build Coastguard Worker /*!
2815*cc02d7e2SAndroid Build Coastguard Worker * @ingroup tuning
2816*cc02d7e2SAndroid Build Coastguard Worker * @brief Possible values for @ref XXH_VECTOR.
2817*cc02d7e2SAndroid Build Coastguard Worker *
2818*cc02d7e2SAndroid Build Coastguard Worker * Note that these are actually implemented as macros.
2819*cc02d7e2SAndroid Build Coastguard Worker *
2820*cc02d7e2SAndroid Build Coastguard Worker * If this is not defined, it is detected automatically.
2821*cc02d7e2SAndroid Build Coastguard Worker * @ref XXH_X86DISPATCH overrides this.
2822*cc02d7e2SAndroid Build Coastguard Worker */
2823*cc02d7e2SAndroid Build Coastguard Worker enum XXH_VECTOR_TYPE /* fake enum */ {
2824*cc02d7e2SAndroid Build Coastguard Worker XXH_SCALAR = 0, /*!< Portable scalar version */
2825*cc02d7e2SAndroid Build Coastguard Worker XXH_SSE2 = 1, /*!<
2826*cc02d7e2SAndroid Build Coastguard Worker * SSE2 for Pentium 4, Opteron, all x86_64.
2827*cc02d7e2SAndroid Build Coastguard Worker *
2828*cc02d7e2SAndroid Build Coastguard Worker * @note SSE2 is also guaranteed on Windows 10, macOS, and
2829*cc02d7e2SAndroid Build Coastguard Worker * Android x86.
2830*cc02d7e2SAndroid Build Coastguard Worker */
2831*cc02d7e2SAndroid Build Coastguard Worker XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */
2832*cc02d7e2SAndroid Build Coastguard Worker XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */
2833*cc02d7e2SAndroid Build Coastguard Worker XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */
2834*cc02d7e2SAndroid Build Coastguard Worker XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */
2835*cc02d7e2SAndroid Build Coastguard Worker };
2836*cc02d7e2SAndroid Build Coastguard Worker /*!
2837*cc02d7e2SAndroid Build Coastguard Worker * @ingroup tuning
2838*cc02d7e2SAndroid Build Coastguard Worker * @brief Selects the minimum alignment for XXH3's accumulators.
2839*cc02d7e2SAndroid Build Coastguard Worker *
2840*cc02d7e2SAndroid Build Coastguard Worker * When using SIMD, this should match the alignment reqired for said vector
2841*cc02d7e2SAndroid Build Coastguard Worker * type, so, for example, 32 for AVX2.
2842*cc02d7e2SAndroid Build Coastguard Worker *
2843*cc02d7e2SAndroid Build Coastguard Worker * Default: Auto detected.
2844*cc02d7e2SAndroid Build Coastguard Worker */
2845*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 8
2846*cc02d7e2SAndroid Build Coastguard Worker #endif
2847*cc02d7e2SAndroid Build Coastguard Worker
2848*cc02d7e2SAndroid Build Coastguard Worker /* Actual definition */
2849*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_DOXYGEN
2850*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SCALAR 0
2851*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SSE2 1
2852*cc02d7e2SAndroid Build Coastguard Worker # define XXH_AVX2 2
2853*cc02d7e2SAndroid Build Coastguard Worker # define XXH_AVX512 3
2854*cc02d7e2SAndroid Build Coastguard Worker # define XXH_NEON 4
2855*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VSX 5
2856*cc02d7e2SAndroid Build Coastguard Worker #endif
2857*cc02d7e2SAndroid Build Coastguard Worker
2858*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_VECTOR /* can be defined on command line */
2859*cc02d7e2SAndroid Build Coastguard Worker # if defined(__AVX512F__)
2860*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_AVX512
2861*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__AVX2__)
2862*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_AVX2
2863*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
2864*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_SSE2
2865*cc02d7e2SAndroid Build Coastguard Worker # elif ( \
2866*cc02d7e2SAndroid Build Coastguard Worker defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
2867*cc02d7e2SAndroid Build Coastguard Worker || defined(_M_ARM64) || defined(_M_ARM_ARMV7VE) /* msvc */ \
2868*cc02d7e2SAndroid Build Coastguard Worker ) && ( \
2869*cc02d7e2SAndroid Build Coastguard Worker defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
2870*cc02d7e2SAndroid Build Coastguard Worker || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
2871*cc02d7e2SAndroid Build Coastguard Worker )
2872*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_NEON
2873*cc02d7e2SAndroid Build Coastguard Worker # elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
2874*cc02d7e2SAndroid Build Coastguard Worker || (defined(__s390x__) && defined(__VEC__)) \
2875*cc02d7e2SAndroid Build Coastguard Worker && defined(__GNUC__) /* TODO: IBM XL */
2876*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_VSX
2877*cc02d7e2SAndroid Build Coastguard Worker # else
2878*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VECTOR XXH_SCALAR
2879*cc02d7e2SAndroid Build Coastguard Worker # endif
2880*cc02d7e2SAndroid Build Coastguard Worker #endif
2881*cc02d7e2SAndroid Build Coastguard Worker
2882*cc02d7e2SAndroid Build Coastguard Worker /*
2883*cc02d7e2SAndroid Build Coastguard Worker * Controls the alignment of the accumulator,
2884*cc02d7e2SAndroid Build Coastguard Worker * for compatibility with aligned vector loads, which are usually faster.
2885*cc02d7e2SAndroid Build Coastguard Worker */
2886*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_ACC_ALIGN
2887*cc02d7e2SAndroid Build Coastguard Worker # if defined(XXH_X86DISPATCH)
2888*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */
2889*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_SCALAR /* scalar */
2890*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 8
2891*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_SSE2 /* sse2 */
2892*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 16
2893*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_AVX2 /* avx2 */
2894*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 32
2895*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_NEON /* neon */
2896*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 16
2897*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_VSX /* vsx */
2898*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 16
2899*cc02d7e2SAndroid Build Coastguard Worker # elif XXH_VECTOR == XXH_AVX512 /* avx512 */
2900*cc02d7e2SAndroid Build Coastguard Worker # define XXH_ACC_ALIGN 64
2901*cc02d7e2SAndroid Build Coastguard Worker # endif
2902*cc02d7e2SAndroid Build Coastguard Worker #endif
2903*cc02d7e2SAndroid Build Coastguard Worker
2904*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \
2905*cc02d7e2SAndroid Build Coastguard Worker || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512
2906*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SEC_ALIGN XXH_ACC_ALIGN
2907*cc02d7e2SAndroid Build Coastguard Worker #else
2908*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SEC_ALIGN 8
2909*cc02d7e2SAndroid Build Coastguard Worker #endif
2910*cc02d7e2SAndroid Build Coastguard Worker
2911*cc02d7e2SAndroid Build Coastguard Worker /*
2912*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
2913*cc02d7e2SAndroid Build Coastguard Worker * GCC usually generates the best code with -O3 for xxHash.
2914*cc02d7e2SAndroid Build Coastguard Worker *
2915*cc02d7e2SAndroid Build Coastguard Worker * However, when targeting AVX2, it is overzealous in its unrolling resulting
2916*cc02d7e2SAndroid Build Coastguard Worker * in code roughly 3/4 the speed of Clang.
2917*cc02d7e2SAndroid Build Coastguard Worker *
2918*cc02d7e2SAndroid Build Coastguard Worker * There are other issues, such as GCC splitting _mm256_loadu_si256 into
2919*cc02d7e2SAndroid Build Coastguard Worker * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which
2920*cc02d7e2SAndroid Build Coastguard Worker * only applies to Sandy and Ivy Bridge... which don't even support AVX2.
2921*cc02d7e2SAndroid Build Coastguard Worker *
2922*cc02d7e2SAndroid Build Coastguard Worker * That is why when compiling the AVX2 version, it is recommended to use either
2923*cc02d7e2SAndroid Build Coastguard Worker * -O2 -mavx2 -march=haswell
2924*cc02d7e2SAndroid Build Coastguard Worker * or
2925*cc02d7e2SAndroid Build Coastguard Worker * -O2 -mavx2 -mno-avx256-split-unaligned-load
2926*cc02d7e2SAndroid Build Coastguard Worker * for decent performance, or to use Clang instead.
2927*cc02d7e2SAndroid Build Coastguard Worker *
2928*cc02d7e2SAndroid Build Coastguard Worker * Fortunately, we can control the first one with a pragma that forces GCC into
2929*cc02d7e2SAndroid Build Coastguard Worker * -O2, but the other one we can't control without "failed to inline always
2930*cc02d7e2SAndroid Build Coastguard Worker * inline function due to target mismatch" warnings.
2931*cc02d7e2SAndroid Build Coastguard Worker */
2932*cc02d7e2SAndroid Build Coastguard Worker #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
2933*cc02d7e2SAndroid Build Coastguard Worker && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
2934*cc02d7e2SAndroid Build Coastguard Worker && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
2935*cc02d7e2SAndroid Build Coastguard Worker # pragma GCC push_options
2936*cc02d7e2SAndroid Build Coastguard Worker # pragma GCC optimize("-O2")
2937*cc02d7e2SAndroid Build Coastguard Worker #endif
2938*cc02d7e2SAndroid Build Coastguard Worker
2939*cc02d7e2SAndroid Build Coastguard Worker
2940*cc02d7e2SAndroid Build Coastguard Worker #if XXH_VECTOR == XXH_NEON
2941*cc02d7e2SAndroid Build Coastguard Worker /*
2942*cc02d7e2SAndroid Build Coastguard Worker * NEON's setup for vmlal_u32 is a little more complicated than it is on
2943*cc02d7e2SAndroid Build Coastguard Worker * SSE2, AVX2, and VSX.
2944*cc02d7e2SAndroid Build Coastguard Worker *
2945*cc02d7e2SAndroid Build Coastguard Worker * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast.
2946*cc02d7e2SAndroid Build Coastguard Worker *
2947*cc02d7e2SAndroid Build Coastguard Worker * To do the same operation, the 128-bit 'Q' register needs to be split into
2948*cc02d7e2SAndroid Build Coastguard Worker * two 64-bit 'D' registers, performing this operation::
2949*cc02d7e2SAndroid Build Coastguard Worker *
2950*cc02d7e2SAndroid Build Coastguard Worker * [ a | b ]
2951*cc02d7e2SAndroid Build Coastguard Worker * | '---------. .--------' |
2952*cc02d7e2SAndroid Build Coastguard Worker * | x |
2953*cc02d7e2SAndroid Build Coastguard Worker * | .---------' '--------. |
2954*cc02d7e2SAndroid Build Coastguard Worker * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ]
2955*cc02d7e2SAndroid Build Coastguard Worker *
2956*cc02d7e2SAndroid Build Coastguard Worker * Due to significant changes in aarch64, the fastest method for aarch64 is
2957*cc02d7e2SAndroid Build Coastguard Worker * completely different than the fastest method for ARMv7-A.
2958*cc02d7e2SAndroid Build Coastguard Worker *
2959*cc02d7e2SAndroid Build Coastguard Worker * ARMv7-A treats D registers as unions overlaying Q registers, so modifying
2960*cc02d7e2SAndroid Build Coastguard Worker * D11 will modify the high half of Q5. This is similar to how modifying AH
2961*cc02d7e2SAndroid Build Coastguard Worker * will only affect bits 8-15 of AX on x86.
2962*cc02d7e2SAndroid Build Coastguard Worker *
2963*cc02d7e2SAndroid Build Coastguard Worker * VZIP takes two registers, and puts even lanes in one register and odd lanes
2964*cc02d7e2SAndroid Build Coastguard Worker * in the other.
2965*cc02d7e2SAndroid Build Coastguard Worker *
2966*cc02d7e2SAndroid Build Coastguard Worker * On ARMv7-A, this strangely modifies both parameters in place instead of
2967*cc02d7e2SAndroid Build Coastguard Worker * taking the usual 3-operand form.
2968*cc02d7e2SAndroid Build Coastguard Worker *
2969*cc02d7e2SAndroid Build Coastguard Worker * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the
2970*cc02d7e2SAndroid Build Coastguard Worker * lower and upper halves of the Q register to end up with the high and low
2971*cc02d7e2SAndroid Build Coastguard Worker * halves where we want - all in one instruction.
2972*cc02d7e2SAndroid Build Coastguard Worker *
2973*cc02d7e2SAndroid Build Coastguard Worker * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] }
2974*cc02d7e2SAndroid Build Coastguard Worker *
2975*cc02d7e2SAndroid Build Coastguard Worker * Unfortunately we need inline assembly for this: Instructions modifying two
2976*cc02d7e2SAndroid Build Coastguard Worker * registers at once is not possible in GCC or Clang's IR, and they have to
2977*cc02d7e2SAndroid Build Coastguard Worker * create a copy.
2978*cc02d7e2SAndroid Build Coastguard Worker *
2979*cc02d7e2SAndroid Build Coastguard Worker * aarch64 requires a different approach.
2980*cc02d7e2SAndroid Build Coastguard Worker *
2981*cc02d7e2SAndroid Build Coastguard Worker * In order to make it easier to write a decent compiler for aarch64, many
2982*cc02d7e2SAndroid Build Coastguard Worker * quirks were removed, such as conditional execution.
2983*cc02d7e2SAndroid Build Coastguard Worker *
2984*cc02d7e2SAndroid Build Coastguard Worker * NEON was also affected by this.
2985*cc02d7e2SAndroid Build Coastguard Worker *
2986*cc02d7e2SAndroid Build Coastguard Worker * aarch64 cannot access the high bits of a Q-form register, and writes to a
2987*cc02d7e2SAndroid Build Coastguard Worker * D-form register zero the high bits, similar to how writes to W-form scalar
2988*cc02d7e2SAndroid Build Coastguard Worker * registers (or DWORD registers on x86_64) work.
2989*cc02d7e2SAndroid Build Coastguard Worker *
2990*cc02d7e2SAndroid Build Coastguard Worker * The formerly free vget_high intrinsics now require a vext (with a few
2991*cc02d7e2SAndroid Build Coastguard Worker * exceptions)
2992*cc02d7e2SAndroid Build Coastguard Worker *
2993*cc02d7e2SAndroid Build Coastguard Worker * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent
2994*cc02d7e2SAndroid Build Coastguard Worker * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one
2995*cc02d7e2SAndroid Build Coastguard Worker * operand.
2996*cc02d7e2SAndroid Build Coastguard Worker *
2997*cc02d7e2SAndroid Build Coastguard Worker * The equivalent of the VZIP.32 on the lower and upper halves would be this
2998*cc02d7e2SAndroid Build Coastguard Worker * mess:
2999*cc02d7e2SAndroid Build Coastguard Worker *
3000*cc02d7e2SAndroid Build Coastguard Worker * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] }
3001*cc02d7e2SAndroid Build Coastguard Worker * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] }
3002*cc02d7e2SAndroid Build Coastguard Worker * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] }
3003*cc02d7e2SAndroid Build Coastguard Worker *
3004*cc02d7e2SAndroid Build Coastguard Worker * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN):
3005*cc02d7e2SAndroid Build Coastguard Worker *
3006*cc02d7e2SAndroid Build Coastguard Worker * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32);
3007*cc02d7e2SAndroid Build Coastguard Worker * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF);
3008*cc02d7e2SAndroid Build Coastguard Worker *
3009*cc02d7e2SAndroid Build Coastguard Worker * This is available on ARMv7-A, but is less efficient than a single VZIP.32.
3010*cc02d7e2SAndroid Build Coastguard Worker */
3011*cc02d7e2SAndroid Build Coastguard Worker
3012*cc02d7e2SAndroid Build Coastguard Worker /*!
3013*cc02d7e2SAndroid Build Coastguard Worker * Function-like macro:
3014*cc02d7e2SAndroid Build Coastguard Worker * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi)
3015*cc02d7e2SAndroid Build Coastguard Worker * {
3016*cc02d7e2SAndroid Build Coastguard Worker * outLo = (uint32x2_t)(in & 0xFFFFFFFF);
3017*cc02d7e2SAndroid Build Coastguard Worker * outHi = (uint32x2_t)(in >> 32);
3018*cc02d7e2SAndroid Build Coastguard Worker * in = UNDEFINED;
3019*cc02d7e2SAndroid Build Coastguard Worker * }
3020*cc02d7e2SAndroid Build Coastguard Worker */
3021*cc02d7e2SAndroid Build Coastguard Worker # if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \
3022*cc02d7e2SAndroid Build Coastguard Worker && defined(__GNUC__) \
3023*cc02d7e2SAndroid Build Coastguard Worker && !defined(__aarch64__) && !defined(__arm64__) && !defined(_M_ARM64)
3024*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
3025*cc02d7e2SAndroid Build Coastguard Worker do { \
3026*cc02d7e2SAndroid Build Coastguard Worker /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \
3027*cc02d7e2SAndroid Build Coastguard Worker /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \
3028*cc02d7e2SAndroid Build Coastguard Worker /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \
3029*cc02d7e2SAndroid Build Coastguard Worker __asm__("vzip.32 %e0, %f0" : "+w" (in)); \
3030*cc02d7e2SAndroid Build Coastguard Worker (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \
3031*cc02d7e2SAndroid Build Coastguard Worker (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \
3032*cc02d7e2SAndroid Build Coastguard Worker } while (0)
3033*cc02d7e2SAndroid Build Coastguard Worker # else
3034*cc02d7e2SAndroid Build Coastguard Worker # define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
3035*cc02d7e2SAndroid Build Coastguard Worker do { \
3036*cc02d7e2SAndroid Build Coastguard Worker (outLo) = vmovn_u64 (in); \
3037*cc02d7e2SAndroid Build Coastguard Worker (outHi) = vshrn_n_u64 ((in), 32); \
3038*cc02d7e2SAndroid Build Coastguard Worker } while (0)
3039*cc02d7e2SAndroid Build Coastguard Worker # endif
3040*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_VECTOR == XXH_NEON */
3041*cc02d7e2SAndroid Build Coastguard Worker
3042*cc02d7e2SAndroid Build Coastguard Worker /*
3043*cc02d7e2SAndroid Build Coastguard Worker * VSX and Z Vector helpers.
3044*cc02d7e2SAndroid Build Coastguard Worker *
3045*cc02d7e2SAndroid Build Coastguard Worker * This is very messy, and any pull requests to clean this up are welcome.
3046*cc02d7e2SAndroid Build Coastguard Worker *
3047*cc02d7e2SAndroid Build Coastguard Worker * There are a lot of problems with supporting VSX and s390x, due to
3048*cc02d7e2SAndroid Build Coastguard Worker * inconsistent intrinsics, spotty coverage, and multiple endiannesses.
3049*cc02d7e2SAndroid Build Coastguard Worker */
3050*cc02d7e2SAndroid Build Coastguard Worker #if XXH_VECTOR == XXH_VSX
3051*cc02d7e2SAndroid Build Coastguard Worker # if defined(__s390x__)
3052*cc02d7e2SAndroid Build Coastguard Worker # include <s390intrin.h>
3053*cc02d7e2SAndroid Build Coastguard Worker # else
3054*cc02d7e2SAndroid Build Coastguard Worker /* gcc's altivec.h can have the unwanted consequence to unconditionally
3055*cc02d7e2SAndroid Build Coastguard Worker * #define bool, vector, and pixel keywords,
3056*cc02d7e2SAndroid Build Coastguard Worker * with bad consequences for programs already using these keywords for other purposes.
3057*cc02d7e2SAndroid Build Coastguard Worker * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined.
3058*cc02d7e2SAndroid Build Coastguard Worker * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler,
3059*cc02d7e2SAndroid Build Coastguard Worker * but it seems that, in some cases, it isn't.
3060*cc02d7e2SAndroid Build Coastguard Worker * Force the build macro to be defined, so that keywords are not altered.
3061*cc02d7e2SAndroid Build Coastguard Worker */
3062*cc02d7e2SAndroid Build Coastguard Worker # if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__)
3063*cc02d7e2SAndroid Build Coastguard Worker # define __APPLE_ALTIVEC__
3064*cc02d7e2SAndroid Build Coastguard Worker # endif
3065*cc02d7e2SAndroid Build Coastguard Worker # include <altivec.h>
3066*cc02d7e2SAndroid Build Coastguard Worker # endif
3067*cc02d7e2SAndroid Build Coastguard Worker
3068*cc02d7e2SAndroid Build Coastguard Worker typedef __vector unsigned long long xxh_u64x2;
3069*cc02d7e2SAndroid Build Coastguard Worker typedef __vector unsigned char xxh_u8x16;
3070*cc02d7e2SAndroid Build Coastguard Worker typedef __vector unsigned xxh_u32x4;
3071*cc02d7e2SAndroid Build Coastguard Worker
3072*cc02d7e2SAndroid Build Coastguard Worker # ifndef XXH_VSX_BE
3073*cc02d7e2SAndroid Build Coastguard Worker # if defined(__BIG_ENDIAN__) \
3074*cc02d7e2SAndroid Build Coastguard Worker || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
3075*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VSX_BE 1
3076*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__
3077*cc02d7e2SAndroid Build Coastguard Worker # warning "-maltivec=be is not recommended. Please use native endianness."
3078*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VSX_BE 1
3079*cc02d7e2SAndroid Build Coastguard Worker # else
3080*cc02d7e2SAndroid Build Coastguard Worker # define XXH_VSX_BE 0
3081*cc02d7e2SAndroid Build Coastguard Worker # endif
3082*cc02d7e2SAndroid Build Coastguard Worker # endif /* !defined(XXH_VSX_BE) */
3083*cc02d7e2SAndroid Build Coastguard Worker
3084*cc02d7e2SAndroid Build Coastguard Worker # if XXH_VSX_BE
3085*cc02d7e2SAndroid Build Coastguard Worker # if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
3086*cc02d7e2SAndroid Build Coastguard Worker # define XXH_vec_revb vec_revb
3087*cc02d7e2SAndroid Build Coastguard Worker # else
3088*cc02d7e2SAndroid Build Coastguard Worker /*!
3089*cc02d7e2SAndroid Build Coastguard Worker * A polyfill for POWER9's vec_revb().
3090*cc02d7e2SAndroid Build Coastguard Worker */
XXH_vec_revb(xxh_u64x2 val)3091*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
3092*cc02d7e2SAndroid Build Coastguard Worker {
3093*cc02d7e2SAndroid Build Coastguard Worker xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
3094*cc02d7e2SAndroid Build Coastguard Worker 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
3095*cc02d7e2SAndroid Build Coastguard Worker return vec_perm(val, val, vByteSwap);
3096*cc02d7e2SAndroid Build Coastguard Worker }
3097*cc02d7e2SAndroid Build Coastguard Worker # endif
3098*cc02d7e2SAndroid Build Coastguard Worker # endif /* XXH_VSX_BE */
3099*cc02d7e2SAndroid Build Coastguard Worker
3100*cc02d7e2SAndroid Build Coastguard Worker /*!
3101*cc02d7e2SAndroid Build Coastguard Worker * Performs an unaligned vector load and byte swaps it on big endian.
3102*cc02d7e2SAndroid Build Coastguard Worker */
XXH_vec_loadu(const void * ptr)3103*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
3104*cc02d7e2SAndroid Build Coastguard Worker {
3105*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 ret;
3106*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2));
3107*cc02d7e2SAndroid Build Coastguard Worker # if XXH_VSX_BE
3108*cc02d7e2SAndroid Build Coastguard Worker ret = XXH_vec_revb(ret);
3109*cc02d7e2SAndroid Build Coastguard Worker # endif
3110*cc02d7e2SAndroid Build Coastguard Worker return ret;
3111*cc02d7e2SAndroid Build Coastguard Worker }
3112*cc02d7e2SAndroid Build Coastguard Worker
3113*cc02d7e2SAndroid Build Coastguard Worker /*
3114*cc02d7e2SAndroid Build Coastguard Worker * vec_mulo and vec_mule are very problematic intrinsics on PowerPC
3115*cc02d7e2SAndroid Build Coastguard Worker *
3116*cc02d7e2SAndroid Build Coastguard Worker * These intrinsics weren't added until GCC 8, despite existing for a while,
3117*cc02d7e2SAndroid Build Coastguard Worker * and they are endian dependent. Also, their meaning swap depending on version.
3118*cc02d7e2SAndroid Build Coastguard Worker * */
3119*cc02d7e2SAndroid Build Coastguard Worker # if defined(__s390x__)
3120*cc02d7e2SAndroid Build Coastguard Worker /* s390x is always big endian, no issue on this platform */
3121*cc02d7e2SAndroid Build Coastguard Worker # define XXH_vec_mulo vec_mulo
3122*cc02d7e2SAndroid Build Coastguard Worker # define XXH_vec_mule vec_mule
3123*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw)
3124*cc02d7e2SAndroid Build Coastguard Worker /* Clang has a better way to control this, we can just use the builtin which doesn't swap. */
3125*cc02d7e2SAndroid Build Coastguard Worker # define XXH_vec_mulo __builtin_altivec_vmulouw
3126*cc02d7e2SAndroid Build Coastguard Worker # define XXH_vec_mule __builtin_altivec_vmuleuw
3127*cc02d7e2SAndroid Build Coastguard Worker # else
3128*cc02d7e2SAndroid Build Coastguard Worker /* gcc needs inline assembly */
3129*cc02d7e2SAndroid Build Coastguard Worker /* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */
XXH_vec_mulo(xxh_u32x4 a,xxh_u32x4 b)3130*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b)
3131*cc02d7e2SAndroid Build Coastguard Worker {
3132*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 result;
3133*cc02d7e2SAndroid Build Coastguard Worker __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
3134*cc02d7e2SAndroid Build Coastguard Worker return result;
3135*cc02d7e2SAndroid Build Coastguard Worker }
XXH_vec_mule(xxh_u32x4 a,xxh_u32x4 b)3136*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
3137*cc02d7e2SAndroid Build Coastguard Worker {
3138*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 result;
3139*cc02d7e2SAndroid Build Coastguard Worker __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
3140*cc02d7e2SAndroid Build Coastguard Worker return result;
3141*cc02d7e2SAndroid Build Coastguard Worker }
3142*cc02d7e2SAndroid Build Coastguard Worker # endif /* XXH_vec_mulo, XXH_vec_mule */
3143*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_VECTOR == XXH_VSX */
3144*cc02d7e2SAndroid Build Coastguard Worker
3145*cc02d7e2SAndroid Build Coastguard Worker
3146*cc02d7e2SAndroid Build Coastguard Worker /* prefetch
3147*cc02d7e2SAndroid Build Coastguard Worker * can be disabled, by declaring XXH_NO_PREFETCH build macro */
3148*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH_NO_PREFETCH)
3149*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
3150*cc02d7e2SAndroid Build Coastguard Worker #else
3151*cc02d7e2SAndroid Build Coastguard Worker # if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
3152*cc02d7e2SAndroid Build Coastguard Worker # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
3153*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
3154*cc02d7e2SAndroid Build Coastguard Worker # elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
3155*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
3156*cc02d7e2SAndroid Build Coastguard Worker # else
3157*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
3158*cc02d7e2SAndroid Build Coastguard Worker # endif
3159*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_NO_PREFETCH */
3160*cc02d7e2SAndroid Build Coastguard Worker
3161*cc02d7e2SAndroid Build Coastguard Worker
3162*cc02d7e2SAndroid Build Coastguard Worker /* ==========================================
3163*cc02d7e2SAndroid Build Coastguard Worker * XXH3 default settings
3164*cc02d7e2SAndroid Build Coastguard Worker * ========================================== */
3165*cc02d7e2SAndroid Build Coastguard Worker
3166*cc02d7e2SAndroid Build Coastguard Worker #define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
3167*cc02d7e2SAndroid Build Coastguard Worker
3168*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
3169*cc02d7e2SAndroid Build Coastguard Worker # error "default keyset is not large enough"
3170*cc02d7e2SAndroid Build Coastguard Worker #endif
3171*cc02d7e2SAndroid Build Coastguard Worker
3172*cc02d7e2SAndroid Build Coastguard Worker /*! Pseudorandom secret taken directly from FARSH. */
3173*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
3174*cc02d7e2SAndroid Build Coastguard Worker 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
3175*cc02d7e2SAndroid Build Coastguard Worker 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
3176*cc02d7e2SAndroid Build Coastguard Worker 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
3177*cc02d7e2SAndroid Build Coastguard Worker 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
3178*cc02d7e2SAndroid Build Coastguard Worker 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
3179*cc02d7e2SAndroid Build Coastguard Worker 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
3180*cc02d7e2SAndroid Build Coastguard Worker 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
3181*cc02d7e2SAndroid Build Coastguard Worker 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
3182*cc02d7e2SAndroid Build Coastguard Worker 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
3183*cc02d7e2SAndroid Build Coastguard Worker 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
3184*cc02d7e2SAndroid Build Coastguard Worker 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
3185*cc02d7e2SAndroid Build Coastguard Worker 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
3186*cc02d7e2SAndroid Build Coastguard Worker };
3187*cc02d7e2SAndroid Build Coastguard Worker
3188*cc02d7e2SAndroid Build Coastguard Worker
3189*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
3190*cc02d7e2SAndroid Build Coastguard Worker # define kSecret XXH3_kSecret
3191*cc02d7e2SAndroid Build Coastguard Worker #endif
3192*cc02d7e2SAndroid Build Coastguard Worker
3193*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_DOXYGEN
3194*cc02d7e2SAndroid Build Coastguard Worker /*!
3195*cc02d7e2SAndroid Build Coastguard Worker * @brief Calculates a 32-bit to 64-bit long multiply.
3196*cc02d7e2SAndroid Build Coastguard Worker *
3197*cc02d7e2SAndroid Build Coastguard Worker * Implemented as a macro.
3198*cc02d7e2SAndroid Build Coastguard Worker *
3199*cc02d7e2SAndroid Build Coastguard Worker * Wraps `__emulu` on MSVC x86 because it tends to call `__allmul` when it doesn't
3200*cc02d7e2SAndroid Build Coastguard Worker * need to (but it shouldn't need to anyways, it is about 7 instructions to do
3201*cc02d7e2SAndroid Build Coastguard Worker * a 64x64 multiply...). Since we know that this will _always_ emit `MULL`, we
3202*cc02d7e2SAndroid Build Coastguard Worker * use that instead of the normal method.
3203*cc02d7e2SAndroid Build Coastguard Worker *
3204*cc02d7e2SAndroid Build Coastguard Worker * If you are compiling for platforms like Thumb-1 and don't have a better option,
3205*cc02d7e2SAndroid Build Coastguard Worker * you may also want to write your own long multiply routine here.
3206*cc02d7e2SAndroid Build Coastguard Worker *
3207*cc02d7e2SAndroid Build Coastguard Worker * @param x, y Numbers to be multiplied
3208*cc02d7e2SAndroid Build Coastguard Worker * @return 64-bit product of the low 32 bits of @p x and @p y.
3209*cc02d7e2SAndroid Build Coastguard Worker */
3210*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64
XXH_mult32to64(xxh_u64 x,xxh_u64 y)3211*cc02d7e2SAndroid Build Coastguard Worker XXH_mult32to64(xxh_u64 x, xxh_u64 y)
3212*cc02d7e2SAndroid Build Coastguard Worker {
3213*cc02d7e2SAndroid Build Coastguard Worker return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF);
3214*cc02d7e2SAndroid Build Coastguard Worker }
3215*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_MSC_VER) && defined(_M_IX86)
3216*cc02d7e2SAndroid Build Coastguard Worker # include <intrin.h>
3217*cc02d7e2SAndroid Build Coastguard Worker # define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y))
3218*cc02d7e2SAndroid Build Coastguard Worker #else
3219*cc02d7e2SAndroid Build Coastguard Worker /*
3220*cc02d7e2SAndroid Build Coastguard Worker * Downcast + upcast is usually better than masking on older compilers like
3221*cc02d7e2SAndroid Build Coastguard Worker * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers.
3222*cc02d7e2SAndroid Build Coastguard Worker *
3223*cc02d7e2SAndroid Build Coastguard Worker * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands
3224*cc02d7e2SAndroid Build Coastguard Worker * and perform a full 64x64 multiply -- entirely redundant on 32-bit.
3225*cc02d7e2SAndroid Build Coastguard Worker */
3226*cc02d7e2SAndroid Build Coastguard Worker # define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y))
3227*cc02d7e2SAndroid Build Coastguard Worker #endif
3228*cc02d7e2SAndroid Build Coastguard Worker
3229*cc02d7e2SAndroid Build Coastguard Worker /*!
3230*cc02d7e2SAndroid Build Coastguard Worker * @brief Calculates a 64->128-bit long multiply.
3231*cc02d7e2SAndroid Build Coastguard Worker *
3232*cc02d7e2SAndroid Build Coastguard Worker * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar
3233*cc02d7e2SAndroid Build Coastguard Worker * version.
3234*cc02d7e2SAndroid Build Coastguard Worker *
3235*cc02d7e2SAndroid Build Coastguard Worker * @param lhs , rhs The 64-bit integers to be multiplied
3236*cc02d7e2SAndroid Build Coastguard Worker * @return The 128-bit result represented in an @ref XXH128_hash_t.
3237*cc02d7e2SAndroid Build Coastguard Worker */
3238*cc02d7e2SAndroid Build Coastguard Worker static XXH128_hash_t
XXH_mult64to128(xxh_u64 lhs,xxh_u64 rhs)3239*cc02d7e2SAndroid Build Coastguard Worker XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
3240*cc02d7e2SAndroid Build Coastguard Worker {
3241*cc02d7e2SAndroid Build Coastguard Worker /*
3242*cc02d7e2SAndroid Build Coastguard Worker * GCC/Clang __uint128_t method.
3243*cc02d7e2SAndroid Build Coastguard Worker *
3244*cc02d7e2SAndroid Build Coastguard Worker * On most 64-bit targets, GCC and Clang define a __uint128_t type.
3245*cc02d7e2SAndroid Build Coastguard Worker * This is usually the best way as it usually uses a native long 64-bit
3246*cc02d7e2SAndroid Build Coastguard Worker * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64.
3247*cc02d7e2SAndroid Build Coastguard Worker *
3248*cc02d7e2SAndroid Build Coastguard Worker * Usually.
3249*cc02d7e2SAndroid Build Coastguard Worker *
3250*cc02d7e2SAndroid Build Coastguard Worker * Despite being a 32-bit platform, Clang (and emscripten) define this type
3251*cc02d7e2SAndroid Build Coastguard Worker * despite not having the arithmetic for it. This results in a laggy
3252*cc02d7e2SAndroid Build Coastguard Worker * compiler builtin call which calculates a full 128-bit multiply.
3253*cc02d7e2SAndroid Build Coastguard Worker * In that case it is best to use the portable one.
3254*cc02d7e2SAndroid Build Coastguard Worker * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677
3255*cc02d7e2SAndroid Build Coastguard Worker */
3256*cc02d7e2SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__wasm__) \
3257*cc02d7e2SAndroid Build Coastguard Worker && defined(__SIZEOF_INT128__) \
3258*cc02d7e2SAndroid Build Coastguard Worker || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
3259*cc02d7e2SAndroid Build Coastguard Worker
3260*cc02d7e2SAndroid Build Coastguard Worker __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs;
3261*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t r128;
3262*cc02d7e2SAndroid Build Coastguard Worker r128.low64 = (xxh_u64)(product);
3263*cc02d7e2SAndroid Build Coastguard Worker r128.high64 = (xxh_u64)(product >> 64);
3264*cc02d7e2SAndroid Build Coastguard Worker return r128;
3265*cc02d7e2SAndroid Build Coastguard Worker
3266*cc02d7e2SAndroid Build Coastguard Worker /*
3267*cc02d7e2SAndroid Build Coastguard Worker * MSVC for x64's _umul128 method.
3268*cc02d7e2SAndroid Build Coastguard Worker *
3269*cc02d7e2SAndroid Build Coastguard Worker * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct);
3270*cc02d7e2SAndroid Build Coastguard Worker *
3271*cc02d7e2SAndroid Build Coastguard Worker * This compiles to single operand MUL on x64.
3272*cc02d7e2SAndroid Build Coastguard Worker */
3273*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_M_X64) || defined(_M_IA64)
3274*cc02d7e2SAndroid Build Coastguard Worker
3275*cc02d7e2SAndroid Build Coastguard Worker #ifndef _MSC_VER
3276*cc02d7e2SAndroid Build Coastguard Worker # pragma intrinsic(_umul128)
3277*cc02d7e2SAndroid Build Coastguard Worker #endif
3278*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 product_high;
3279*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const product_low = _umul128(lhs, rhs, &product_high);
3280*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t r128;
3281*cc02d7e2SAndroid Build Coastguard Worker r128.low64 = product_low;
3282*cc02d7e2SAndroid Build Coastguard Worker r128.high64 = product_high;
3283*cc02d7e2SAndroid Build Coastguard Worker return r128;
3284*cc02d7e2SAndroid Build Coastguard Worker
3285*cc02d7e2SAndroid Build Coastguard Worker /*
3286*cc02d7e2SAndroid Build Coastguard Worker * MSVC for ARM64's __umulh method.
3287*cc02d7e2SAndroid Build Coastguard Worker *
3288*cc02d7e2SAndroid Build Coastguard Worker * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method.
3289*cc02d7e2SAndroid Build Coastguard Worker */
3290*cc02d7e2SAndroid Build Coastguard Worker #elif defined(_M_ARM64)
3291*cc02d7e2SAndroid Build Coastguard Worker
3292*cc02d7e2SAndroid Build Coastguard Worker #ifndef _MSC_VER
3293*cc02d7e2SAndroid Build Coastguard Worker # pragma intrinsic(__umulh)
3294*cc02d7e2SAndroid Build Coastguard Worker #endif
3295*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t r128;
3296*cc02d7e2SAndroid Build Coastguard Worker r128.low64 = lhs * rhs;
3297*cc02d7e2SAndroid Build Coastguard Worker r128.high64 = __umulh(lhs, rhs);
3298*cc02d7e2SAndroid Build Coastguard Worker return r128;
3299*cc02d7e2SAndroid Build Coastguard Worker
3300*cc02d7e2SAndroid Build Coastguard Worker #else
3301*cc02d7e2SAndroid Build Coastguard Worker /*
3302*cc02d7e2SAndroid Build Coastguard Worker * Portable scalar method. Optimized for 32-bit and 64-bit ALUs.
3303*cc02d7e2SAndroid Build Coastguard Worker *
3304*cc02d7e2SAndroid Build Coastguard Worker * This is a fast and simple grade school multiply, which is shown below
3305*cc02d7e2SAndroid Build Coastguard Worker * with base 10 arithmetic instead of base 0x100000000.
3306*cc02d7e2SAndroid Build Coastguard Worker *
3307*cc02d7e2SAndroid Build Coastguard Worker * 9 3 // D2 lhs = 93
3308*cc02d7e2SAndroid Build Coastguard Worker * x 7 5 // D2 rhs = 75
3309*cc02d7e2SAndroid Build Coastguard Worker * ----------
3310*cc02d7e2SAndroid Build Coastguard Worker * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15
3311*cc02d7e2SAndroid Build Coastguard Worker * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45
3312*cc02d7e2SAndroid Build Coastguard Worker * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21
3313*cc02d7e2SAndroid Build Coastguard Worker * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63
3314*cc02d7e2SAndroid Build Coastguard Worker * ---------
3315*cc02d7e2SAndroid Build Coastguard Worker * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27
3316*cc02d7e2SAndroid Build Coastguard Worker * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67
3317*cc02d7e2SAndroid Build Coastguard Worker * ---------
3318*cc02d7e2SAndroid Build Coastguard Worker * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975
3319*cc02d7e2SAndroid Build Coastguard Worker *
3320*cc02d7e2SAndroid Build Coastguard Worker * The reasons for adding the products like this are:
3321*cc02d7e2SAndroid Build Coastguard Worker * 1. It avoids manual carry tracking. Just like how
3322*cc02d7e2SAndroid Build Coastguard Worker * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX.
3323*cc02d7e2SAndroid Build Coastguard Worker * This avoids a lot of complexity.
3324*cc02d7e2SAndroid Build Coastguard Worker *
3325*cc02d7e2SAndroid Build Coastguard Worker * 2. It hints for, and on Clang, compiles to, the powerful UMAAL
3326*cc02d7e2SAndroid Build Coastguard Worker * instruction available in ARM's Digital Signal Processing extension
3327*cc02d7e2SAndroid Build Coastguard Worker * in 32-bit ARMv6 and later, which is shown below:
3328*cc02d7e2SAndroid Build Coastguard Worker *
3329*cc02d7e2SAndroid Build Coastguard Worker * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm)
3330*cc02d7e2SAndroid Build Coastguard Worker * {
3331*cc02d7e2SAndroid Build Coastguard Worker * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm;
3332*cc02d7e2SAndroid Build Coastguard Worker * *RdLo = (xxh_u32)(product & 0xFFFFFFFF);
3333*cc02d7e2SAndroid Build Coastguard Worker * *RdHi = (xxh_u32)(product >> 32);
3334*cc02d7e2SAndroid Build Coastguard Worker * }
3335*cc02d7e2SAndroid Build Coastguard Worker *
3336*cc02d7e2SAndroid Build Coastguard Worker * This instruction was designed for efficient long multiplication, and
3337*cc02d7e2SAndroid Build Coastguard Worker * allows this to be calculated in only 4 instructions at speeds
3338*cc02d7e2SAndroid Build Coastguard Worker * comparable to some 64-bit ALUs.
3339*cc02d7e2SAndroid Build Coastguard Worker *
3340*cc02d7e2SAndroid Build Coastguard Worker * 3. It isn't terrible on other platforms. Usually this will be a couple
3341*cc02d7e2SAndroid Build Coastguard Worker * of 32-bit ADD/ADCs.
3342*cc02d7e2SAndroid Build Coastguard Worker */
3343*cc02d7e2SAndroid Build Coastguard Worker
3344*cc02d7e2SAndroid Build Coastguard Worker /* First calculate all of the cross products. */
3345*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
3346*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
3347*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
3348*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32);
3349*cc02d7e2SAndroid Build Coastguard Worker
3350*cc02d7e2SAndroid Build Coastguard Worker /* Now add the products together. These will never overflow. */
3351*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
3352*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
3353*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
3354*cc02d7e2SAndroid Build Coastguard Worker
3355*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t r128;
3356*cc02d7e2SAndroid Build Coastguard Worker r128.low64 = lower;
3357*cc02d7e2SAndroid Build Coastguard Worker r128.high64 = upper;
3358*cc02d7e2SAndroid Build Coastguard Worker return r128;
3359*cc02d7e2SAndroid Build Coastguard Worker #endif
3360*cc02d7e2SAndroid Build Coastguard Worker }
3361*cc02d7e2SAndroid Build Coastguard Worker
3362*cc02d7e2SAndroid Build Coastguard Worker /*!
3363*cc02d7e2SAndroid Build Coastguard Worker * @brief Calculates a 64-bit to 128-bit multiply, then XOR folds it.
3364*cc02d7e2SAndroid Build Coastguard Worker *
3365*cc02d7e2SAndroid Build Coastguard Worker * The reason for the separate function is to prevent passing too many structs
3366*cc02d7e2SAndroid Build Coastguard Worker * around by value. This will hopefully inline the multiply, but we don't force it.
3367*cc02d7e2SAndroid Build Coastguard Worker *
3368*cc02d7e2SAndroid Build Coastguard Worker * @param lhs , rhs The 64-bit integers to multiply
3369*cc02d7e2SAndroid Build Coastguard Worker * @return The low 64 bits of the product XOR'd by the high 64 bits.
3370*cc02d7e2SAndroid Build Coastguard Worker * @see XXH_mult64to128()
3371*cc02d7e2SAndroid Build Coastguard Worker */
3372*cc02d7e2SAndroid Build Coastguard Worker static xxh_u64
XXH3_mul128_fold64(xxh_u64 lhs,xxh_u64 rhs)3373*cc02d7e2SAndroid Build Coastguard Worker XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
3374*cc02d7e2SAndroid Build Coastguard Worker {
3375*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t product = XXH_mult64to128(lhs, rhs);
3376*cc02d7e2SAndroid Build Coastguard Worker return product.low64 ^ product.high64;
3377*cc02d7e2SAndroid Build Coastguard Worker }
3378*cc02d7e2SAndroid Build Coastguard Worker
3379*cc02d7e2SAndroid Build Coastguard Worker /*! Seems to produce slightly better code on GCC for some reason. */
XXH_xorshift64(xxh_u64 v64,int shift)3380*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
3381*cc02d7e2SAndroid Build Coastguard Worker {
3382*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(0 <= shift && shift < 64);
3383*cc02d7e2SAndroid Build Coastguard Worker return v64 ^ (v64 >> shift);
3384*cc02d7e2SAndroid Build Coastguard Worker }
3385*cc02d7e2SAndroid Build Coastguard Worker
3386*cc02d7e2SAndroid Build Coastguard Worker /*
3387*cc02d7e2SAndroid Build Coastguard Worker * This is a fast avalanche stage,
3388*cc02d7e2SAndroid Build Coastguard Worker * suitable when input bits are already partially mixed
3389*cc02d7e2SAndroid Build Coastguard Worker */
XXH3_avalanche(xxh_u64 h64)3390*cc02d7e2SAndroid Build Coastguard Worker static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
3391*cc02d7e2SAndroid Build Coastguard Worker {
3392*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_xorshift64(h64, 37);
3393*cc02d7e2SAndroid Build Coastguard Worker h64 *= 0x165667919E3779F9ULL;
3394*cc02d7e2SAndroid Build Coastguard Worker h64 = XXH_xorshift64(h64, 32);
3395*cc02d7e2SAndroid Build Coastguard Worker return h64;
3396*cc02d7e2SAndroid Build Coastguard Worker }
3397*cc02d7e2SAndroid Build Coastguard Worker
3398*cc02d7e2SAndroid Build Coastguard Worker /*
3399*cc02d7e2SAndroid Build Coastguard Worker * This is a stronger avalanche,
3400*cc02d7e2SAndroid Build Coastguard Worker * inspired by Pelle Evensen's rrmxmx
3401*cc02d7e2SAndroid Build Coastguard Worker * preferable when input has not been previously mixed
3402*cc02d7e2SAndroid Build Coastguard Worker */
XXH3_rrmxmx(xxh_u64 h64,xxh_u64 len)3403*cc02d7e2SAndroid Build Coastguard Worker static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
3404*cc02d7e2SAndroid Build Coastguard Worker {
3405*cc02d7e2SAndroid Build Coastguard Worker /* this mix is inspired by Pelle Evensen's rrmxmx */
3406*cc02d7e2SAndroid Build Coastguard Worker h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
3407*cc02d7e2SAndroid Build Coastguard Worker h64 *= 0x9FB21C651E98DF25ULL;
3408*cc02d7e2SAndroid Build Coastguard Worker h64 ^= (h64 >> 35) + len ;
3409*cc02d7e2SAndroid Build Coastguard Worker h64 *= 0x9FB21C651E98DF25ULL;
3410*cc02d7e2SAndroid Build Coastguard Worker return XXH_xorshift64(h64, 28);
3411*cc02d7e2SAndroid Build Coastguard Worker }
3412*cc02d7e2SAndroid Build Coastguard Worker
3413*cc02d7e2SAndroid Build Coastguard Worker
3414*cc02d7e2SAndroid Build Coastguard Worker /* ==========================================
3415*cc02d7e2SAndroid Build Coastguard Worker * Short keys
3416*cc02d7e2SAndroid Build Coastguard Worker * ==========================================
3417*cc02d7e2SAndroid Build Coastguard Worker * One of the shortcomings of XXH32 and XXH64 was that their performance was
3418*cc02d7e2SAndroid Build Coastguard Worker * sub-optimal on short lengths. It used an iterative algorithm which strongly
3419*cc02d7e2SAndroid Build Coastguard Worker * favored lengths that were a multiple of 4 or 8.
3420*cc02d7e2SAndroid Build Coastguard Worker *
3421*cc02d7e2SAndroid Build Coastguard Worker * Instead of iterating over individual inputs, we use a set of single shot
3422*cc02d7e2SAndroid Build Coastguard Worker * functions which piece together a range of lengths and operate in constant time.
3423*cc02d7e2SAndroid Build Coastguard Worker *
3424*cc02d7e2SAndroid Build Coastguard Worker * Additionally, the number of multiplies has been significantly reduced. This
3425*cc02d7e2SAndroid Build Coastguard Worker * reduces latency, especially when emulating 64-bit multiplies on 32-bit.
3426*cc02d7e2SAndroid Build Coastguard Worker *
3427*cc02d7e2SAndroid Build Coastguard Worker * Depending on the platform, this may or may not be faster than XXH32, but it
3428*cc02d7e2SAndroid Build Coastguard Worker * is almost guaranteed to be faster than XXH64.
3429*cc02d7e2SAndroid Build Coastguard Worker */
3430*cc02d7e2SAndroid Build Coastguard Worker
3431*cc02d7e2SAndroid Build Coastguard Worker /*
3432*cc02d7e2SAndroid Build Coastguard Worker * At very short lengths, there isn't enough input to fully hide secrets, or use
3433*cc02d7e2SAndroid Build Coastguard Worker * the entire secret.
3434*cc02d7e2SAndroid Build Coastguard Worker *
3435*cc02d7e2SAndroid Build Coastguard Worker * There is also only a limited amount of mixing we can do before significantly
3436*cc02d7e2SAndroid Build Coastguard Worker * impacting performance.
3437*cc02d7e2SAndroid Build Coastguard Worker *
3438*cc02d7e2SAndroid Build Coastguard Worker * Therefore, we use different sections of the secret and always mix two secret
3439*cc02d7e2SAndroid Build Coastguard Worker * samples with an XOR. This should have no effect on performance on the
3440*cc02d7e2SAndroid Build Coastguard Worker * seedless or withSeed variants because everything _should_ be constant folded
3441*cc02d7e2SAndroid Build Coastguard Worker * by modern compilers.
3442*cc02d7e2SAndroid Build Coastguard Worker *
3443*cc02d7e2SAndroid Build Coastguard Worker * The XOR mixing hides individual parts of the secret and increases entropy.
3444*cc02d7e2SAndroid Build Coastguard Worker *
3445*cc02d7e2SAndroid Build Coastguard Worker * This adds an extra layer of strength for custom secrets.
3446*cc02d7e2SAndroid Build Coastguard Worker */
3447*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_1to3_64b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)3448*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3449*cc02d7e2SAndroid Build Coastguard Worker {
3450*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
3451*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(1 <= len && len <= 3);
3452*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
3453*cc02d7e2SAndroid Build Coastguard Worker /*
3454*cc02d7e2SAndroid Build Coastguard Worker * len = 1: combined = { input[0], 0x01, input[0], input[0] }
3455*cc02d7e2SAndroid Build Coastguard Worker * len = 2: combined = { input[1], 0x02, input[0], input[1] }
3456*cc02d7e2SAndroid Build Coastguard Worker * len = 3: combined = { input[2], 0x03, input[0], input[1] }
3457*cc02d7e2SAndroid Build Coastguard Worker */
3458*cc02d7e2SAndroid Build Coastguard Worker { xxh_u8 const c1 = input[0];
3459*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 const c2 = input[len >> 1];
3460*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 const c3 = input[len - 1];
3461*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24)
3462*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
3463*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
3464*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const keyed = (xxh_u64)combined ^ bitflip;
3465*cc02d7e2SAndroid Build Coastguard Worker return XXH64_avalanche(keyed);
3466*cc02d7e2SAndroid Build Coastguard Worker }
3467*cc02d7e2SAndroid Build Coastguard Worker }
3468*cc02d7e2SAndroid Build Coastguard Worker
3469*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_4to8_64b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)3470*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3471*cc02d7e2SAndroid Build Coastguard Worker {
3472*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
3473*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
3474*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(4 <= len && len <= 8);
3475*cc02d7e2SAndroid Build Coastguard Worker seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
3476*cc02d7e2SAndroid Build Coastguard Worker { xxh_u32 const input1 = XXH_readLE32(input);
3477*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 const input2 = XXH_readLE32(input + len - 4);
3478*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed;
3479*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32);
3480*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const keyed = input64 ^ bitflip;
3481*cc02d7e2SAndroid Build Coastguard Worker return XXH3_rrmxmx(keyed, len);
3482*cc02d7e2SAndroid Build Coastguard Worker }
3483*cc02d7e2SAndroid Build Coastguard Worker }
3484*cc02d7e2SAndroid Build Coastguard Worker
3485*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_9to16_64b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)3486*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3487*cc02d7e2SAndroid Build Coastguard Worker {
3488*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
3489*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
3490*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(9 <= len && len <= 16);
3491*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed;
3492*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed;
3493*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1;
3494*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2;
3495*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const acc = len
3496*cc02d7e2SAndroid Build Coastguard Worker + XXH_swap64(input_lo) + input_hi
3497*cc02d7e2SAndroid Build Coastguard Worker + XXH3_mul128_fold64(input_lo, input_hi);
3498*cc02d7e2SAndroid Build Coastguard Worker return XXH3_avalanche(acc);
3499*cc02d7e2SAndroid Build Coastguard Worker }
3500*cc02d7e2SAndroid Build Coastguard Worker }
3501*cc02d7e2SAndroid Build Coastguard Worker
3502*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_0to16_64b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)3503*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3504*cc02d7e2SAndroid Build Coastguard Worker {
3505*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len <= 16);
3506*cc02d7e2SAndroid Build Coastguard Worker { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed);
3507*cc02d7e2SAndroid Build Coastguard Worker if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed);
3508*cc02d7e2SAndroid Build Coastguard Worker if (len) return XXH3_len_1to3_64b(input, len, secret, seed);
3509*cc02d7e2SAndroid Build Coastguard Worker return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64)));
3510*cc02d7e2SAndroid Build Coastguard Worker }
3511*cc02d7e2SAndroid Build Coastguard Worker }
3512*cc02d7e2SAndroid Build Coastguard Worker
3513*cc02d7e2SAndroid Build Coastguard Worker /*
3514*cc02d7e2SAndroid Build Coastguard Worker * DISCLAIMER: There are known *seed-dependent* multicollisions here due to
3515*cc02d7e2SAndroid Build Coastguard Worker * multiplication by zero, affecting hashes of lengths 17 to 240.
3516*cc02d7e2SAndroid Build Coastguard Worker *
3517*cc02d7e2SAndroid Build Coastguard Worker * However, they are very unlikely.
3518*cc02d7e2SAndroid Build Coastguard Worker *
3519*cc02d7e2SAndroid Build Coastguard Worker * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all
3520*cc02d7e2SAndroid Build Coastguard Worker * unseeded non-cryptographic hashes, it does not attempt to defend itself
3521*cc02d7e2SAndroid Build Coastguard Worker * against specially crafted inputs, only random inputs.
3522*cc02d7e2SAndroid Build Coastguard Worker *
3523*cc02d7e2SAndroid Build Coastguard Worker * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes
3524*cc02d7e2SAndroid Build Coastguard Worker * cancelling out the secret is taken an arbitrary number of times (addressed
3525*cc02d7e2SAndroid Build Coastguard Worker * in XXH3_accumulate_512), this collision is very unlikely with random inputs
3526*cc02d7e2SAndroid Build Coastguard Worker * and/or proper seeding:
3527*cc02d7e2SAndroid Build Coastguard Worker *
3528*cc02d7e2SAndroid Build Coastguard Worker * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a
3529*cc02d7e2SAndroid Build Coastguard Worker * function that is only called up to 16 times per hash with up to 240 bytes of
3530*cc02d7e2SAndroid Build Coastguard Worker * input.
3531*cc02d7e2SAndroid Build Coastguard Worker *
3532*cc02d7e2SAndroid Build Coastguard Worker * This is not too bad for a non-cryptographic hash function, especially with
3533*cc02d7e2SAndroid Build Coastguard Worker * only 64 bit outputs.
3534*cc02d7e2SAndroid Build Coastguard Worker *
3535*cc02d7e2SAndroid Build Coastguard Worker * The 128-bit variant (which trades some speed for strength) is NOT affected
3536*cc02d7e2SAndroid Build Coastguard Worker * by this, although it is always a good idea to use a proper seed if you care
3537*cc02d7e2SAndroid Build Coastguard Worker * about strength.
3538*cc02d7e2SAndroid Build Coastguard Worker */
XXH3_mix16B(const xxh_u8 * XXH_RESTRICT input,const xxh_u8 * XXH_RESTRICT secret,xxh_u64 seed64)3539*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
3540*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64)
3541*cc02d7e2SAndroid Build Coastguard Worker {
3542*cc02d7e2SAndroid Build Coastguard Worker #if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
3543*cc02d7e2SAndroid Build Coastguard Worker && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \
3544*cc02d7e2SAndroid Build Coastguard Worker && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */
3545*cc02d7e2SAndroid Build Coastguard Worker /*
3546*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
3547*cc02d7e2SAndroid Build Coastguard Worker * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in
3548*cc02d7e2SAndroid Build Coastguard Worker * slower code.
3549*cc02d7e2SAndroid Build Coastguard Worker *
3550*cc02d7e2SAndroid Build Coastguard Worker * By forcing seed64 into a register, we disrupt the cost model and
3551*cc02d7e2SAndroid Build Coastguard Worker * cause it to scalarize. See `XXH32_round()`
3552*cc02d7e2SAndroid Build Coastguard Worker *
3553*cc02d7e2SAndroid Build Coastguard Worker * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600,
3554*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on
3555*cc02d7e2SAndroid Build Coastguard Worker * GCC 9.2, despite both emitting scalar code.
3556*cc02d7e2SAndroid Build Coastguard Worker *
3557*cc02d7e2SAndroid Build Coastguard Worker * GCC generates much better scalar code than Clang for the rest of XXH3,
3558*cc02d7e2SAndroid Build Coastguard Worker * which is why finding a more optimal codepath is an interest.
3559*cc02d7e2SAndroid Build Coastguard Worker */
3560*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(seed64);
3561*cc02d7e2SAndroid Build Coastguard Worker #endif
3562*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64 const input_lo = XXH_readLE64(input);
3563*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input_hi = XXH_readLE64(input+8);
3564*cc02d7e2SAndroid Build Coastguard Worker return XXH3_mul128_fold64(
3565*cc02d7e2SAndroid Build Coastguard Worker input_lo ^ (XXH_readLE64(secret) + seed64),
3566*cc02d7e2SAndroid Build Coastguard Worker input_hi ^ (XXH_readLE64(secret+8) - seed64)
3567*cc02d7e2SAndroid Build Coastguard Worker );
3568*cc02d7e2SAndroid Build Coastguard Worker }
3569*cc02d7e2SAndroid Build Coastguard Worker }
3570*cc02d7e2SAndroid Build Coastguard Worker
3571*cc02d7e2SAndroid Build Coastguard Worker /* For mid range keys, XXH3 uses a Mum-hash variant. */
3572*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_len_17to128_64b(const xxh_u8 * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH64_hash_t seed)3573*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3574*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3575*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed)
3576*cc02d7e2SAndroid Build Coastguard Worker {
3577*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
3578*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(16 < len && len <= 128);
3579*cc02d7e2SAndroid Build Coastguard Worker
3580*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64 acc = len * XXH_PRIME64_1;
3581*cc02d7e2SAndroid Build Coastguard Worker if (len > 32) {
3582*cc02d7e2SAndroid Build Coastguard Worker if (len > 64) {
3583*cc02d7e2SAndroid Build Coastguard Worker if (len > 96) {
3584*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+48, secret+96, seed);
3585*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+len-64, secret+112, seed);
3586*cc02d7e2SAndroid Build Coastguard Worker }
3587*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+32, secret+64, seed);
3588*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+len-48, secret+80, seed);
3589*cc02d7e2SAndroid Build Coastguard Worker }
3590*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+16, secret+32, seed);
3591*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+len-32, secret+48, seed);
3592*cc02d7e2SAndroid Build Coastguard Worker }
3593*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+0, secret+0, seed);
3594*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+len-16, secret+16, seed);
3595*cc02d7e2SAndroid Build Coastguard Worker
3596*cc02d7e2SAndroid Build Coastguard Worker return XXH3_avalanche(acc);
3597*cc02d7e2SAndroid Build Coastguard Worker }
3598*cc02d7e2SAndroid Build Coastguard Worker }
3599*cc02d7e2SAndroid Build Coastguard Worker
3600*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_MIDSIZE_MAX 240
3601*cc02d7e2SAndroid Build Coastguard Worker
3602*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH64_hash_t
XXH3_len_129to240_64b(const xxh_u8 * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH64_hash_t seed)3603*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3604*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3605*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed)
3606*cc02d7e2SAndroid Build Coastguard Worker {
3607*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
3608*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
3609*cc02d7e2SAndroid Build Coastguard Worker
3610*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_MIDSIZE_STARTOFFSET 3
3611*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_MIDSIZE_LASTOFFSET 17
3612*cc02d7e2SAndroid Build Coastguard Worker
3613*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64 acc = len * XXH_PRIME64_1;
3614*cc02d7e2SAndroid Build Coastguard Worker int const nbRounds = (int)len / 16;
3615*cc02d7e2SAndroid Build Coastguard Worker int i;
3616*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i<8; i++) {
3617*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed);
3618*cc02d7e2SAndroid Build Coastguard Worker }
3619*cc02d7e2SAndroid Build Coastguard Worker acc = XXH3_avalanche(acc);
3620*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(nbRounds >= 8);
3621*cc02d7e2SAndroid Build Coastguard Worker #if defined(__clang__) /* Clang */ \
3622*cc02d7e2SAndroid Build Coastguard Worker && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
3623*cc02d7e2SAndroid Build Coastguard Worker && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
3624*cc02d7e2SAndroid Build Coastguard Worker /*
3625*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
3626*cc02d7e2SAndroid Build Coastguard Worker * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86.
3627*cc02d7e2SAndroid Build Coastguard Worker * In everywhere else, it uses scalar code.
3628*cc02d7e2SAndroid Build Coastguard Worker *
3629*cc02d7e2SAndroid Build Coastguard Worker * For 64->128-bit multiplies, even if the NEON was 100% optimal, it
3630*cc02d7e2SAndroid Build Coastguard Worker * would still be slower than UMAAL (see XXH_mult64to128).
3631*cc02d7e2SAndroid Build Coastguard Worker *
3632*cc02d7e2SAndroid Build Coastguard Worker * Unfortunately, Clang doesn't handle the long multiplies properly and
3633*cc02d7e2SAndroid Build Coastguard Worker * converts them to the nonexistent "vmulq_u64" intrinsic, which is then
3634*cc02d7e2SAndroid Build Coastguard Worker * scalarized into an ugly mess of VMOV.32 instructions.
3635*cc02d7e2SAndroid Build Coastguard Worker *
3636*cc02d7e2SAndroid Build Coastguard Worker * This mess is difficult to avoid without turning autovectorization
3637*cc02d7e2SAndroid Build Coastguard Worker * off completely, but they are usually relatively minor and/or not
3638*cc02d7e2SAndroid Build Coastguard Worker * worth it to fix.
3639*cc02d7e2SAndroid Build Coastguard Worker *
3640*cc02d7e2SAndroid Build Coastguard Worker * This loop is the easiest to fix, as unlike XXH32, this pragma
3641*cc02d7e2SAndroid Build Coastguard Worker * _actually works_ because it is a loop vectorization instead of an
3642*cc02d7e2SAndroid Build Coastguard Worker * SLP vectorization.
3643*cc02d7e2SAndroid Build Coastguard Worker */
3644*cc02d7e2SAndroid Build Coastguard Worker #pragma clang loop vectorize(disable)
3645*cc02d7e2SAndroid Build Coastguard Worker #endif
3646*cc02d7e2SAndroid Build Coastguard Worker for (i=8 ; i < nbRounds; i++) {
3647*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
3648*cc02d7e2SAndroid Build Coastguard Worker }
3649*cc02d7e2SAndroid Build Coastguard Worker /* last bytes */
3650*cc02d7e2SAndroid Build Coastguard Worker acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
3651*cc02d7e2SAndroid Build Coastguard Worker return XXH3_avalanche(acc);
3652*cc02d7e2SAndroid Build Coastguard Worker }
3653*cc02d7e2SAndroid Build Coastguard Worker }
3654*cc02d7e2SAndroid Build Coastguard Worker
3655*cc02d7e2SAndroid Build Coastguard Worker
3656*cc02d7e2SAndroid Build Coastguard Worker /* ======= Long Keys ======= */
3657*cc02d7e2SAndroid Build Coastguard Worker
3658*cc02d7e2SAndroid Build Coastguard Worker #define XXH_STRIPE_LEN 64
3659*cc02d7e2SAndroid Build Coastguard Worker #define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */
3660*cc02d7e2SAndroid Build Coastguard Worker #define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64))
3661*cc02d7e2SAndroid Build Coastguard Worker
3662*cc02d7e2SAndroid Build Coastguard Worker #ifdef XXH_OLD_NAMES
3663*cc02d7e2SAndroid Build Coastguard Worker # define STRIPE_LEN XXH_STRIPE_LEN
3664*cc02d7e2SAndroid Build Coastguard Worker # define ACC_NB XXH_ACC_NB
3665*cc02d7e2SAndroid Build Coastguard Worker #endif
3666*cc02d7e2SAndroid Build Coastguard Worker
XXH_writeLE64(void * dst,xxh_u64 v64)3667*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
3668*cc02d7e2SAndroid Build Coastguard Worker {
3669*cc02d7e2SAndroid Build Coastguard Worker if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
3670*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dst, &v64, sizeof(v64));
3671*cc02d7e2SAndroid Build Coastguard Worker }
3672*cc02d7e2SAndroid Build Coastguard Worker
3673*cc02d7e2SAndroid Build Coastguard Worker /* Several intrinsic functions below are supposed to accept __int64 as argument,
3674*cc02d7e2SAndroid Build Coastguard Worker * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ .
3675*cc02d7e2SAndroid Build Coastguard Worker * However, several environments do not define __int64 type,
3676*cc02d7e2SAndroid Build Coastguard Worker * requiring a workaround.
3677*cc02d7e2SAndroid Build Coastguard Worker */
3678*cc02d7e2SAndroid Build Coastguard Worker #if !defined (__VMS) \
3679*cc02d7e2SAndroid Build Coastguard Worker && (defined (__cplusplus) \
3680*cc02d7e2SAndroid Build Coastguard Worker || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
3681*cc02d7e2SAndroid Build Coastguard Worker typedef int64_t xxh_i64;
3682*cc02d7e2SAndroid Build Coastguard Worker #else
3683*cc02d7e2SAndroid Build Coastguard Worker /* the following type must have a width of 64-bit */
3684*cc02d7e2SAndroid Build Coastguard Worker typedef long long xxh_i64;
3685*cc02d7e2SAndroid Build Coastguard Worker #endif
3686*cc02d7e2SAndroid Build Coastguard Worker
3687*cc02d7e2SAndroid Build Coastguard Worker /*
3688*cc02d7e2SAndroid Build Coastguard Worker * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized.
3689*cc02d7e2SAndroid Build Coastguard Worker *
3690*cc02d7e2SAndroid Build Coastguard Worker * It is a hardened version of UMAC, based off of FARSH's implementation.
3691*cc02d7e2SAndroid Build Coastguard Worker *
3692*cc02d7e2SAndroid Build Coastguard Worker * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD
3693*cc02d7e2SAndroid Build Coastguard Worker * implementations, and it is ridiculously fast.
3694*cc02d7e2SAndroid Build Coastguard Worker *
3695*cc02d7e2SAndroid Build Coastguard Worker * We harden it by mixing the original input to the accumulators as well as the product.
3696*cc02d7e2SAndroid Build Coastguard Worker *
3697*cc02d7e2SAndroid Build Coastguard Worker * This means that in the (relatively likely) case of a multiply by zero, the
3698*cc02d7e2SAndroid Build Coastguard Worker * original input is preserved.
3699*cc02d7e2SAndroid Build Coastguard Worker *
3700*cc02d7e2SAndroid Build Coastguard Worker * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve
3701*cc02d7e2SAndroid Build Coastguard Worker * cross-pollination, as otherwise the upper and lower halves would be
3702*cc02d7e2SAndroid Build Coastguard Worker * essentially independent.
3703*cc02d7e2SAndroid Build Coastguard Worker *
3704*cc02d7e2SAndroid Build Coastguard Worker * This doesn't matter on 64-bit hashes since they all get merged together in
3705*cc02d7e2SAndroid Build Coastguard Worker * the end, so we skip the extra step.
3706*cc02d7e2SAndroid Build Coastguard Worker *
3707*cc02d7e2SAndroid Build Coastguard Worker * Both XXH3_64bits and XXH3_128bits use this subroutine.
3708*cc02d7e2SAndroid Build Coastguard Worker */
3709*cc02d7e2SAndroid Build Coastguard Worker
3710*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_AVX512) \
3711*cc02d7e2SAndroid Build Coastguard Worker || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0)
3712*cc02d7e2SAndroid Build Coastguard Worker
3713*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_TARGET_AVX512
3714*cc02d7e2SAndroid Build Coastguard Worker # define XXH_TARGET_AVX512 /* disable attribute target */
3715*cc02d7e2SAndroid Build Coastguard Worker #endif
3716*cc02d7e2SAndroid Build Coastguard Worker
3717*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX512 void
XXH3_accumulate_512_avx512(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)3718*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc,
3719*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
3720*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
3721*cc02d7e2SAndroid Build Coastguard Worker {
3722*cc02d7e2SAndroid Build Coastguard Worker __m512i* const xacc = (__m512i *) acc;
3723*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 63) == 0);
3724*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3725*cc02d7e2SAndroid Build Coastguard Worker
3726*cc02d7e2SAndroid Build Coastguard Worker {
3727*cc02d7e2SAndroid Build Coastguard Worker /* data_vec = input[0]; */
3728*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_vec = _mm512_loadu_si512 (input);
3729*cc02d7e2SAndroid Build Coastguard Worker /* key_vec = secret[0]; */
3730*cc02d7e2SAndroid Build Coastguard Worker __m512i const key_vec = _mm512_loadu_si512 (secret);
3731*cc02d7e2SAndroid Build Coastguard Worker /* data_key = data_vec ^ key_vec; */
3732*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
3733*cc02d7e2SAndroid Build Coastguard Worker /* data_key_lo = data_key >> 32; */
3734*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
3735*cc02d7e2SAndroid Build Coastguard Worker /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3736*cc02d7e2SAndroid Build Coastguard Worker __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo);
3737*cc02d7e2SAndroid Build Coastguard Worker /* xacc[0] += swap(data_vec); */
3738*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2));
3739*cc02d7e2SAndroid Build Coastguard Worker __m512i const sum = _mm512_add_epi64(*xacc, data_swap);
3740*cc02d7e2SAndroid Build Coastguard Worker /* xacc[0] += product; */
3741*cc02d7e2SAndroid Build Coastguard Worker *xacc = _mm512_add_epi64(product, sum);
3742*cc02d7e2SAndroid Build Coastguard Worker }
3743*cc02d7e2SAndroid Build Coastguard Worker }
3744*cc02d7e2SAndroid Build Coastguard Worker
3745*cc02d7e2SAndroid Build Coastguard Worker /*
3746*cc02d7e2SAndroid Build Coastguard Worker * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing.
3747*cc02d7e2SAndroid Build Coastguard Worker *
3748*cc02d7e2SAndroid Build Coastguard Worker * Multiplication isn't perfect, as explained by Google in HighwayHash:
3749*cc02d7e2SAndroid Build Coastguard Worker *
3750*cc02d7e2SAndroid Build Coastguard Worker * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to
3751*cc02d7e2SAndroid Build Coastguard Worker * // varying degrees. In descending order of goodness, bytes
3752*cc02d7e2SAndroid Build Coastguard Worker * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32.
3753*cc02d7e2SAndroid Build Coastguard Worker * // As expected, the upper and lower bytes are much worse.
3754*cc02d7e2SAndroid Build Coastguard Worker *
3755*cc02d7e2SAndroid Build Coastguard Worker * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291
3756*cc02d7e2SAndroid Build Coastguard Worker *
3757*cc02d7e2SAndroid Build Coastguard Worker * Since our algorithm uses a pseudorandom secret to add some variance into the
3758*cc02d7e2SAndroid Build Coastguard Worker * mix, we don't need to (or want to) mix as often or as much as HighwayHash does.
3759*cc02d7e2SAndroid Build Coastguard Worker *
3760*cc02d7e2SAndroid Build Coastguard Worker * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid
3761*cc02d7e2SAndroid Build Coastguard Worker * extraction.
3762*cc02d7e2SAndroid Build Coastguard Worker *
3763*cc02d7e2SAndroid Build Coastguard Worker * Both XXH3_64bits and XXH3_128bits use this subroutine.
3764*cc02d7e2SAndroid Build Coastguard Worker */
3765*cc02d7e2SAndroid Build Coastguard Worker
3766*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX512 void
XXH3_scrambleAcc_avx512(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)3767*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3768*cc02d7e2SAndroid Build Coastguard Worker {
3769*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 63) == 0);
3770*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3771*cc02d7e2SAndroid Build Coastguard Worker { __m512i* const xacc = (__m512i*) acc;
3772*cc02d7e2SAndroid Build Coastguard Worker const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1);
3773*cc02d7e2SAndroid Build Coastguard Worker
3774*cc02d7e2SAndroid Build Coastguard Worker /* xacc[0] ^= (xacc[0] >> 47) */
3775*cc02d7e2SAndroid Build Coastguard Worker __m512i const acc_vec = *xacc;
3776*cc02d7e2SAndroid Build Coastguard Worker __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47);
3777*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted);
3778*cc02d7e2SAndroid Build Coastguard Worker /* xacc[0] ^= secret; */
3779*cc02d7e2SAndroid Build Coastguard Worker __m512i const key_vec = _mm512_loadu_si512 (secret);
3780*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
3781*cc02d7e2SAndroid Build Coastguard Worker
3782*cc02d7e2SAndroid Build Coastguard Worker /* xacc[0] *= XXH_PRIME32_1; */
3783*cc02d7e2SAndroid Build Coastguard Worker __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
3784*cc02d7e2SAndroid Build Coastguard Worker __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32);
3785*cc02d7e2SAndroid Build Coastguard Worker __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32);
3786*cc02d7e2SAndroid Build Coastguard Worker *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32));
3787*cc02d7e2SAndroid Build Coastguard Worker }
3788*cc02d7e2SAndroid Build Coastguard Worker }
3789*cc02d7e2SAndroid Build Coastguard Worker
3790*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX512 void
XXH3_initCustomSecret_avx512(void * XXH_RESTRICT customSecret,xxh_u64 seed64)3791*cc02d7e2SAndroid Build Coastguard Worker XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3792*cc02d7e2SAndroid Build Coastguard Worker {
3793*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0);
3794*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64);
3795*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)customSecret & 63) == 0);
3796*cc02d7e2SAndroid Build Coastguard Worker (void)(&XXH_writeLE64);
3797*cc02d7e2SAndroid Build Coastguard Worker { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i);
3798*cc02d7e2SAndroid Build Coastguard Worker __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64));
3799*cc02d7e2SAndroid Build Coastguard Worker
3800*cc02d7e2SAndroid Build Coastguard Worker const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret);
3801*cc02d7e2SAndroid Build Coastguard Worker __m512i* const dest = ( __m512i*) customSecret;
3802*cc02d7e2SAndroid Build Coastguard Worker int i;
3803*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */
3804*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)dest & 63) == 0);
3805*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < nbRounds; ++i) {
3806*cc02d7e2SAndroid Build Coastguard Worker /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*',
3807*cc02d7e2SAndroid Build Coastguard Worker * this will warn "discards 'const' qualifier". */
3808*cc02d7e2SAndroid Build Coastguard Worker union {
3809*cc02d7e2SAndroid Build Coastguard Worker const __m512i* cp;
3810*cc02d7e2SAndroid Build Coastguard Worker void* p;
3811*cc02d7e2SAndroid Build Coastguard Worker } remote_const_void;
3812*cc02d7e2SAndroid Build Coastguard Worker remote_const_void.cp = src + i;
3813*cc02d7e2SAndroid Build Coastguard Worker dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed);
3814*cc02d7e2SAndroid Build Coastguard Worker } }
3815*cc02d7e2SAndroid Build Coastguard Worker }
3816*cc02d7e2SAndroid Build Coastguard Worker
3817*cc02d7e2SAndroid Build Coastguard Worker #endif
3818*cc02d7e2SAndroid Build Coastguard Worker
3819*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_AVX2) \
3820*cc02d7e2SAndroid Build Coastguard Worker || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0)
3821*cc02d7e2SAndroid Build Coastguard Worker
3822*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_TARGET_AVX2
3823*cc02d7e2SAndroid Build Coastguard Worker # define XXH_TARGET_AVX2 /* disable attribute target */
3824*cc02d7e2SAndroid Build Coastguard Worker #endif
3825*cc02d7e2SAndroid Build Coastguard Worker
3826*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX2 void
XXH3_accumulate_512_avx2(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)3827*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc,
3828*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
3829*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
3830*cc02d7e2SAndroid Build Coastguard Worker {
3831*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 31) == 0);
3832*cc02d7e2SAndroid Build Coastguard Worker { __m256i* const xacc = (__m256i *) acc;
3833*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3834*cc02d7e2SAndroid Build Coastguard Worker * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3835*cc02d7e2SAndroid Build Coastguard Worker const __m256i* const xinput = (const __m256i *) input;
3836*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3837*cc02d7e2SAndroid Build Coastguard Worker * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3838*cc02d7e2SAndroid Build Coastguard Worker const __m256i* const xsecret = (const __m256i *) secret;
3839*cc02d7e2SAndroid Build Coastguard Worker
3840*cc02d7e2SAndroid Build Coastguard Worker size_t i;
3841*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
3842*cc02d7e2SAndroid Build Coastguard Worker /* data_vec = xinput[i]; */
3843*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_vec = _mm256_loadu_si256 (xinput+i);
3844*cc02d7e2SAndroid Build Coastguard Worker /* key_vec = xsecret[i]; */
3845*cc02d7e2SAndroid Build Coastguard Worker __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
3846*cc02d7e2SAndroid Build Coastguard Worker /* data_key = data_vec ^ key_vec; */
3847*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
3848*cc02d7e2SAndroid Build Coastguard Worker /* data_key_lo = data_key >> 32; */
3849*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3850*cc02d7e2SAndroid Build Coastguard Worker /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3851*cc02d7e2SAndroid Build Coastguard Worker __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo);
3852*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += swap(data_vec); */
3853*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2));
3854*cc02d7e2SAndroid Build Coastguard Worker __m256i const sum = _mm256_add_epi64(xacc[i], data_swap);
3855*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += product; */
3856*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = _mm256_add_epi64(product, sum);
3857*cc02d7e2SAndroid Build Coastguard Worker } }
3858*cc02d7e2SAndroid Build Coastguard Worker }
3859*cc02d7e2SAndroid Build Coastguard Worker
3860*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX2 void
XXH3_scrambleAcc_avx2(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)3861*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3862*cc02d7e2SAndroid Build Coastguard Worker {
3863*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 31) == 0);
3864*cc02d7e2SAndroid Build Coastguard Worker { __m256i* const xacc = (__m256i*) acc;
3865*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3866*cc02d7e2SAndroid Build Coastguard Worker * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3867*cc02d7e2SAndroid Build Coastguard Worker const __m256i* const xsecret = (const __m256i *) secret;
3868*cc02d7e2SAndroid Build Coastguard Worker const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1);
3869*cc02d7e2SAndroid Build Coastguard Worker
3870*cc02d7e2SAndroid Build Coastguard Worker size_t i;
3871*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
3872*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= (xacc[i] >> 47) */
3873*cc02d7e2SAndroid Build Coastguard Worker __m256i const acc_vec = xacc[i];
3874*cc02d7e2SAndroid Build Coastguard Worker __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47);
3875*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted);
3876*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= xsecret; */
3877*cc02d7e2SAndroid Build Coastguard Worker __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
3878*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
3879*cc02d7e2SAndroid Build Coastguard Worker
3880*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] *= XXH_PRIME32_1; */
3881*cc02d7e2SAndroid Build Coastguard Worker __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3882*cc02d7e2SAndroid Build Coastguard Worker __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32);
3883*cc02d7e2SAndroid Build Coastguard Worker __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32);
3884*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32));
3885*cc02d7e2SAndroid Build Coastguard Worker }
3886*cc02d7e2SAndroid Build Coastguard Worker }
3887*cc02d7e2SAndroid Build Coastguard Worker }
3888*cc02d7e2SAndroid Build Coastguard Worker
XXH3_initCustomSecret_avx2(void * XXH_RESTRICT customSecret,xxh_u64 seed64)3889*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3890*cc02d7e2SAndroid Build Coastguard Worker {
3891*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0);
3892*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6);
3893*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
3894*cc02d7e2SAndroid Build Coastguard Worker (void)(&XXH_writeLE64);
3895*cc02d7e2SAndroid Build Coastguard Worker XXH_PREFETCH(customSecret);
3896*cc02d7e2SAndroid Build Coastguard Worker { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
3897*cc02d7e2SAndroid Build Coastguard Worker
3898*cc02d7e2SAndroid Build Coastguard Worker const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret);
3899*cc02d7e2SAndroid Build Coastguard Worker __m256i* dest = ( __m256i*) customSecret;
3900*cc02d7e2SAndroid Build Coastguard Worker
3901*cc02d7e2SAndroid Build Coastguard Worker # if defined(__GNUC__) || defined(__clang__)
3902*cc02d7e2SAndroid Build Coastguard Worker /*
3903*cc02d7e2SAndroid Build Coastguard Worker * On GCC & Clang, marking 'dest' as modified will cause the compiler:
3904*cc02d7e2SAndroid Build Coastguard Worker * - do not extract the secret from sse registers in the internal loop
3905*cc02d7e2SAndroid Build Coastguard Worker * - use less common registers, and avoid pushing these reg into stack
3906*cc02d7e2SAndroid Build Coastguard Worker */
3907*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(dest);
3908*cc02d7e2SAndroid Build Coastguard Worker # endif
3909*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */
3910*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)dest & 31) == 0);
3911*cc02d7e2SAndroid Build Coastguard Worker
3912*cc02d7e2SAndroid Build Coastguard Worker /* GCC -O2 need unroll loop manually */
3913*cc02d7e2SAndroid Build Coastguard Worker dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed);
3914*cc02d7e2SAndroid Build Coastguard Worker dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed);
3915*cc02d7e2SAndroid Build Coastguard Worker dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed);
3916*cc02d7e2SAndroid Build Coastguard Worker dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed);
3917*cc02d7e2SAndroid Build Coastguard Worker dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed);
3918*cc02d7e2SAndroid Build Coastguard Worker dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed);
3919*cc02d7e2SAndroid Build Coastguard Worker }
3920*cc02d7e2SAndroid Build Coastguard Worker }
3921*cc02d7e2SAndroid Build Coastguard Worker
3922*cc02d7e2SAndroid Build Coastguard Worker #endif
3923*cc02d7e2SAndroid Build Coastguard Worker
3924*cc02d7e2SAndroid Build Coastguard Worker /* x86dispatch always generates SSE2 */
3925*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH)
3926*cc02d7e2SAndroid Build Coastguard Worker
3927*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_TARGET_SSE2
3928*cc02d7e2SAndroid Build Coastguard Worker # define XXH_TARGET_SSE2 /* disable attribute target */
3929*cc02d7e2SAndroid Build Coastguard Worker #endif
3930*cc02d7e2SAndroid Build Coastguard Worker
3931*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_SSE2 void
XXH3_accumulate_512_sse2(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)3932*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc,
3933*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
3934*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
3935*cc02d7e2SAndroid Build Coastguard Worker {
3936*cc02d7e2SAndroid Build Coastguard Worker /* SSE2 is just a half-scale version of the AVX2 version. */
3937*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 15) == 0);
3938*cc02d7e2SAndroid Build Coastguard Worker { __m128i* const xacc = (__m128i *) acc;
3939*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3940*cc02d7e2SAndroid Build Coastguard Worker * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3941*cc02d7e2SAndroid Build Coastguard Worker const __m128i* const xinput = (const __m128i *) input;
3942*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3943*cc02d7e2SAndroid Build Coastguard Worker * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3944*cc02d7e2SAndroid Build Coastguard Worker const __m128i* const xsecret = (const __m128i *) secret;
3945*cc02d7e2SAndroid Build Coastguard Worker
3946*cc02d7e2SAndroid Build Coastguard Worker size_t i;
3947*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
3948*cc02d7e2SAndroid Build Coastguard Worker /* data_vec = xinput[i]; */
3949*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_vec = _mm_loadu_si128 (xinput+i);
3950*cc02d7e2SAndroid Build Coastguard Worker /* key_vec = xsecret[i]; */
3951*cc02d7e2SAndroid Build Coastguard Worker __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
3952*cc02d7e2SAndroid Build Coastguard Worker /* data_key = data_vec ^ key_vec; */
3953*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
3954*cc02d7e2SAndroid Build Coastguard Worker /* data_key_lo = data_key >> 32; */
3955*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3956*cc02d7e2SAndroid Build Coastguard Worker /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3957*cc02d7e2SAndroid Build Coastguard Worker __m128i const product = _mm_mul_epu32 (data_key, data_key_lo);
3958*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += swap(data_vec); */
3959*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2));
3960*cc02d7e2SAndroid Build Coastguard Worker __m128i const sum = _mm_add_epi64(xacc[i], data_swap);
3961*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += product; */
3962*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = _mm_add_epi64(product, sum);
3963*cc02d7e2SAndroid Build Coastguard Worker } }
3964*cc02d7e2SAndroid Build Coastguard Worker }
3965*cc02d7e2SAndroid Build Coastguard Worker
3966*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_SSE2 void
XXH3_scrambleAcc_sse2(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)3967*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3968*cc02d7e2SAndroid Build Coastguard Worker {
3969*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 15) == 0);
3970*cc02d7e2SAndroid Build Coastguard Worker { __m128i* const xacc = (__m128i*) acc;
3971*cc02d7e2SAndroid Build Coastguard Worker /* Unaligned. This is mainly for pointer arithmetic, and because
3972*cc02d7e2SAndroid Build Coastguard Worker * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3973*cc02d7e2SAndroid Build Coastguard Worker const __m128i* const xsecret = (const __m128i *) secret;
3974*cc02d7e2SAndroid Build Coastguard Worker const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1);
3975*cc02d7e2SAndroid Build Coastguard Worker
3976*cc02d7e2SAndroid Build Coastguard Worker size_t i;
3977*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
3978*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= (xacc[i] >> 47) */
3979*cc02d7e2SAndroid Build Coastguard Worker __m128i const acc_vec = xacc[i];
3980*cc02d7e2SAndroid Build Coastguard Worker __m128i const shifted = _mm_srli_epi64 (acc_vec, 47);
3981*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted);
3982*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= xsecret[i]; */
3983*cc02d7e2SAndroid Build Coastguard Worker __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
3984*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
3985*cc02d7e2SAndroid Build Coastguard Worker
3986*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] *= XXH_PRIME32_1; */
3987*cc02d7e2SAndroid Build Coastguard Worker __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3988*cc02d7e2SAndroid Build Coastguard Worker __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32);
3989*cc02d7e2SAndroid Build Coastguard Worker __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32);
3990*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32));
3991*cc02d7e2SAndroid Build Coastguard Worker }
3992*cc02d7e2SAndroid Build Coastguard Worker }
3993*cc02d7e2SAndroid Build Coastguard Worker }
3994*cc02d7e2SAndroid Build Coastguard Worker
XXH3_initCustomSecret_sse2(void * XXH_RESTRICT customSecret,xxh_u64 seed64)3995*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3996*cc02d7e2SAndroid Build Coastguard Worker {
3997*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
3998*cc02d7e2SAndroid Build Coastguard Worker (void)(&XXH_writeLE64);
3999*cc02d7e2SAndroid Build Coastguard Worker { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i);
4000*cc02d7e2SAndroid Build Coastguard Worker
4001*cc02d7e2SAndroid Build Coastguard Worker # if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
4002*cc02d7e2SAndroid Build Coastguard Worker /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
4003*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
4004*cc02d7e2SAndroid Build Coastguard Worker __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
4005*cc02d7e2SAndroid Build Coastguard Worker # else
4006*cc02d7e2SAndroid Build Coastguard Worker __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
4007*cc02d7e2SAndroid Build Coastguard Worker # endif
4008*cc02d7e2SAndroid Build Coastguard Worker int i;
4009*cc02d7e2SAndroid Build Coastguard Worker
4010*cc02d7e2SAndroid Build Coastguard Worker const void* const src16 = XXH3_kSecret;
4011*cc02d7e2SAndroid Build Coastguard Worker __m128i* dst16 = (__m128i*) customSecret;
4012*cc02d7e2SAndroid Build Coastguard Worker # if defined(__GNUC__) || defined(__clang__)
4013*cc02d7e2SAndroid Build Coastguard Worker /*
4014*cc02d7e2SAndroid Build Coastguard Worker * On GCC & Clang, marking 'dest' as modified will cause the compiler:
4015*cc02d7e2SAndroid Build Coastguard Worker * - do not extract the secret from sse registers in the internal loop
4016*cc02d7e2SAndroid Build Coastguard Worker * - use less common registers, and avoid pushing these reg into stack
4017*cc02d7e2SAndroid Build Coastguard Worker */
4018*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(dst16);
4019*cc02d7e2SAndroid Build Coastguard Worker # endif
4020*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */
4021*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)dst16 & 15) == 0);
4022*cc02d7e2SAndroid Build Coastguard Worker
4023*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < nbRounds; ++i) {
4024*cc02d7e2SAndroid Build Coastguard Worker dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed);
4025*cc02d7e2SAndroid Build Coastguard Worker } }
4026*cc02d7e2SAndroid Build Coastguard Worker }
4027*cc02d7e2SAndroid Build Coastguard Worker
4028*cc02d7e2SAndroid Build Coastguard Worker #endif
4029*cc02d7e2SAndroid Build Coastguard Worker
4030*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_NEON)
4031*cc02d7e2SAndroid Build Coastguard Worker
4032*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_accumulate_512_neon(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)4033*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4034*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
4035*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
4036*cc02d7e2SAndroid Build Coastguard Worker {
4037*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 15) == 0);
4038*cc02d7e2SAndroid Build Coastguard Worker {
4039*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t* const xacc = (uint64x2_t *) acc;
4040*cc02d7e2SAndroid Build Coastguard Worker /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
4041*cc02d7e2SAndroid Build Coastguard Worker uint8_t const* const xinput = (const uint8_t *) input;
4042*cc02d7e2SAndroid Build Coastguard Worker uint8_t const* const xsecret = (const uint8_t *) secret;
4043*cc02d7e2SAndroid Build Coastguard Worker
4044*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4045*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN / sizeof(uint64x2_t); i++) {
4046*cc02d7e2SAndroid Build Coastguard Worker /* data_vec = xinput[i]; */
4047*cc02d7e2SAndroid Build Coastguard Worker uint8x16_t data_vec = vld1q_u8(xinput + (i * 16));
4048*cc02d7e2SAndroid Build Coastguard Worker /* key_vec = xsecret[i]; */
4049*cc02d7e2SAndroid Build Coastguard Worker uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16));
4050*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t data_key;
4051*cc02d7e2SAndroid Build Coastguard Worker uint32x2_t data_key_lo, data_key_hi;
4052*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += swap(data_vec); */
4053*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec);
4054*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t const swapped = vextq_u64(data64, data64, 1);
4055*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = vaddq_u64 (xacc[i], swapped);
4056*cc02d7e2SAndroid Build Coastguard Worker /* data_key = data_vec ^ key_vec; */
4057*cc02d7e2SAndroid Build Coastguard Worker data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec));
4058*cc02d7e2SAndroid Build Coastguard Worker /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF);
4059*cc02d7e2SAndroid Build Coastguard Worker * data_key_hi = (uint32x2_t) (data_key >> 32);
4060*cc02d7e2SAndroid Build Coastguard Worker * data_key = UNDEFINED; */
4061*cc02d7e2SAndroid Build Coastguard Worker XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
4062*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */
4063*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi);
4064*cc02d7e2SAndroid Build Coastguard Worker
4065*cc02d7e2SAndroid Build Coastguard Worker }
4066*cc02d7e2SAndroid Build Coastguard Worker }
4067*cc02d7e2SAndroid Build Coastguard Worker }
4068*cc02d7e2SAndroid Build Coastguard Worker
4069*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_scrambleAcc_neon(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)4070*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4071*cc02d7e2SAndroid Build Coastguard Worker {
4072*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 15) == 0);
4073*cc02d7e2SAndroid Build Coastguard Worker
4074*cc02d7e2SAndroid Build Coastguard Worker { uint64x2_t* xacc = (uint64x2_t*) acc;
4075*cc02d7e2SAndroid Build Coastguard Worker uint8_t const* xsecret = (uint8_t const*) secret;
4076*cc02d7e2SAndroid Build Coastguard Worker uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1);
4077*cc02d7e2SAndroid Build Coastguard Worker
4078*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4079*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_STRIPE_LEN/sizeof(uint64x2_t); i++) {
4080*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= (xacc[i] >> 47); */
4081*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t acc_vec = xacc[i];
4082*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47);
4083*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t data_vec = veorq_u64 (acc_vec, shifted);
4084*cc02d7e2SAndroid Build Coastguard Worker
4085*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= xsecret[i]; */
4086*cc02d7e2SAndroid Build Coastguard Worker uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16));
4087*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec));
4088*cc02d7e2SAndroid Build Coastguard Worker
4089*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] *= XXH_PRIME32_1 */
4090*cc02d7e2SAndroid Build Coastguard Worker uint32x2_t data_key_lo, data_key_hi;
4091*cc02d7e2SAndroid Build Coastguard Worker /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF);
4092*cc02d7e2SAndroid Build Coastguard Worker * data_key_hi = (uint32x2_t) (xacc[i] >> 32);
4093*cc02d7e2SAndroid Build Coastguard Worker * xacc[i] = UNDEFINED; */
4094*cc02d7e2SAndroid Build Coastguard Worker XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
4095*cc02d7e2SAndroid Build Coastguard Worker { /*
4096*cc02d7e2SAndroid Build Coastguard Worker * prod_hi = (data_key >> 32) * XXH_PRIME32_1;
4097*cc02d7e2SAndroid Build Coastguard Worker *
4098*cc02d7e2SAndroid Build Coastguard Worker * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will
4099*cc02d7e2SAndroid Build Coastguard Worker * incorrectly "optimize" this:
4100*cc02d7e2SAndroid Build Coastguard Worker * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b));
4101*cc02d7e2SAndroid Build Coastguard Worker * shifted = vshll_n_u32(tmp, 32);
4102*cc02d7e2SAndroid Build Coastguard Worker * to this:
4103*cc02d7e2SAndroid Build Coastguard Worker * tmp = "vmulq_u64"(a, b); // no such thing!
4104*cc02d7e2SAndroid Build Coastguard Worker * shifted = vshlq_n_u64(tmp, 32);
4105*cc02d7e2SAndroid Build Coastguard Worker *
4106*cc02d7e2SAndroid Build Coastguard Worker * However, unlike SSE, Clang lacks a 64-bit multiply routine
4107*cc02d7e2SAndroid Build Coastguard Worker * for NEON, and it scalarizes two 64-bit multiplies instead.
4108*cc02d7e2SAndroid Build Coastguard Worker *
4109*cc02d7e2SAndroid Build Coastguard Worker * vmull_u32 has the same timing as vmul_u32, and it avoids
4110*cc02d7e2SAndroid Build Coastguard Worker * this bug completely.
4111*cc02d7e2SAndroid Build Coastguard Worker * See https://bugs.llvm.org/show_bug.cgi?id=39967
4112*cc02d7e2SAndroid Build Coastguard Worker */
4113*cc02d7e2SAndroid Build Coastguard Worker uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime);
4114*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] = prod_hi << 32; */
4115*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = vshlq_n_u64(prod_hi, 32);
4116*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */
4117*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime);
4118*cc02d7e2SAndroid Build Coastguard Worker }
4119*cc02d7e2SAndroid Build Coastguard Worker } }
4120*cc02d7e2SAndroid Build Coastguard Worker }
4121*cc02d7e2SAndroid Build Coastguard Worker
4122*cc02d7e2SAndroid Build Coastguard Worker #endif
4123*cc02d7e2SAndroid Build Coastguard Worker
4124*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_VSX)
4125*cc02d7e2SAndroid Build Coastguard Worker
4126*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_accumulate_512_vsx(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)4127*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
4128*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
4129*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
4130*cc02d7e2SAndroid Build Coastguard Worker {
4131*cc02d7e2SAndroid Build Coastguard Worker /* presumed aligned */
4132*cc02d7e2SAndroid Build Coastguard Worker unsigned long long* const xacc = (unsigned long long*) acc;
4133*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */
4134*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */
4135*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const v32 = { 32, 32 };
4136*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4137*cc02d7e2SAndroid Build Coastguard Worker for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
4138*cc02d7e2SAndroid Build Coastguard Worker /* data_vec = xinput[i]; */
4139*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i);
4140*cc02d7e2SAndroid Build Coastguard Worker /* key_vec = xsecret[i]; */
4141*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
4142*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const data_key = data_vec ^ key_vec;
4143*cc02d7e2SAndroid Build Coastguard Worker /* shuffled = (data_key << 32) | (data_key >> 32); */
4144*cc02d7e2SAndroid Build Coastguard Worker xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
4145*cc02d7e2SAndroid Build Coastguard Worker /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */
4146*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
4147*cc02d7e2SAndroid Build Coastguard Worker /* acc_vec = xacc[i]; */
4148*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 acc_vec = vec_xl(0, xacc + 2 * i);
4149*cc02d7e2SAndroid Build Coastguard Worker acc_vec += product;
4150*cc02d7e2SAndroid Build Coastguard Worker
4151*cc02d7e2SAndroid Build Coastguard Worker /* swap high and low halves */
4152*cc02d7e2SAndroid Build Coastguard Worker #ifdef __s390x__
4153*cc02d7e2SAndroid Build Coastguard Worker acc_vec += vec_permi(data_vec, data_vec, 2);
4154*cc02d7e2SAndroid Build Coastguard Worker #else
4155*cc02d7e2SAndroid Build Coastguard Worker acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
4156*cc02d7e2SAndroid Build Coastguard Worker #endif
4157*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] = acc_vec; */
4158*cc02d7e2SAndroid Build Coastguard Worker vec_xst(acc_vec, 0, xacc + 2 * i);
4159*cc02d7e2SAndroid Build Coastguard Worker }
4160*cc02d7e2SAndroid Build Coastguard Worker }
4161*cc02d7e2SAndroid Build Coastguard Worker
4162*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_scrambleAcc_vsx(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)4163*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4164*cc02d7e2SAndroid Build Coastguard Worker {
4165*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & 15) == 0);
4166*cc02d7e2SAndroid Build Coastguard Worker
4167*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64x2* const xacc = (xxh_u64x2*) acc;
4168*cc02d7e2SAndroid Build Coastguard Worker const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret;
4169*cc02d7e2SAndroid Build Coastguard Worker /* constants */
4170*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const v32 = { 32, 32 };
4171*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const v47 = { 47, 47 };
4172*cc02d7e2SAndroid Build Coastguard Worker xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 };
4173*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4174*cc02d7e2SAndroid Build Coastguard Worker for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
4175*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= (xacc[i] >> 47); */
4176*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const acc_vec = xacc[i];
4177*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47);
4178*cc02d7e2SAndroid Build Coastguard Worker
4179*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] ^= xsecret[i]; */
4180*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
4181*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const data_key = data_vec ^ key_vec;
4182*cc02d7e2SAndroid Build Coastguard Worker
4183*cc02d7e2SAndroid Build Coastguard Worker /* xacc[i] *= XXH_PRIME32_1 */
4184*cc02d7e2SAndroid Build Coastguard Worker /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */
4185*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime);
4186*cc02d7e2SAndroid Build Coastguard Worker /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */
4187*cc02d7e2SAndroid Build Coastguard Worker xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime);
4188*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = prod_odd + (prod_even << v32);
4189*cc02d7e2SAndroid Build Coastguard Worker } }
4190*cc02d7e2SAndroid Build Coastguard Worker }
4191*cc02d7e2SAndroid Build Coastguard Worker
4192*cc02d7e2SAndroid Build Coastguard Worker #endif
4193*cc02d7e2SAndroid Build Coastguard Worker
4194*cc02d7e2SAndroid Build Coastguard Worker /* scalar variants - universal */
4195*cc02d7e2SAndroid Build Coastguard Worker
4196*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_accumulate_512_scalar(void * XXH_RESTRICT acc,const void * XXH_RESTRICT input,const void * XXH_RESTRICT secret)4197*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
4198*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT input,
4199*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret)
4200*cc02d7e2SAndroid Build Coastguard Worker {
4201*cc02d7e2SAndroid Build Coastguard Worker xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4202*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const xinput = (const xxh_u8*) input; /* no alignment restriction */
4203*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
4204*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4205*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0);
4206*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_ACC_NB; i++) {
4207*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const data_val = XXH_readLE64(xinput + 8*i);
4208*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + i*8);
4209*cc02d7e2SAndroid Build Coastguard Worker xacc[i ^ 1] += data_val; /* swap adjacent lanes */
4210*cc02d7e2SAndroid Build Coastguard Worker xacc[i] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32);
4211*cc02d7e2SAndroid Build Coastguard Worker }
4212*cc02d7e2SAndroid Build Coastguard Worker }
4213*cc02d7e2SAndroid Build Coastguard Worker
4214*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_scrambleAcc_scalar(void * XXH_RESTRICT acc,const void * XXH_RESTRICT secret)4215*cc02d7e2SAndroid Build Coastguard Worker XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4216*cc02d7e2SAndroid Build Coastguard Worker {
4217*cc02d7e2SAndroid Build Coastguard Worker xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4218*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
4219*cc02d7e2SAndroid Build Coastguard Worker size_t i;
4220*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
4221*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < XXH_ACC_NB; i++) {
4222*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const key64 = XXH_readLE64(xsecret + 8*i);
4223*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 acc64 = xacc[i];
4224*cc02d7e2SAndroid Build Coastguard Worker acc64 = XXH_xorshift64(acc64, 47);
4225*cc02d7e2SAndroid Build Coastguard Worker acc64 ^= key64;
4226*cc02d7e2SAndroid Build Coastguard Worker acc64 *= XXH_PRIME32_1;
4227*cc02d7e2SAndroid Build Coastguard Worker xacc[i] = acc64;
4228*cc02d7e2SAndroid Build Coastguard Worker }
4229*cc02d7e2SAndroid Build Coastguard Worker }
4230*cc02d7e2SAndroid Build Coastguard Worker
4231*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_initCustomSecret_scalar(void * XXH_RESTRICT customSecret,xxh_u64 seed64)4232*cc02d7e2SAndroid Build Coastguard Worker XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
4233*cc02d7e2SAndroid Build Coastguard Worker {
4234*cc02d7e2SAndroid Build Coastguard Worker /*
4235*cc02d7e2SAndroid Build Coastguard Worker * We need a separate pointer for the hack below,
4236*cc02d7e2SAndroid Build Coastguard Worker * which requires a non-const pointer.
4237*cc02d7e2SAndroid Build Coastguard Worker * Any decent compiler will optimize this out otherwise.
4238*cc02d7e2SAndroid Build Coastguard Worker */
4239*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* kSecretPtr = XXH3_kSecret;
4240*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
4241*cc02d7e2SAndroid Build Coastguard Worker
4242*cc02d7e2SAndroid Build Coastguard Worker #if defined(__clang__) && defined(__aarch64__)
4243*cc02d7e2SAndroid Build Coastguard Worker /*
4244*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
4245*cc02d7e2SAndroid Build Coastguard Worker * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are
4246*cc02d7e2SAndroid Build Coastguard Worker * placed sequentially, in order, at the top of the unrolled loop.
4247*cc02d7e2SAndroid Build Coastguard Worker *
4248*cc02d7e2SAndroid Build Coastguard Worker * While MOVK is great for generating constants (2 cycles for a 64-bit
4249*cc02d7e2SAndroid Build Coastguard Worker * constant compared to 4 cycles for LDR), long MOVK chains stall the
4250*cc02d7e2SAndroid Build Coastguard Worker * integer pipelines:
4251*cc02d7e2SAndroid Build Coastguard Worker * I L S
4252*cc02d7e2SAndroid Build Coastguard Worker * MOVK
4253*cc02d7e2SAndroid Build Coastguard Worker * MOVK
4254*cc02d7e2SAndroid Build Coastguard Worker * MOVK
4255*cc02d7e2SAndroid Build Coastguard Worker * MOVK
4256*cc02d7e2SAndroid Build Coastguard Worker * ADD
4257*cc02d7e2SAndroid Build Coastguard Worker * SUB STR
4258*cc02d7e2SAndroid Build Coastguard Worker * STR
4259*cc02d7e2SAndroid Build Coastguard Worker * By forcing loads from memory (as the asm line causes Clang to assume
4260*cc02d7e2SAndroid Build Coastguard Worker * that XXH3_kSecretPtr has been changed), the pipelines are used more
4261*cc02d7e2SAndroid Build Coastguard Worker * efficiently:
4262*cc02d7e2SAndroid Build Coastguard Worker * I L S
4263*cc02d7e2SAndroid Build Coastguard Worker * LDR
4264*cc02d7e2SAndroid Build Coastguard Worker * ADD LDR
4265*cc02d7e2SAndroid Build Coastguard Worker * SUB STR
4266*cc02d7e2SAndroid Build Coastguard Worker * STR
4267*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits_withSeed, len == 256, Snapdragon 835
4268*cc02d7e2SAndroid Build Coastguard Worker * without hack: 2654.4 MB/s
4269*cc02d7e2SAndroid Build Coastguard Worker * with hack: 3202.9 MB/s
4270*cc02d7e2SAndroid Build Coastguard Worker */
4271*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(kSecretPtr);
4272*cc02d7e2SAndroid Build Coastguard Worker #endif
4273*cc02d7e2SAndroid Build Coastguard Worker /*
4274*cc02d7e2SAndroid Build Coastguard Worker * Note: in debug mode, this overrides the asm optimization
4275*cc02d7e2SAndroid Build Coastguard Worker * and Clang will emit MOVK chains again.
4276*cc02d7e2SAndroid Build Coastguard Worker */
4277*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(kSecretPtr == XXH3_kSecret);
4278*cc02d7e2SAndroid Build Coastguard Worker
4279*cc02d7e2SAndroid Build Coastguard Worker { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16;
4280*cc02d7e2SAndroid Build Coastguard Worker int i;
4281*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i < nbRounds; i++) {
4282*cc02d7e2SAndroid Build Coastguard Worker /*
4283*cc02d7e2SAndroid Build Coastguard Worker * The asm hack causes Clang to assume that kSecretPtr aliases with
4284*cc02d7e2SAndroid Build Coastguard Worker * customSecret, and on aarch64, this prevented LDP from merging two
4285*cc02d7e2SAndroid Build Coastguard Worker * loads together for free. Putting the loads together before the stores
4286*cc02d7e2SAndroid Build Coastguard Worker * properly generates LDP.
4287*cc02d7e2SAndroid Build Coastguard Worker */
4288*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64;
4289*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64;
4290*cc02d7e2SAndroid Build Coastguard Worker XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo);
4291*cc02d7e2SAndroid Build Coastguard Worker XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi);
4292*cc02d7e2SAndroid Build Coastguard Worker } }
4293*cc02d7e2SAndroid Build Coastguard Worker }
4294*cc02d7e2SAndroid Build Coastguard Worker
4295*cc02d7e2SAndroid Build Coastguard Worker
4296*cc02d7e2SAndroid Build Coastguard Worker typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*);
4297*cc02d7e2SAndroid Build Coastguard Worker typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*);
4298*cc02d7e2SAndroid Build Coastguard Worker typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
4299*cc02d7e2SAndroid Build Coastguard Worker
4300*cc02d7e2SAndroid Build Coastguard Worker
4301*cc02d7e2SAndroid Build Coastguard Worker #if (XXH_VECTOR == XXH_AVX512)
4302*cc02d7e2SAndroid Build Coastguard Worker
4303*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_avx512
4304*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_avx512
4305*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_avx512
4306*cc02d7e2SAndroid Build Coastguard Worker
4307*cc02d7e2SAndroid Build Coastguard Worker #elif (XXH_VECTOR == XXH_AVX2)
4308*cc02d7e2SAndroid Build Coastguard Worker
4309*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_avx2
4310*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_avx2
4311*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_avx2
4312*cc02d7e2SAndroid Build Coastguard Worker
4313*cc02d7e2SAndroid Build Coastguard Worker #elif (XXH_VECTOR == XXH_SSE2)
4314*cc02d7e2SAndroid Build Coastguard Worker
4315*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_sse2
4316*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_sse2
4317*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_sse2
4318*cc02d7e2SAndroid Build Coastguard Worker
4319*cc02d7e2SAndroid Build Coastguard Worker #elif (XXH_VECTOR == XXH_NEON)
4320*cc02d7e2SAndroid Build Coastguard Worker
4321*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_neon
4322*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_neon
4323*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4324*cc02d7e2SAndroid Build Coastguard Worker
4325*cc02d7e2SAndroid Build Coastguard Worker #elif (XXH_VECTOR == XXH_VSX)
4326*cc02d7e2SAndroid Build Coastguard Worker
4327*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_vsx
4328*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_vsx
4329*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4330*cc02d7e2SAndroid Build Coastguard Worker
4331*cc02d7e2SAndroid Build Coastguard Worker #else /* scalar */
4332*cc02d7e2SAndroid Build Coastguard Worker
4333*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_accumulate_512 XXH3_accumulate_512_scalar
4334*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
4335*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4336*cc02d7e2SAndroid Build Coastguard Worker
4337*cc02d7e2SAndroid Build Coastguard Worker #endif
4338*cc02d7e2SAndroid Build Coastguard Worker
4339*cc02d7e2SAndroid Build Coastguard Worker
4340*cc02d7e2SAndroid Build Coastguard Worker
4341*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH_PREFETCH_DIST
4342*cc02d7e2SAndroid Build Coastguard Worker # ifdef __clang__
4343*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH_DIST 320
4344*cc02d7e2SAndroid Build Coastguard Worker # else
4345*cc02d7e2SAndroid Build Coastguard Worker # if (XXH_VECTOR == XXH_AVX512)
4346*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH_DIST 512
4347*cc02d7e2SAndroid Build Coastguard Worker # else
4348*cc02d7e2SAndroid Build Coastguard Worker # define XXH_PREFETCH_DIST 384
4349*cc02d7e2SAndroid Build Coastguard Worker # endif
4350*cc02d7e2SAndroid Build Coastguard Worker # endif /* __clang__ */
4351*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_PREFETCH_DIST */
4352*cc02d7e2SAndroid Build Coastguard Worker
4353*cc02d7e2SAndroid Build Coastguard Worker /*
4354*cc02d7e2SAndroid Build Coastguard Worker * XXH3_accumulate()
4355*cc02d7e2SAndroid Build Coastguard Worker * Loops over XXH3_accumulate_512().
4356*cc02d7e2SAndroid Build Coastguard Worker * Assumption: nbStripes will not overflow the secret size
4357*cc02d7e2SAndroid Build Coastguard Worker */
4358*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_accumulate(xxh_u64 * XXH_RESTRICT acc,const xxh_u8 * XXH_RESTRICT input,const xxh_u8 * XXH_RESTRICT secret,size_t nbStripes,XXH3_f_accumulate_512 f_acc512)4359*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate( xxh_u64* XXH_RESTRICT acc,
4360*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT input,
4361*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret,
4362*cc02d7e2SAndroid Build Coastguard Worker size_t nbStripes,
4363*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512)
4364*cc02d7e2SAndroid Build Coastguard Worker {
4365*cc02d7e2SAndroid Build Coastguard Worker size_t n;
4366*cc02d7e2SAndroid Build Coastguard Worker for (n = 0; n < nbStripes; n++ ) {
4367*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const in = input + n*XXH_STRIPE_LEN;
4368*cc02d7e2SAndroid Build Coastguard Worker XXH_PREFETCH(in + XXH_PREFETCH_DIST);
4369*cc02d7e2SAndroid Build Coastguard Worker f_acc512(acc,
4370*cc02d7e2SAndroid Build Coastguard Worker in,
4371*cc02d7e2SAndroid Build Coastguard Worker secret + n*XXH_SECRET_CONSUME_RATE);
4372*cc02d7e2SAndroid Build Coastguard Worker }
4373*cc02d7e2SAndroid Build Coastguard Worker }
4374*cc02d7e2SAndroid Build Coastguard Worker
4375*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_hashLong_internal_loop(xxh_u64 * XXH_RESTRICT acc,const xxh_u8 * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble)4376*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc,
4377*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT input, size_t len,
4378*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
4379*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
4380*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble)
4381*cc02d7e2SAndroid Build Coastguard Worker {
4382*cc02d7e2SAndroid Build Coastguard Worker size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE;
4383*cc02d7e2SAndroid Build Coastguard Worker size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock;
4384*cc02d7e2SAndroid Build Coastguard Worker size_t const nb_blocks = (len - 1) / block_len;
4385*cc02d7e2SAndroid Build Coastguard Worker
4386*cc02d7e2SAndroid Build Coastguard Worker size_t n;
4387*cc02d7e2SAndroid Build Coastguard Worker
4388*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
4389*cc02d7e2SAndroid Build Coastguard Worker
4390*cc02d7e2SAndroid Build Coastguard Worker for (n = 0; n < nb_blocks; n++) {
4391*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512);
4392*cc02d7e2SAndroid Build Coastguard Worker f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN);
4393*cc02d7e2SAndroid Build Coastguard Worker }
4394*cc02d7e2SAndroid Build Coastguard Worker
4395*cc02d7e2SAndroid Build Coastguard Worker /* last partial block */
4396*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len > XXH_STRIPE_LEN);
4397*cc02d7e2SAndroid Build Coastguard Worker { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN;
4398*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE));
4399*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512);
4400*cc02d7e2SAndroid Build Coastguard Worker
4401*cc02d7e2SAndroid Build Coastguard Worker /* last stripe */
4402*cc02d7e2SAndroid Build Coastguard Worker { const xxh_u8* const p = input + len - XXH_STRIPE_LEN;
4403*cc02d7e2SAndroid Build Coastguard Worker #define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */
4404*cc02d7e2SAndroid Build Coastguard Worker f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START);
4405*cc02d7e2SAndroid Build Coastguard Worker } }
4406*cc02d7e2SAndroid Build Coastguard Worker }
4407*cc02d7e2SAndroid Build Coastguard Worker
4408*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE xxh_u64
XXH3_mix2Accs(const xxh_u64 * XXH_RESTRICT acc,const xxh_u8 * XXH_RESTRICT secret)4409*cc02d7e2SAndroid Build Coastguard Worker XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret)
4410*cc02d7e2SAndroid Build Coastguard Worker {
4411*cc02d7e2SAndroid Build Coastguard Worker return XXH3_mul128_fold64(
4412*cc02d7e2SAndroid Build Coastguard Worker acc[0] ^ XXH_readLE64(secret),
4413*cc02d7e2SAndroid Build Coastguard Worker acc[1] ^ XXH_readLE64(secret+8) );
4414*cc02d7e2SAndroid Build Coastguard Worker }
4415*cc02d7e2SAndroid Build Coastguard Worker
4416*cc02d7e2SAndroid Build Coastguard Worker static XXH64_hash_t
XXH3_mergeAccs(const xxh_u64 * XXH_RESTRICT acc,const xxh_u8 * XXH_RESTRICT secret,xxh_u64 start)4417*cc02d7e2SAndroid Build Coastguard Worker XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start)
4418*cc02d7e2SAndroid Build Coastguard Worker {
4419*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 result64 = start;
4420*cc02d7e2SAndroid Build Coastguard Worker size_t i = 0;
4421*cc02d7e2SAndroid Build Coastguard Worker
4422*cc02d7e2SAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
4423*cc02d7e2SAndroid Build Coastguard Worker result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i);
4424*cc02d7e2SAndroid Build Coastguard Worker #if defined(__clang__) /* Clang */ \
4425*cc02d7e2SAndroid Build Coastguard Worker && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \
4426*cc02d7e2SAndroid Build Coastguard Worker && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
4427*cc02d7e2SAndroid Build Coastguard Worker && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
4428*cc02d7e2SAndroid Build Coastguard Worker /*
4429*cc02d7e2SAndroid Build Coastguard Worker * UGLY HACK:
4430*cc02d7e2SAndroid Build Coastguard Worker * Prevent autovectorization on Clang ARMv7-a. Exact same problem as
4431*cc02d7e2SAndroid Build Coastguard Worker * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b.
4432*cc02d7e2SAndroid Build Coastguard Worker * XXH3_64bits, len == 256, Snapdragon 835:
4433*cc02d7e2SAndroid Build Coastguard Worker * without hack: 2063.7 MB/s
4434*cc02d7e2SAndroid Build Coastguard Worker * with hack: 2560.7 MB/s
4435*cc02d7e2SAndroid Build Coastguard Worker */
4436*cc02d7e2SAndroid Build Coastguard Worker XXH_COMPILER_GUARD(result64);
4437*cc02d7e2SAndroid Build Coastguard Worker #endif
4438*cc02d7e2SAndroid Build Coastguard Worker }
4439*cc02d7e2SAndroid Build Coastguard Worker
4440*cc02d7e2SAndroid Build Coastguard Worker return XXH3_avalanche(result64);
4441*cc02d7e2SAndroid Build Coastguard Worker }
4442*cc02d7e2SAndroid Build Coastguard Worker
4443*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
4444*cc02d7e2SAndroid Build Coastguard Worker XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
4445*cc02d7e2SAndroid Build Coastguard Worker
4446*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_hashLong_64b_internal(const void * XXH_RESTRICT input,size_t len,const void * XXH_RESTRICT secret,size_t secretSize,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble)4447*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
4448*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret, size_t secretSize,
4449*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
4450*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble)
4451*cc02d7e2SAndroid Build Coastguard Worker {
4452*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
4453*cc02d7e2SAndroid Build Coastguard Worker
4454*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble);
4455*cc02d7e2SAndroid Build Coastguard Worker
4456*cc02d7e2SAndroid Build Coastguard Worker /* converge into final hash */
4457*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(sizeof(acc) == 64);
4458*cc02d7e2SAndroid Build Coastguard Worker /* do not align on 8, so that the secret is different from the accumulator */
4459*cc02d7e2SAndroid Build Coastguard Worker #define XXH_SECRET_MERGEACCS_START 11
4460*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
4461*cc02d7e2SAndroid Build Coastguard Worker return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1);
4462*cc02d7e2SAndroid Build Coastguard Worker }
4463*cc02d7e2SAndroid Build Coastguard Worker
4464*cc02d7e2SAndroid Build Coastguard Worker /*
4465*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance to transmit secret's size (when it's static)
4466*cc02d7e2SAndroid Build Coastguard Worker * so that the compiler can properly optimize the vectorized loop.
4467*cc02d7e2SAndroid Build Coastguard Worker * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set.
4468*cc02d7e2SAndroid Build Coastguard Worker */
4469*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_hashLong_64b_withSecret(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,const xxh_u8 * XXH_RESTRICT secret,size_t secretLen)4470*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
4471*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4472*cc02d7e2SAndroid Build Coastguard Worker {
4473*cc02d7e2SAndroid Build Coastguard Worker (void)seed64;
4474*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc);
4475*cc02d7e2SAndroid Build Coastguard Worker }
4476*cc02d7e2SAndroid Build Coastguard Worker
4477*cc02d7e2SAndroid Build Coastguard Worker /*
4478*cc02d7e2SAndroid Build Coastguard Worker * It's preferable for performance that XXH3_hashLong is not inlined,
4479*cc02d7e2SAndroid Build Coastguard Worker * as it results in a smaller function for small data, easier to the instruction cache.
4480*cc02d7e2SAndroid Build Coastguard Worker * Note that inside this no_inline function, we do inline the internal loop,
4481*cc02d7e2SAndroid Build Coastguard Worker * and provide a statically defined secret size to allow optimization of vector loop.
4482*cc02d7e2SAndroid Build Coastguard Worker */
4483*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH64_hash_t
XXH3_hashLong_64b_default(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,const xxh_u8 * XXH_RESTRICT secret,size_t secretLen)4484*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
4485*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4486*cc02d7e2SAndroid Build Coastguard Worker {
4487*cc02d7e2SAndroid Build Coastguard Worker (void)seed64; (void)secret; (void)secretLen;
4488*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc);
4489*cc02d7e2SAndroid Build Coastguard Worker }
4490*cc02d7e2SAndroid Build Coastguard Worker
4491*cc02d7e2SAndroid Build Coastguard Worker /*
4492*cc02d7e2SAndroid Build Coastguard Worker * XXH3_hashLong_64b_withSeed():
4493*cc02d7e2SAndroid Build Coastguard Worker * Generate a custom key based on alteration of default XXH3_kSecret with the seed,
4494*cc02d7e2SAndroid Build Coastguard Worker * and then use this key for long mode hashing.
4495*cc02d7e2SAndroid Build Coastguard Worker *
4496*cc02d7e2SAndroid Build Coastguard Worker * This operation is decently fast but nonetheless costs a little bit of time.
4497*cc02d7e2SAndroid Build Coastguard Worker * Try to avoid it whenever possible (typically when seed==0).
4498*cc02d7e2SAndroid Build Coastguard Worker *
4499*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance that XXH3_hashLong is not inlined. Not sure
4500*cc02d7e2SAndroid Build Coastguard Worker * why (uop cache maybe?), but the difference is large and easily measurable.
4501*cc02d7e2SAndroid Build Coastguard Worker */
4502*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_hashLong_64b_withSeed_internal(const void * input,size_t len,XXH64_hash_t seed,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble,XXH3_f_initCustomSecret f_initSec)4503*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len,
4504*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed,
4505*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
4506*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble,
4507*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_initCustomSecret f_initSec)
4508*cc02d7e2SAndroid Build Coastguard Worker {
4509*cc02d7e2SAndroid Build Coastguard Worker if (seed == 0)
4510*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_internal(input, len,
4511*cc02d7e2SAndroid Build Coastguard Worker XXH3_kSecret, sizeof(XXH3_kSecret),
4512*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
4513*cc02d7e2SAndroid Build Coastguard Worker { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
4514*cc02d7e2SAndroid Build Coastguard Worker f_initSec(secret, seed);
4515*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret),
4516*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
4517*cc02d7e2SAndroid Build Coastguard Worker }
4518*cc02d7e2SAndroid Build Coastguard Worker }
4519*cc02d7e2SAndroid Build Coastguard Worker
4520*cc02d7e2SAndroid Build Coastguard Worker /*
4521*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance that XXH3_hashLong is not inlined.
4522*cc02d7e2SAndroid Build Coastguard Worker */
4523*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH64_hash_t
XXH3_hashLong_64b_withSeed(const void * input,size_t len,XXH64_hash_t seed,const xxh_u8 * secret,size_t secretLen)4524*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_64b_withSeed(const void* input, size_t len,
4525*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen)
4526*cc02d7e2SAndroid Build Coastguard Worker {
4527*cc02d7e2SAndroid Build Coastguard Worker (void)secret; (void)secretLen;
4528*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_withSeed_internal(input, len, seed,
4529*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
4530*cc02d7e2SAndroid Build Coastguard Worker }
4531*cc02d7e2SAndroid Build Coastguard Worker
4532*cc02d7e2SAndroid Build Coastguard Worker
4533*cc02d7e2SAndroid Build Coastguard Worker typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t,
4534*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t);
4535*cc02d7e2SAndroid Build Coastguard Worker
4536*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH64_hash_t
XXH3_64bits_internal(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,const void * XXH_RESTRICT secret,size_t secretLen,XXH3_hashLong64_f f_hashLong)4537*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
4538*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
4539*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong64_f f_hashLong)
4540*cc02d7e2SAndroid Build Coastguard Worker {
4541*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
4542*cc02d7e2SAndroid Build Coastguard Worker /*
4543*cc02d7e2SAndroid Build Coastguard Worker * If an action is to be taken if `secretLen` condition is not respected,
4544*cc02d7e2SAndroid Build Coastguard Worker * it should be done here.
4545*cc02d7e2SAndroid Build Coastguard Worker * For now, it's a contract pre-condition.
4546*cc02d7e2SAndroid Build Coastguard Worker * Adding a check and a branch here would cost performance at every hash.
4547*cc02d7e2SAndroid Build Coastguard Worker * Also, note that function signature doesn't offer room to return an error.
4548*cc02d7e2SAndroid Build Coastguard Worker */
4549*cc02d7e2SAndroid Build Coastguard Worker if (len <= 16)
4550*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
4551*cc02d7e2SAndroid Build Coastguard Worker if (len <= 128)
4552*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
4553*cc02d7e2SAndroid Build Coastguard Worker if (len <= XXH3_MIDSIZE_MAX)
4554*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
4555*cc02d7e2SAndroid Build Coastguard Worker return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen);
4556*cc02d7e2SAndroid Build Coastguard Worker }
4557*cc02d7e2SAndroid Build Coastguard Worker
4558*cc02d7e2SAndroid Build Coastguard Worker
4559*cc02d7e2SAndroid Build Coastguard Worker /* === Public entry point === */
4560*cc02d7e2SAndroid Build Coastguard Worker
4561*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_64bits(const void * input,size_t len)4562*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len)
4563*cc02d7e2SAndroid Build Coastguard Worker {
4564*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
4565*cc02d7e2SAndroid Build Coastguard Worker }
4566*cc02d7e2SAndroid Build Coastguard Worker
4567*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4568*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t
XXH3_64bits_withSecret(const void * input,size_t len,const void * secret,size_t secretSize)4569*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
4570*cc02d7e2SAndroid Build Coastguard Worker {
4571*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
4572*cc02d7e2SAndroid Build Coastguard Worker }
4573*cc02d7e2SAndroid Build Coastguard Worker
4574*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4575*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t
XXH3_64bits_withSeed(const void * input,size_t len,XXH64_hash_t seed)4576*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
4577*cc02d7e2SAndroid Build Coastguard Worker {
4578*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
4579*cc02d7e2SAndroid Build Coastguard Worker }
4580*cc02d7e2SAndroid Build Coastguard Worker
4581*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t
XXH3_64bits_withSecretandSeed(const void * input,size_t len,const void * secret,size_t secretSize,XXH64_hash_t seed)4582*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
4583*cc02d7e2SAndroid Build Coastguard Worker {
4584*cc02d7e2SAndroid Build Coastguard Worker if (len <= XXH3_MIDSIZE_MAX)
4585*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
4586*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
4587*cc02d7e2SAndroid Build Coastguard Worker }
4588*cc02d7e2SAndroid Build Coastguard Worker
4589*cc02d7e2SAndroid Build Coastguard Worker
4590*cc02d7e2SAndroid Build Coastguard Worker /* === XXH3 streaming === */
4591*cc02d7e2SAndroid Build Coastguard Worker
4592*cc02d7e2SAndroid Build Coastguard Worker /*
4593*cc02d7e2SAndroid Build Coastguard Worker * Malloc's a pointer that is always aligned to align.
4594*cc02d7e2SAndroid Build Coastguard Worker *
4595*cc02d7e2SAndroid Build Coastguard Worker * This must be freed with `XXH_alignedFree()`.
4596*cc02d7e2SAndroid Build Coastguard Worker *
4597*cc02d7e2SAndroid Build Coastguard Worker * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte
4598*cc02d7e2SAndroid Build Coastguard Worker * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2
4599*cc02d7e2SAndroid Build Coastguard Worker * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON.
4600*cc02d7e2SAndroid Build Coastguard Worker *
4601*cc02d7e2SAndroid Build Coastguard Worker * This underalignment previously caused a rather obvious crash which went
4602*cc02d7e2SAndroid Build Coastguard Worker * completely unnoticed due to XXH3_createState() not actually being tested.
4603*cc02d7e2SAndroid Build Coastguard Worker * Credit to RedSpah for noticing this bug.
4604*cc02d7e2SAndroid Build Coastguard Worker *
4605*cc02d7e2SAndroid Build Coastguard Worker * The alignment is done manually: Functions like posix_memalign or _mm_malloc
4606*cc02d7e2SAndroid Build Coastguard Worker * are avoided: To maintain portability, we would have to write a fallback
4607*cc02d7e2SAndroid Build Coastguard Worker * like this anyways, and besides, testing for the existence of library
4608*cc02d7e2SAndroid Build Coastguard Worker * functions without relying on external build tools is impossible.
4609*cc02d7e2SAndroid Build Coastguard Worker *
4610*cc02d7e2SAndroid Build Coastguard Worker * The method is simple: Overallocate, manually align, and store the offset
4611*cc02d7e2SAndroid Build Coastguard Worker * to the original behind the returned pointer.
4612*cc02d7e2SAndroid Build Coastguard Worker *
4613*cc02d7e2SAndroid Build Coastguard Worker * Align must be a power of 2 and 8 <= align <= 128.
4614*cc02d7e2SAndroid Build Coastguard Worker */
XXH_alignedMalloc(size_t s,size_t align)4615*cc02d7e2SAndroid Build Coastguard Worker static void* XXH_alignedMalloc(size_t s, size_t align)
4616*cc02d7e2SAndroid Build Coastguard Worker {
4617*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(align <= 128 && align >= 8); /* range check */
4618*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
4619*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */
4620*cc02d7e2SAndroid Build Coastguard Worker { /* Overallocate to make room for manual realignment and an offset byte */
4621*cc02d7e2SAndroid Build Coastguard Worker xxh_u8* base = (xxh_u8*)XXH_malloc(s + align);
4622*cc02d7e2SAndroid Build Coastguard Worker if (base != NULL) {
4623*cc02d7e2SAndroid Build Coastguard Worker /*
4624*cc02d7e2SAndroid Build Coastguard Worker * Get the offset needed to align this pointer.
4625*cc02d7e2SAndroid Build Coastguard Worker *
4626*cc02d7e2SAndroid Build Coastguard Worker * Even if the returned pointer is aligned, there will always be
4627*cc02d7e2SAndroid Build Coastguard Worker * at least one byte to store the offset to the original pointer.
4628*cc02d7e2SAndroid Build Coastguard Worker */
4629*cc02d7e2SAndroid Build Coastguard Worker size_t offset = align - ((size_t)base & (align - 1)); /* base % align */
4630*cc02d7e2SAndroid Build Coastguard Worker /* Add the offset for the now-aligned pointer */
4631*cc02d7e2SAndroid Build Coastguard Worker xxh_u8* ptr = base + offset;
4632*cc02d7e2SAndroid Build Coastguard Worker
4633*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT((size_t)ptr % align == 0);
4634*cc02d7e2SAndroid Build Coastguard Worker
4635*cc02d7e2SAndroid Build Coastguard Worker /* Store the offset immediately before the returned pointer. */
4636*cc02d7e2SAndroid Build Coastguard Worker ptr[-1] = (xxh_u8)offset;
4637*cc02d7e2SAndroid Build Coastguard Worker return ptr;
4638*cc02d7e2SAndroid Build Coastguard Worker }
4639*cc02d7e2SAndroid Build Coastguard Worker return NULL;
4640*cc02d7e2SAndroid Build Coastguard Worker }
4641*cc02d7e2SAndroid Build Coastguard Worker }
4642*cc02d7e2SAndroid Build Coastguard Worker /*
4643*cc02d7e2SAndroid Build Coastguard Worker * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass
4644*cc02d7e2SAndroid Build Coastguard Worker * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout.
4645*cc02d7e2SAndroid Build Coastguard Worker */
XXH_alignedFree(void * p)4646*cc02d7e2SAndroid Build Coastguard Worker static void XXH_alignedFree(void* p)
4647*cc02d7e2SAndroid Build Coastguard Worker {
4648*cc02d7e2SAndroid Build Coastguard Worker if (p != NULL) {
4649*cc02d7e2SAndroid Build Coastguard Worker xxh_u8* ptr = (xxh_u8*)p;
4650*cc02d7e2SAndroid Build Coastguard Worker /* Get the offset byte we added in XXH_malloc. */
4651*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 offset = ptr[-1];
4652*cc02d7e2SAndroid Build Coastguard Worker /* Free the original malloc'd pointer */
4653*cc02d7e2SAndroid Build Coastguard Worker xxh_u8* base = ptr - offset;
4654*cc02d7e2SAndroid Build Coastguard Worker XXH_free(base);
4655*cc02d7e2SAndroid Build Coastguard Worker }
4656*cc02d7e2SAndroid Build Coastguard Worker }
4657*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_createState(void)4658*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
4659*cc02d7e2SAndroid Build Coastguard Worker {
4660*cc02d7e2SAndroid Build Coastguard Worker XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
4661*cc02d7e2SAndroid Build Coastguard Worker if (state==NULL) return NULL;
4662*cc02d7e2SAndroid Build Coastguard Worker XXH3_INITSTATE(state);
4663*cc02d7e2SAndroid Build Coastguard Worker return state;
4664*cc02d7e2SAndroid Build Coastguard Worker }
4665*cc02d7e2SAndroid Build Coastguard Worker
4666*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_freeState(XXH3_state_t * statePtr)4667*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
4668*cc02d7e2SAndroid Build Coastguard Worker {
4669*cc02d7e2SAndroid Build Coastguard Worker XXH_alignedFree(statePtr);
4670*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4671*cc02d7e2SAndroid Build Coastguard Worker }
4672*cc02d7e2SAndroid Build Coastguard Worker
4673*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4674*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void
XXH3_copyState(XXH3_state_t * dst_state,const XXH3_state_t * src_state)4675*cc02d7e2SAndroid Build Coastguard Worker XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
4676*cc02d7e2SAndroid Build Coastguard Worker {
4677*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dst_state, src_state, sizeof(*dst_state));
4678*cc02d7e2SAndroid Build Coastguard Worker }
4679*cc02d7e2SAndroid Build Coastguard Worker
4680*cc02d7e2SAndroid Build Coastguard Worker static void
XXH3_reset_internal(XXH3_state_t * statePtr,XXH64_hash_t seed,const void * secret,size_t secretSize)4681*cc02d7e2SAndroid Build Coastguard Worker XXH3_reset_internal(XXH3_state_t* statePtr,
4682*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed,
4683*cc02d7e2SAndroid Build Coastguard Worker const void* secret, size_t secretSize)
4684*cc02d7e2SAndroid Build Coastguard Worker {
4685*cc02d7e2SAndroid Build Coastguard Worker size_t const initStart = offsetof(XXH3_state_t, bufferedSize);
4686*cc02d7e2SAndroid Build Coastguard Worker size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart;
4687*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart);
4688*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(statePtr != NULL);
4689*cc02d7e2SAndroid Build Coastguard Worker /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */
4690*cc02d7e2SAndroid Build Coastguard Worker memset((char*)statePtr + initStart, 0, initLength);
4691*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[0] = XXH_PRIME32_3;
4692*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[1] = XXH_PRIME64_1;
4693*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[2] = XXH_PRIME64_2;
4694*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[3] = XXH_PRIME64_3;
4695*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[4] = XXH_PRIME64_4;
4696*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[5] = XXH_PRIME32_2;
4697*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[6] = XXH_PRIME64_5;
4698*cc02d7e2SAndroid Build Coastguard Worker statePtr->acc[7] = XXH_PRIME32_1;
4699*cc02d7e2SAndroid Build Coastguard Worker statePtr->seed = seed;
4700*cc02d7e2SAndroid Build Coastguard Worker statePtr->useSeed = (seed != 0);
4701*cc02d7e2SAndroid Build Coastguard Worker statePtr->extSecret = (const unsigned char*)secret;
4702*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
4703*cc02d7e2SAndroid Build Coastguard Worker statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
4704*cc02d7e2SAndroid Build Coastguard Worker statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
4705*cc02d7e2SAndroid Build Coastguard Worker }
4706*cc02d7e2SAndroid Build Coastguard Worker
4707*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4708*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_64bits_reset(XXH3_state_t * statePtr)4709*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_reset(XXH3_state_t* statePtr)
4710*cc02d7e2SAndroid Build Coastguard Worker {
4711*cc02d7e2SAndroid Build Coastguard Worker if (statePtr == NULL) return XXH_ERROR;
4712*cc02d7e2SAndroid Build Coastguard Worker XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
4713*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4714*cc02d7e2SAndroid Build Coastguard Worker }
4715*cc02d7e2SAndroid Build Coastguard Worker
4716*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4717*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_64bits_reset_withSecret(XXH3_state_t * statePtr,const void * secret,size_t secretSize)4718*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
4719*cc02d7e2SAndroid Build Coastguard Worker {
4720*cc02d7e2SAndroid Build Coastguard Worker if (statePtr == NULL) return XXH_ERROR;
4721*cc02d7e2SAndroid Build Coastguard Worker XXH3_reset_internal(statePtr, 0, secret, secretSize);
4722*cc02d7e2SAndroid Build Coastguard Worker if (secret == NULL) return XXH_ERROR;
4723*cc02d7e2SAndroid Build Coastguard Worker if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
4724*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4725*cc02d7e2SAndroid Build Coastguard Worker }
4726*cc02d7e2SAndroid Build Coastguard Worker
4727*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4728*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_64bits_reset_withSeed(XXH3_state_t * statePtr,XXH64_hash_t seed)4729*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
4730*cc02d7e2SAndroid Build Coastguard Worker {
4731*cc02d7e2SAndroid Build Coastguard Worker if (statePtr == NULL) return XXH_ERROR;
4732*cc02d7e2SAndroid Build Coastguard Worker if (seed==0) return XXH3_64bits_reset(statePtr);
4733*cc02d7e2SAndroid Build Coastguard Worker if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
4734*cc02d7e2SAndroid Build Coastguard Worker XXH3_initCustomSecret(statePtr->customSecret, seed);
4735*cc02d7e2SAndroid Build Coastguard Worker XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
4736*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4737*cc02d7e2SAndroid Build Coastguard Worker }
4738*cc02d7e2SAndroid Build Coastguard Worker
4739*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4740*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_64bits_reset_withSecretandSeed(XXH3_state_t * statePtr,const void * secret,size_t secretSize,XXH64_hash_t seed64)4741*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
4742*cc02d7e2SAndroid Build Coastguard Worker {
4743*cc02d7e2SAndroid Build Coastguard Worker if (statePtr == NULL) return XXH_ERROR;
4744*cc02d7e2SAndroid Build Coastguard Worker if (secret == NULL) return XXH_ERROR;
4745*cc02d7e2SAndroid Build Coastguard Worker if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
4746*cc02d7e2SAndroid Build Coastguard Worker XXH3_reset_internal(statePtr, seed64, secret, secretSize);
4747*cc02d7e2SAndroid Build Coastguard Worker statePtr->useSeed = 1; /* always, even if seed64==0 */
4748*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4749*cc02d7e2SAndroid Build Coastguard Worker }
4750*cc02d7e2SAndroid Build Coastguard Worker
4751*cc02d7e2SAndroid Build Coastguard Worker /* Note : when XXH3_consumeStripes() is invoked,
4752*cc02d7e2SAndroid Build Coastguard Worker * there must be a guarantee that at least one more byte must be consumed from input
4753*cc02d7e2SAndroid Build Coastguard Worker * so that the function can blindly consume all stripes using the "normal" secret segment */
4754*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_consumeStripes(xxh_u64 * XXH_RESTRICT acc,size_t * XXH_RESTRICT nbStripesSoFarPtr,size_t nbStripesPerBlock,const xxh_u8 * XXH_RESTRICT input,size_t nbStripes,const xxh_u8 * XXH_RESTRICT secret,size_t secretLimit,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble)4755*cc02d7e2SAndroid Build Coastguard Worker XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
4756*cc02d7e2SAndroid Build Coastguard Worker size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock,
4757*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT input, size_t nbStripes,
4758*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretLimit,
4759*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
4760*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble)
4761*cc02d7e2SAndroid Build Coastguard Worker {
4762*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */
4763*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock);
4764*cc02d7e2SAndroid Build Coastguard Worker if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) {
4765*cc02d7e2SAndroid Build Coastguard Worker /* need a scrambling operation */
4766*cc02d7e2SAndroid Build Coastguard Worker size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr;
4767*cc02d7e2SAndroid Build Coastguard Worker size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock;
4768*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512);
4769*cc02d7e2SAndroid Build Coastguard Worker f_scramble(acc, secret + secretLimit);
4770*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512);
4771*cc02d7e2SAndroid Build Coastguard Worker *nbStripesSoFarPtr = nbStripesAfterBlock;
4772*cc02d7e2SAndroid Build Coastguard Worker } else {
4773*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512);
4774*cc02d7e2SAndroid Build Coastguard Worker *nbStripesSoFarPtr += nbStripes;
4775*cc02d7e2SAndroid Build Coastguard Worker }
4776*cc02d7e2SAndroid Build Coastguard Worker }
4777*cc02d7e2SAndroid Build Coastguard Worker
4778*cc02d7e2SAndroid Build Coastguard Worker #ifndef XXH3_STREAM_USE_STACK
4779*cc02d7e2SAndroid Build Coastguard Worker # ifndef __clang__ /* clang doesn't need additional stack space */
4780*cc02d7e2SAndroid Build Coastguard Worker # define XXH3_STREAM_USE_STACK 1
4781*cc02d7e2SAndroid Build Coastguard Worker # endif
4782*cc02d7e2SAndroid Build Coastguard Worker #endif
4783*cc02d7e2SAndroid Build Coastguard Worker /*
4784*cc02d7e2SAndroid Build Coastguard Worker * Both XXH3_64bits_update and XXH3_128bits_update use this routine.
4785*cc02d7e2SAndroid Build Coastguard Worker */
4786*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH_errorcode
XXH3_update(XXH3_state_t * XXH_RESTRICT const state,const xxh_u8 * XXH_RESTRICT input,size_t len,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble)4787*cc02d7e2SAndroid Build Coastguard Worker XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
4788*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT input, size_t len,
4789*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
4790*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble)
4791*cc02d7e2SAndroid Build Coastguard Worker {
4792*cc02d7e2SAndroid Build Coastguard Worker if (input==NULL) {
4793*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len == 0);
4794*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4795*cc02d7e2SAndroid Build Coastguard Worker }
4796*cc02d7e2SAndroid Build Coastguard Worker
4797*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state != NULL);
4798*cc02d7e2SAndroid Build Coastguard Worker { const xxh_u8* const bEnd = input + len;
4799*cc02d7e2SAndroid Build Coastguard Worker const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
4800*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4801*cc02d7e2SAndroid Build Coastguard Worker /* For some reason, gcc and MSVC seem to suffer greatly
4802*cc02d7e2SAndroid Build Coastguard Worker * when operating accumulators directly into state.
4803*cc02d7e2SAndroid Build Coastguard Worker * Operating into stack space seems to enable proper optimization.
4804*cc02d7e2SAndroid Build Coastguard Worker * clang, on the other hand, doesn't seem to need this trick */
4805*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc));
4806*cc02d7e2SAndroid Build Coastguard Worker #else
4807*cc02d7e2SAndroid Build Coastguard Worker xxh_u64* XXH_RESTRICT const acc = state->acc;
4808*cc02d7e2SAndroid Build Coastguard Worker #endif
4809*cc02d7e2SAndroid Build Coastguard Worker state->totalLen += len;
4810*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
4811*cc02d7e2SAndroid Build Coastguard Worker
4812*cc02d7e2SAndroid Build Coastguard Worker /* small input : just fill in tmp buffer */
4813*cc02d7e2SAndroid Build Coastguard Worker if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) {
4814*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->buffer + state->bufferedSize, input, len);
4815*cc02d7e2SAndroid Build Coastguard Worker state->bufferedSize += (XXH32_hash_t)len;
4816*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4817*cc02d7e2SAndroid Build Coastguard Worker }
4818*cc02d7e2SAndroid Build Coastguard Worker
4819*cc02d7e2SAndroid Build Coastguard Worker /* total input is now > XXH3_INTERNALBUFFER_SIZE */
4820*cc02d7e2SAndroid Build Coastguard Worker #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
4821*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */
4822*cc02d7e2SAndroid Build Coastguard Worker
4823*cc02d7e2SAndroid Build Coastguard Worker /*
4824*cc02d7e2SAndroid Build Coastguard Worker * Internal buffer is partially filled (always, except at beginning)
4825*cc02d7e2SAndroid Build Coastguard Worker * Complete it, then consume it.
4826*cc02d7e2SAndroid Build Coastguard Worker */
4827*cc02d7e2SAndroid Build Coastguard Worker if (state->bufferedSize) {
4828*cc02d7e2SAndroid Build Coastguard Worker size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
4829*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize);
4830*cc02d7e2SAndroid Build Coastguard Worker input += loadSize;
4831*cc02d7e2SAndroid Build Coastguard Worker XXH3_consumeStripes(acc,
4832*cc02d7e2SAndroid Build Coastguard Worker &state->nbStripesSoFar, state->nbStripesPerBlock,
4833*cc02d7e2SAndroid Build Coastguard Worker state->buffer, XXH3_INTERNALBUFFER_STRIPES,
4834*cc02d7e2SAndroid Build Coastguard Worker secret, state->secretLimit,
4835*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
4836*cc02d7e2SAndroid Build Coastguard Worker state->bufferedSize = 0;
4837*cc02d7e2SAndroid Build Coastguard Worker }
4838*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input < bEnd);
4839*cc02d7e2SAndroid Build Coastguard Worker
4840*cc02d7e2SAndroid Build Coastguard Worker /* large input to consume : ingest per full block */
4841*cc02d7e2SAndroid Build Coastguard Worker if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) {
4842*cc02d7e2SAndroid Build Coastguard Worker size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN;
4843*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar);
4844*cc02d7e2SAndroid Build Coastguard Worker /* join to current block's end */
4845*cc02d7e2SAndroid Build Coastguard Worker { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar;
4846*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(nbStripes <= nbStripes);
4847*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512);
4848*cc02d7e2SAndroid Build Coastguard Worker f_scramble(acc, secret + state->secretLimit);
4849*cc02d7e2SAndroid Build Coastguard Worker state->nbStripesSoFar = 0;
4850*cc02d7e2SAndroid Build Coastguard Worker input += nbStripesToEnd * XXH_STRIPE_LEN;
4851*cc02d7e2SAndroid Build Coastguard Worker nbStripes -= nbStripesToEnd;
4852*cc02d7e2SAndroid Build Coastguard Worker }
4853*cc02d7e2SAndroid Build Coastguard Worker /* consume per entire blocks */
4854*cc02d7e2SAndroid Build Coastguard Worker while(nbStripes >= state->nbStripesPerBlock) {
4855*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512);
4856*cc02d7e2SAndroid Build Coastguard Worker f_scramble(acc, secret + state->secretLimit);
4857*cc02d7e2SAndroid Build Coastguard Worker input += state->nbStripesPerBlock * XXH_STRIPE_LEN;
4858*cc02d7e2SAndroid Build Coastguard Worker nbStripes -= state->nbStripesPerBlock;
4859*cc02d7e2SAndroid Build Coastguard Worker }
4860*cc02d7e2SAndroid Build Coastguard Worker /* consume last partial block */
4861*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate(acc, input, secret, nbStripes, f_acc512);
4862*cc02d7e2SAndroid Build Coastguard Worker input += nbStripes * XXH_STRIPE_LEN;
4863*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input < bEnd); /* at least some bytes left */
4864*cc02d7e2SAndroid Build Coastguard Worker state->nbStripesSoFar = nbStripes;
4865*cc02d7e2SAndroid Build Coastguard Worker /* buffer predecessor of last partial stripe */
4866*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4867*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN);
4868*cc02d7e2SAndroid Build Coastguard Worker } else {
4869*cc02d7e2SAndroid Build Coastguard Worker /* content to consume <= block size */
4870*cc02d7e2SAndroid Build Coastguard Worker /* Consume input by a multiple of internal buffer size */
4871*cc02d7e2SAndroid Build Coastguard Worker if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) {
4872*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
4873*cc02d7e2SAndroid Build Coastguard Worker do {
4874*cc02d7e2SAndroid Build Coastguard Worker XXH3_consumeStripes(acc,
4875*cc02d7e2SAndroid Build Coastguard Worker &state->nbStripesSoFar, state->nbStripesPerBlock,
4876*cc02d7e2SAndroid Build Coastguard Worker input, XXH3_INTERNALBUFFER_STRIPES,
4877*cc02d7e2SAndroid Build Coastguard Worker secret, state->secretLimit,
4878*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
4879*cc02d7e2SAndroid Build Coastguard Worker input += XXH3_INTERNALBUFFER_SIZE;
4880*cc02d7e2SAndroid Build Coastguard Worker } while (input<limit);
4881*cc02d7e2SAndroid Build Coastguard Worker /* buffer predecessor of last partial stripe */
4882*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4883*cc02d7e2SAndroid Build Coastguard Worker }
4884*cc02d7e2SAndroid Build Coastguard Worker }
4885*cc02d7e2SAndroid Build Coastguard Worker
4886*cc02d7e2SAndroid Build Coastguard Worker /* Some remaining input (always) : buffer it */
4887*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input < bEnd);
4888*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE);
4889*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state->bufferedSize == 0);
4890*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(state->buffer, input, (size_t)(bEnd-input));
4891*cc02d7e2SAndroid Build Coastguard Worker state->bufferedSize = (XXH32_hash_t)(bEnd-input);
4892*cc02d7e2SAndroid Build Coastguard Worker #if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4893*cc02d7e2SAndroid Build Coastguard Worker /* save stack accumulators into state */
4894*cc02d7e2SAndroid Build Coastguard Worker memcpy(state->acc, acc, sizeof(acc));
4895*cc02d7e2SAndroid Build Coastguard Worker #endif
4896*cc02d7e2SAndroid Build Coastguard Worker }
4897*cc02d7e2SAndroid Build Coastguard Worker
4898*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
4899*cc02d7e2SAndroid Build Coastguard Worker }
4900*cc02d7e2SAndroid Build Coastguard Worker
4901*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
4902*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_64bits_update(XXH3_state_t * state,const void * input,size_t len)4903*cc02d7e2SAndroid Build Coastguard Worker XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
4904*cc02d7e2SAndroid Build Coastguard Worker {
4905*cc02d7e2SAndroid Build Coastguard Worker return XXH3_update(state, (const xxh_u8*)input, len,
4906*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc);
4907*cc02d7e2SAndroid Build Coastguard Worker }
4908*cc02d7e2SAndroid Build Coastguard Worker
4909*cc02d7e2SAndroid Build Coastguard Worker
4910*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE void
XXH3_digest_long(XXH64_hash_t * acc,const XXH3_state_t * state,const unsigned char * secret)4911*cc02d7e2SAndroid Build Coastguard Worker XXH3_digest_long (XXH64_hash_t* acc,
4912*cc02d7e2SAndroid Build Coastguard Worker const XXH3_state_t* state,
4913*cc02d7e2SAndroid Build Coastguard Worker const unsigned char* secret)
4914*cc02d7e2SAndroid Build Coastguard Worker {
4915*cc02d7e2SAndroid Build Coastguard Worker /*
4916*cc02d7e2SAndroid Build Coastguard Worker * Digest on a local copy. This way, the state remains unaltered, and it can
4917*cc02d7e2SAndroid Build Coastguard Worker * continue ingesting more input afterwards.
4918*cc02d7e2SAndroid Build Coastguard Worker */
4919*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(acc, state->acc, sizeof(state->acc));
4920*cc02d7e2SAndroid Build Coastguard Worker if (state->bufferedSize >= XXH_STRIPE_LEN) {
4921*cc02d7e2SAndroid Build Coastguard Worker size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
4922*cc02d7e2SAndroid Build Coastguard Worker size_t nbStripesSoFar = state->nbStripesSoFar;
4923*cc02d7e2SAndroid Build Coastguard Worker XXH3_consumeStripes(acc,
4924*cc02d7e2SAndroid Build Coastguard Worker &nbStripesSoFar, state->nbStripesPerBlock,
4925*cc02d7e2SAndroid Build Coastguard Worker state->buffer, nbStripes,
4926*cc02d7e2SAndroid Build Coastguard Worker secret, state->secretLimit,
4927*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc);
4928*cc02d7e2SAndroid Build Coastguard Worker /* last stripe */
4929*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512(acc,
4930*cc02d7e2SAndroid Build Coastguard Worker state->buffer + state->bufferedSize - XXH_STRIPE_LEN,
4931*cc02d7e2SAndroid Build Coastguard Worker secret + state->secretLimit - XXH_SECRET_LASTACC_START);
4932*cc02d7e2SAndroid Build Coastguard Worker } else { /* bufferedSize < XXH_STRIPE_LEN */
4933*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 lastStripe[XXH_STRIPE_LEN];
4934*cc02d7e2SAndroid Build Coastguard Worker size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
4935*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */
4936*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
4937*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
4938*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512(acc,
4939*cc02d7e2SAndroid Build Coastguard Worker lastStripe,
4940*cc02d7e2SAndroid Build Coastguard Worker secret + state->secretLimit - XXH_SECRET_LASTACC_START);
4941*cc02d7e2SAndroid Build Coastguard Worker }
4942*cc02d7e2SAndroid Build Coastguard Worker }
4943*cc02d7e2SAndroid Build Coastguard Worker
4944*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_64bits_digest(const XXH3_state_t * state)4945*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
4946*cc02d7e2SAndroid Build Coastguard Worker {
4947*cc02d7e2SAndroid Build Coastguard Worker const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
4948*cc02d7e2SAndroid Build Coastguard Worker if (state->totalLen > XXH3_MIDSIZE_MAX) {
4949*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
4950*cc02d7e2SAndroid Build Coastguard Worker XXH3_digest_long(acc, state, secret);
4951*cc02d7e2SAndroid Build Coastguard Worker return XXH3_mergeAccs(acc,
4952*cc02d7e2SAndroid Build Coastguard Worker secret + XXH_SECRET_MERGEACCS_START,
4953*cc02d7e2SAndroid Build Coastguard Worker (xxh_u64)state->totalLen * XXH_PRIME64_1);
4954*cc02d7e2SAndroid Build Coastguard Worker }
4955*cc02d7e2SAndroid Build Coastguard Worker /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
4956*cc02d7e2SAndroid Build Coastguard Worker if (state->useSeed)
4957*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
4958*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
4959*cc02d7e2SAndroid Build Coastguard Worker secret, state->secretLimit + XXH_STRIPE_LEN);
4960*cc02d7e2SAndroid Build Coastguard Worker }
4961*cc02d7e2SAndroid Build Coastguard Worker
4962*cc02d7e2SAndroid Build Coastguard Worker
4963*cc02d7e2SAndroid Build Coastguard Worker
4964*cc02d7e2SAndroid Build Coastguard Worker /* ==========================================
4965*cc02d7e2SAndroid Build Coastguard Worker * XXH3 128 bits (a.k.a XXH128)
4966*cc02d7e2SAndroid Build Coastguard Worker * ==========================================
4967*cc02d7e2SAndroid Build Coastguard Worker * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
4968*cc02d7e2SAndroid Build Coastguard Worker * even without counting the significantly larger output size.
4969*cc02d7e2SAndroid Build Coastguard Worker *
4970*cc02d7e2SAndroid Build Coastguard Worker * For example, extra steps are taken to avoid the seed-dependent collisions
4971*cc02d7e2SAndroid Build Coastguard Worker * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
4972*cc02d7e2SAndroid Build Coastguard Worker *
4973*cc02d7e2SAndroid Build Coastguard Worker * This strength naturally comes at the cost of some speed, especially on short
4974*cc02d7e2SAndroid Build Coastguard Worker * lengths. Note that longer hashes are about as fast as the 64-bit version
4975*cc02d7e2SAndroid Build Coastguard Worker * due to it using only a slight modification of the 64-bit loop.
4976*cc02d7e2SAndroid Build Coastguard Worker *
4977*cc02d7e2SAndroid Build Coastguard Worker * XXH128 is also more oriented towards 64-bit machines. It is still extremely
4978*cc02d7e2SAndroid Build Coastguard Worker * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
4979*cc02d7e2SAndroid Build Coastguard Worker */
4980*cc02d7e2SAndroid Build Coastguard Worker
4981*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_len_1to3_128b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)4982*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
4983*cc02d7e2SAndroid Build Coastguard Worker {
4984*cc02d7e2SAndroid Build Coastguard Worker /* A doubled version of 1to3_64b with different constants. */
4985*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
4986*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(1 <= len && len <= 3);
4987*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
4988*cc02d7e2SAndroid Build Coastguard Worker /*
4989*cc02d7e2SAndroid Build Coastguard Worker * len = 1: combinedl = { input[0], 0x01, input[0], input[0] }
4990*cc02d7e2SAndroid Build Coastguard Worker * len = 2: combinedl = { input[1], 0x02, input[0], input[1] }
4991*cc02d7e2SAndroid Build Coastguard Worker * len = 3: combinedl = { input[2], 0x03, input[0], input[1] }
4992*cc02d7e2SAndroid Build Coastguard Worker */
4993*cc02d7e2SAndroid Build Coastguard Worker { xxh_u8 const c1 = input[0];
4994*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 const c2 = input[len >> 1];
4995*cc02d7e2SAndroid Build Coastguard Worker xxh_u8 const c3 = input[len - 1];
4996*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24)
4997*cc02d7e2SAndroid Build Coastguard Worker | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
4998*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13);
4999*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
5000*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed;
5001*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl;
5002*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph;
5003*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t h128;
5004*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH64_avalanche(keyed_lo);
5005*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = XXH64_avalanche(keyed_hi);
5006*cc02d7e2SAndroid Build Coastguard Worker return h128;
5007*cc02d7e2SAndroid Build Coastguard Worker }
5008*cc02d7e2SAndroid Build Coastguard Worker }
5009*cc02d7e2SAndroid Build Coastguard Worker
5010*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_len_4to8_128b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)5011*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5012*cc02d7e2SAndroid Build Coastguard Worker {
5013*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
5014*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
5015*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(4 <= len && len <= 8);
5016*cc02d7e2SAndroid Build Coastguard Worker seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
5017*cc02d7e2SAndroid Build Coastguard Worker { xxh_u32 const input_lo = XXH_readLE32(input);
5018*cc02d7e2SAndroid Build Coastguard Worker xxh_u32 const input_hi = XXH_readLE32(input + len - 4);
5019*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32);
5020*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed;
5021*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const keyed = input_64 ^ bitflip;
5022*cc02d7e2SAndroid Build Coastguard Worker
5023*cc02d7e2SAndroid Build Coastguard Worker /* Shift len to the left to ensure it is even, this avoids even multiplies. */
5024*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2));
5025*cc02d7e2SAndroid Build Coastguard Worker
5026*cc02d7e2SAndroid Build Coastguard Worker m128.high64 += (m128.low64 << 1);
5027*cc02d7e2SAndroid Build Coastguard Worker m128.low64 ^= (m128.high64 >> 3);
5028*cc02d7e2SAndroid Build Coastguard Worker
5029*cc02d7e2SAndroid Build Coastguard Worker m128.low64 = XXH_xorshift64(m128.low64, 35);
5030*cc02d7e2SAndroid Build Coastguard Worker m128.low64 *= 0x9FB21C651E98DF25ULL;
5031*cc02d7e2SAndroid Build Coastguard Worker m128.low64 = XXH_xorshift64(m128.low64, 28);
5032*cc02d7e2SAndroid Build Coastguard Worker m128.high64 = XXH3_avalanche(m128.high64);
5033*cc02d7e2SAndroid Build Coastguard Worker return m128;
5034*cc02d7e2SAndroid Build Coastguard Worker }
5035*cc02d7e2SAndroid Build Coastguard Worker }
5036*cc02d7e2SAndroid Build Coastguard Worker
5037*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_len_9to16_128b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)5038*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5039*cc02d7e2SAndroid Build Coastguard Worker {
5040*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(input != NULL);
5041*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secret != NULL);
5042*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(9 <= len && len <= 16);
5043*cc02d7e2SAndroid Build Coastguard Worker { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed;
5044*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed;
5045*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const input_lo = XXH_readLE64(input);
5046*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 input_hi = XXH_readLE64(input + len - 8);
5047*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1);
5048*cc02d7e2SAndroid Build Coastguard Worker /*
5049*cc02d7e2SAndroid Build Coastguard Worker * Put len in the middle of m128 to ensure that the length gets mixed to
5050*cc02d7e2SAndroid Build Coastguard Worker * both the low and high bits in the 128x64 multiply below.
5051*cc02d7e2SAndroid Build Coastguard Worker */
5052*cc02d7e2SAndroid Build Coastguard Worker m128.low64 += (xxh_u64)(len - 1) << 54;
5053*cc02d7e2SAndroid Build Coastguard Worker input_hi ^= bitfliph;
5054*cc02d7e2SAndroid Build Coastguard Worker /*
5055*cc02d7e2SAndroid Build Coastguard Worker * Add the high 32 bits of input_hi to the high 32 bits of m128, then
5056*cc02d7e2SAndroid Build Coastguard Worker * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to
5057*cc02d7e2SAndroid Build Coastguard Worker * the high 64 bits of m128.
5058*cc02d7e2SAndroid Build Coastguard Worker *
5059*cc02d7e2SAndroid Build Coastguard Worker * The best approach to this operation is different on 32-bit and 64-bit.
5060*cc02d7e2SAndroid Build Coastguard Worker */
5061*cc02d7e2SAndroid Build Coastguard Worker if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */
5062*cc02d7e2SAndroid Build Coastguard Worker /*
5063*cc02d7e2SAndroid Build Coastguard Worker * 32-bit optimized version, which is more readable.
5064*cc02d7e2SAndroid Build Coastguard Worker *
5065*cc02d7e2SAndroid Build Coastguard Worker * On 32-bit, it removes an ADC and delays a dependency between the two
5066*cc02d7e2SAndroid Build Coastguard Worker * halves of m128.high64, but it generates an extra mask on 64-bit.
5067*cc02d7e2SAndroid Build Coastguard Worker */
5068*cc02d7e2SAndroid Build Coastguard Worker m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2);
5069*cc02d7e2SAndroid Build Coastguard Worker } else {
5070*cc02d7e2SAndroid Build Coastguard Worker /*
5071*cc02d7e2SAndroid Build Coastguard Worker * 64-bit optimized (albeit more confusing) version.
5072*cc02d7e2SAndroid Build Coastguard Worker *
5073*cc02d7e2SAndroid Build Coastguard Worker * Uses some properties of addition and multiplication to remove the mask:
5074*cc02d7e2SAndroid Build Coastguard Worker *
5075*cc02d7e2SAndroid Build Coastguard Worker * Let:
5076*cc02d7e2SAndroid Build Coastguard Worker * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
5077*cc02d7e2SAndroid Build Coastguard Worker * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
5078*cc02d7e2SAndroid Build Coastguard Worker * c = XXH_PRIME32_2
5079*cc02d7e2SAndroid Build Coastguard Worker *
5080*cc02d7e2SAndroid Build Coastguard Worker * a + (b * c)
5081*cc02d7e2SAndroid Build Coastguard Worker * Inverse Property: x + y - x == y
5082*cc02d7e2SAndroid Build Coastguard Worker * a + (b * (1 + c - 1))
5083*cc02d7e2SAndroid Build Coastguard Worker * Distributive Property: x * (y + z) == (x * y) + (x * z)
5084*cc02d7e2SAndroid Build Coastguard Worker * a + (b * 1) + (b * (c - 1))
5085*cc02d7e2SAndroid Build Coastguard Worker * Identity Property: x * 1 == x
5086*cc02d7e2SAndroid Build Coastguard Worker * a + b + (b * (c - 1))
5087*cc02d7e2SAndroid Build Coastguard Worker *
5088*cc02d7e2SAndroid Build Coastguard Worker * Substitute a, b, and c:
5089*cc02d7e2SAndroid Build Coastguard Worker * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
5090*cc02d7e2SAndroid Build Coastguard Worker *
5091*cc02d7e2SAndroid Build Coastguard Worker * Since input_hi.hi + input_hi.lo == input_hi, we get this:
5092*cc02d7e2SAndroid Build Coastguard Worker * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
5093*cc02d7e2SAndroid Build Coastguard Worker */
5094*cc02d7e2SAndroid Build Coastguard Worker m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1);
5095*cc02d7e2SAndroid Build Coastguard Worker }
5096*cc02d7e2SAndroid Build Coastguard Worker /* m128 ^= XXH_swap64(m128 >> 64); */
5097*cc02d7e2SAndroid Build Coastguard Worker m128.low64 ^= XXH_swap64(m128.high64);
5098*cc02d7e2SAndroid Build Coastguard Worker
5099*cc02d7e2SAndroid Build Coastguard Worker { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
5100*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2);
5101*cc02d7e2SAndroid Build Coastguard Worker h128.high64 += m128.high64 * XXH_PRIME64_2;
5102*cc02d7e2SAndroid Build Coastguard Worker
5103*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH3_avalanche(h128.low64);
5104*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = XXH3_avalanche(h128.high64);
5105*cc02d7e2SAndroid Build Coastguard Worker return h128;
5106*cc02d7e2SAndroid Build Coastguard Worker } }
5107*cc02d7e2SAndroid Build Coastguard Worker }
5108*cc02d7e2SAndroid Build Coastguard Worker
5109*cc02d7e2SAndroid Build Coastguard Worker /*
5110*cc02d7e2SAndroid Build Coastguard Worker * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
5111*cc02d7e2SAndroid Build Coastguard Worker */
5112*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_len_0to16_128b(const xxh_u8 * input,size_t len,const xxh_u8 * secret,XXH64_hash_t seed)5113*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5114*cc02d7e2SAndroid Build Coastguard Worker {
5115*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(len <= 16);
5116*cc02d7e2SAndroid Build Coastguard Worker { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed);
5117*cc02d7e2SAndroid Build Coastguard Worker if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed);
5118*cc02d7e2SAndroid Build Coastguard Worker if (len) return XXH3_len_1to3_128b(input, len, secret, seed);
5119*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t h128;
5120*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72);
5121*cc02d7e2SAndroid Build Coastguard Worker xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88);
5122*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH64_avalanche(seed ^ bitflipl);
5123*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = XXH64_avalanche( seed ^ bitfliph);
5124*cc02d7e2SAndroid Build Coastguard Worker return h128;
5125*cc02d7e2SAndroid Build Coastguard Worker } }
5126*cc02d7e2SAndroid Build Coastguard Worker }
5127*cc02d7e2SAndroid Build Coastguard Worker
5128*cc02d7e2SAndroid Build Coastguard Worker /*
5129*cc02d7e2SAndroid Build Coastguard Worker * A bit slower than XXH3_mix16B, but handles multiply by zero better.
5130*cc02d7e2SAndroid Build Coastguard Worker */
5131*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH128_mix32B(XXH128_hash_t acc,const xxh_u8 * input_1,const xxh_u8 * input_2,const xxh_u8 * secret,XXH64_hash_t seed)5132*cc02d7e2SAndroid Build Coastguard Worker XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
5133*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* secret, XXH64_hash_t seed)
5134*cc02d7e2SAndroid Build Coastguard Worker {
5135*cc02d7e2SAndroid Build Coastguard Worker acc.low64 += XXH3_mix16B (input_1, secret+0, seed);
5136*cc02d7e2SAndroid Build Coastguard Worker acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8);
5137*cc02d7e2SAndroid Build Coastguard Worker acc.high64 += XXH3_mix16B (input_2, secret+16, seed);
5138*cc02d7e2SAndroid Build Coastguard Worker acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8);
5139*cc02d7e2SAndroid Build Coastguard Worker return acc;
5140*cc02d7e2SAndroid Build Coastguard Worker }
5141*cc02d7e2SAndroid Build Coastguard Worker
5142*cc02d7e2SAndroid Build Coastguard Worker
5143*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_len_17to128_128b(const xxh_u8 * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH64_hash_t seed)5144*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5145*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5146*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed)
5147*cc02d7e2SAndroid Build Coastguard Worker {
5148*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
5149*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(16 < len && len <= 128);
5150*cc02d7e2SAndroid Build Coastguard Worker
5151*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t acc;
5152*cc02d7e2SAndroid Build Coastguard Worker acc.low64 = len * XXH_PRIME64_1;
5153*cc02d7e2SAndroid Build Coastguard Worker acc.high64 = 0;
5154*cc02d7e2SAndroid Build Coastguard Worker if (len > 32) {
5155*cc02d7e2SAndroid Build Coastguard Worker if (len > 64) {
5156*cc02d7e2SAndroid Build Coastguard Worker if (len > 96) {
5157*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed);
5158*cc02d7e2SAndroid Build Coastguard Worker }
5159*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed);
5160*cc02d7e2SAndroid Build Coastguard Worker }
5161*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed);
5162*cc02d7e2SAndroid Build Coastguard Worker }
5163*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc, input, input+len-16, secret, seed);
5164*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t h128;
5165*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = acc.low64 + acc.high64;
5166*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = (acc.low64 * XXH_PRIME64_1)
5167*cc02d7e2SAndroid Build Coastguard Worker + (acc.high64 * XXH_PRIME64_4)
5168*cc02d7e2SAndroid Build Coastguard Worker + ((len - seed) * XXH_PRIME64_2);
5169*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH3_avalanche(h128.low64);
5170*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
5171*cc02d7e2SAndroid Build Coastguard Worker return h128;
5172*cc02d7e2SAndroid Build Coastguard Worker }
5173*cc02d7e2SAndroid Build Coastguard Worker }
5174*cc02d7e2SAndroid Build Coastguard Worker }
5175*cc02d7e2SAndroid Build Coastguard Worker
5176*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH128_hash_t
XXH3_len_129to240_128b(const xxh_u8 * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH64_hash_t seed)5177*cc02d7e2SAndroid Build Coastguard Worker XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5178*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5179*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed)
5180*cc02d7e2SAndroid Build Coastguard Worker {
5181*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
5182*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
5183*cc02d7e2SAndroid Build Coastguard Worker
5184*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t acc;
5185*cc02d7e2SAndroid Build Coastguard Worker int const nbRounds = (int)len / 32;
5186*cc02d7e2SAndroid Build Coastguard Worker int i;
5187*cc02d7e2SAndroid Build Coastguard Worker acc.low64 = len * XXH_PRIME64_1;
5188*cc02d7e2SAndroid Build Coastguard Worker acc.high64 = 0;
5189*cc02d7e2SAndroid Build Coastguard Worker for (i=0; i<4; i++) {
5190*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc,
5191*cc02d7e2SAndroid Build Coastguard Worker input + (32 * i),
5192*cc02d7e2SAndroid Build Coastguard Worker input + (32 * i) + 16,
5193*cc02d7e2SAndroid Build Coastguard Worker secret + (32 * i),
5194*cc02d7e2SAndroid Build Coastguard Worker seed);
5195*cc02d7e2SAndroid Build Coastguard Worker }
5196*cc02d7e2SAndroid Build Coastguard Worker acc.low64 = XXH3_avalanche(acc.low64);
5197*cc02d7e2SAndroid Build Coastguard Worker acc.high64 = XXH3_avalanche(acc.high64);
5198*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(nbRounds >= 4);
5199*cc02d7e2SAndroid Build Coastguard Worker for (i=4 ; i < nbRounds; i++) {
5200*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc,
5201*cc02d7e2SAndroid Build Coastguard Worker input + (32 * i),
5202*cc02d7e2SAndroid Build Coastguard Worker input + (32 * i) + 16,
5203*cc02d7e2SAndroid Build Coastguard Worker secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)),
5204*cc02d7e2SAndroid Build Coastguard Worker seed);
5205*cc02d7e2SAndroid Build Coastguard Worker }
5206*cc02d7e2SAndroid Build Coastguard Worker /* last bytes */
5207*cc02d7e2SAndroid Build Coastguard Worker acc = XXH128_mix32B(acc,
5208*cc02d7e2SAndroid Build Coastguard Worker input + len - 16,
5209*cc02d7e2SAndroid Build Coastguard Worker input + len - 32,
5210*cc02d7e2SAndroid Build Coastguard Worker secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16,
5211*cc02d7e2SAndroid Build Coastguard Worker 0ULL - seed);
5212*cc02d7e2SAndroid Build Coastguard Worker
5213*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t h128;
5214*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = acc.low64 + acc.high64;
5215*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = (acc.low64 * XXH_PRIME64_1)
5216*cc02d7e2SAndroid Build Coastguard Worker + (acc.high64 * XXH_PRIME64_4)
5217*cc02d7e2SAndroid Build Coastguard Worker + ((len - seed) * XXH_PRIME64_2);
5218*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH3_avalanche(h128.low64);
5219*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
5220*cc02d7e2SAndroid Build Coastguard Worker return h128;
5221*cc02d7e2SAndroid Build Coastguard Worker }
5222*cc02d7e2SAndroid Build Coastguard Worker }
5223*cc02d7e2SAndroid Build Coastguard Worker }
5224*cc02d7e2SAndroid Build Coastguard Worker
5225*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_hashLong_128b_internal(const void * XXH_RESTRICT input,size_t len,const xxh_u8 * XXH_RESTRICT secret,size_t secretSize,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble)5226*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
5227*cc02d7e2SAndroid Build Coastguard Worker const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5228*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
5229*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble)
5230*cc02d7e2SAndroid Build Coastguard Worker {
5231*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
5232*cc02d7e2SAndroid Build Coastguard Worker
5233*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble);
5234*cc02d7e2SAndroid Build Coastguard Worker
5235*cc02d7e2SAndroid Build Coastguard Worker /* converge into final hash */
5236*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(sizeof(acc) == 64);
5237*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
5238*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t h128;
5239*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH3_mergeAccs(acc,
5240*cc02d7e2SAndroid Build Coastguard Worker secret + XXH_SECRET_MERGEACCS_START,
5241*cc02d7e2SAndroid Build Coastguard Worker (xxh_u64)len * XXH_PRIME64_1);
5242*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = XXH3_mergeAccs(acc,
5243*cc02d7e2SAndroid Build Coastguard Worker secret + secretSize
5244*cc02d7e2SAndroid Build Coastguard Worker - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
5245*cc02d7e2SAndroid Build Coastguard Worker ~((xxh_u64)len * XXH_PRIME64_2));
5246*cc02d7e2SAndroid Build Coastguard Worker return h128;
5247*cc02d7e2SAndroid Build Coastguard Worker }
5248*cc02d7e2SAndroid Build Coastguard Worker }
5249*cc02d7e2SAndroid Build Coastguard Worker
5250*cc02d7e2SAndroid Build Coastguard Worker /*
5251*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance that XXH3_hashLong is not inlined.
5252*cc02d7e2SAndroid Build Coastguard Worker */
5253*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH128_hash_t
XXH3_hashLong_128b_default(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,const void * XXH_RESTRICT secret,size_t secretLen)5254*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
5255*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64,
5256*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret, size_t secretLen)
5257*cc02d7e2SAndroid Build Coastguard Worker {
5258*cc02d7e2SAndroid Build Coastguard Worker (void)seed64; (void)secret; (void)secretLen;
5259*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret),
5260*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc);
5261*cc02d7e2SAndroid Build Coastguard Worker }
5262*cc02d7e2SAndroid Build Coastguard Worker
5263*cc02d7e2SAndroid Build Coastguard Worker /*
5264*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance to pass @secretLen (when it's static)
5265*cc02d7e2SAndroid Build Coastguard Worker * to the compiler, so that it can properly optimize the vectorized loop.
5266*cc02d7e2SAndroid Build Coastguard Worker */
5267*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_hashLong_128b_withSecret(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,const void * XXH_RESTRICT secret,size_t secretLen)5268*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len,
5269*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64,
5270*cc02d7e2SAndroid Build Coastguard Worker const void* XXH_RESTRICT secret, size_t secretLen)
5271*cc02d7e2SAndroid Build Coastguard Worker {
5272*cc02d7e2SAndroid Build Coastguard Worker (void)seed64;
5273*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen,
5274*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc);
5275*cc02d7e2SAndroid Build Coastguard Worker }
5276*cc02d7e2SAndroid Build Coastguard Worker
5277*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_hashLong_128b_withSeed_internal(const void * XXH_RESTRICT input,size_t len,XXH64_hash_t seed64,XXH3_f_accumulate_512 f_acc512,XXH3_f_scrambleAcc f_scramble,XXH3_f_initCustomSecret f_initSec)5278*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len,
5279*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64,
5280*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_accumulate_512 f_acc512,
5281*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_scrambleAcc f_scramble,
5282*cc02d7e2SAndroid Build Coastguard Worker XXH3_f_initCustomSecret f_initSec)
5283*cc02d7e2SAndroid Build Coastguard Worker {
5284*cc02d7e2SAndroid Build Coastguard Worker if (seed64 == 0)
5285*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_internal(input, len,
5286*cc02d7e2SAndroid Build Coastguard Worker XXH3_kSecret, sizeof(XXH3_kSecret),
5287*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
5288*cc02d7e2SAndroid Build Coastguard Worker { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
5289*cc02d7e2SAndroid Build Coastguard Worker f_initSec(secret, seed64);
5290*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret),
5291*cc02d7e2SAndroid Build Coastguard Worker f_acc512, f_scramble);
5292*cc02d7e2SAndroid Build Coastguard Worker }
5293*cc02d7e2SAndroid Build Coastguard Worker }
5294*cc02d7e2SAndroid Build Coastguard Worker
5295*cc02d7e2SAndroid Build Coastguard Worker /*
5296*cc02d7e2SAndroid Build Coastguard Worker * It's important for performance that XXH3_hashLong is not inlined.
5297*cc02d7e2SAndroid Build Coastguard Worker */
5298*cc02d7e2SAndroid Build Coastguard Worker XXH_NO_INLINE XXH128_hash_t
XXH3_hashLong_128b_withSeed(const void * input,size_t len,XXH64_hash_t seed64,const void * XXH_RESTRICT secret,size_t secretLen)5299*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_withSeed(const void* input, size_t len,
5300*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen)
5301*cc02d7e2SAndroid Build Coastguard Worker {
5302*cc02d7e2SAndroid Build Coastguard Worker (void)secret; (void)secretLen;
5303*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_withSeed_internal(input, len, seed64,
5304*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
5305*cc02d7e2SAndroid Build Coastguard Worker }
5306*cc02d7e2SAndroid Build Coastguard Worker
5307*cc02d7e2SAndroid Build Coastguard Worker typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t,
5308*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t, const void* XXH_RESTRICT, size_t);
5309*cc02d7e2SAndroid Build Coastguard Worker
5310*cc02d7e2SAndroid Build Coastguard Worker XXH_FORCE_INLINE XXH128_hash_t
XXH3_128bits_internal(const void * input,size_t len,XXH64_hash_t seed64,const void * XXH_RESTRICT secret,size_t secretLen,XXH3_hashLong128_f f_hl128)5311*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_internal(const void* input, size_t len,
5312*cc02d7e2SAndroid Build Coastguard Worker XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
5313*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong128_f f_hl128)
5314*cc02d7e2SAndroid Build Coastguard Worker {
5315*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
5316*cc02d7e2SAndroid Build Coastguard Worker /*
5317*cc02d7e2SAndroid Build Coastguard Worker * If an action is to be taken if `secret` conditions are not respected,
5318*cc02d7e2SAndroid Build Coastguard Worker * it should be done here.
5319*cc02d7e2SAndroid Build Coastguard Worker * For now, it's a contract pre-condition.
5320*cc02d7e2SAndroid Build Coastguard Worker * Adding a check and a branch here would cost performance at every hash.
5321*cc02d7e2SAndroid Build Coastguard Worker */
5322*cc02d7e2SAndroid Build Coastguard Worker if (len <= 16)
5323*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
5324*cc02d7e2SAndroid Build Coastguard Worker if (len <= 128)
5325*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
5326*cc02d7e2SAndroid Build Coastguard Worker if (len <= XXH3_MIDSIZE_MAX)
5327*cc02d7e2SAndroid Build Coastguard Worker return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
5328*cc02d7e2SAndroid Build Coastguard Worker return f_hl128(input, len, seed64, secret, secretLen);
5329*cc02d7e2SAndroid Build Coastguard Worker }
5330*cc02d7e2SAndroid Build Coastguard Worker
5331*cc02d7e2SAndroid Build Coastguard Worker
5332*cc02d7e2SAndroid Build Coastguard Worker /* === Public XXH128 API === */
5333*cc02d7e2SAndroid Build Coastguard Worker
5334*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_128bits(const void * input,size_t len)5335*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
5336*cc02d7e2SAndroid Build Coastguard Worker {
5337*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_internal(input, len, 0,
5338*cc02d7e2SAndroid Build Coastguard Worker XXH3_kSecret, sizeof(XXH3_kSecret),
5339*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_default);
5340*cc02d7e2SAndroid Build Coastguard Worker }
5341*cc02d7e2SAndroid Build Coastguard Worker
5342*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5343*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
XXH3_128bits_withSecret(const void * input,size_t len,const void * secret,size_t secretSize)5344*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
5345*cc02d7e2SAndroid Build Coastguard Worker {
5346*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_internal(input, len, 0,
5347*cc02d7e2SAndroid Build Coastguard Worker (const xxh_u8*)secret, secretSize,
5348*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_withSecret);
5349*cc02d7e2SAndroid Build Coastguard Worker }
5350*cc02d7e2SAndroid Build Coastguard Worker
5351*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5352*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
XXH3_128bits_withSeed(const void * input,size_t len,XXH64_hash_t seed)5353*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5354*cc02d7e2SAndroid Build Coastguard Worker {
5355*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_internal(input, len, seed,
5356*cc02d7e2SAndroid Build Coastguard Worker XXH3_kSecret, sizeof(XXH3_kSecret),
5357*cc02d7e2SAndroid Build Coastguard Worker XXH3_hashLong_128b_withSeed);
5358*cc02d7e2SAndroid Build Coastguard Worker }
5359*cc02d7e2SAndroid Build Coastguard Worker
5360*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5361*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
XXH3_128bits_withSecretandSeed(const void * input,size_t len,const void * secret,size_t secretSize,XXH64_hash_t seed)5362*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
5363*cc02d7e2SAndroid Build Coastguard Worker {
5364*cc02d7e2SAndroid Build Coastguard Worker if (len <= XXH3_MIDSIZE_MAX)
5365*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
5366*cc02d7e2SAndroid Build Coastguard Worker return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
5367*cc02d7e2SAndroid Build Coastguard Worker }
5368*cc02d7e2SAndroid Build Coastguard Worker
5369*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5370*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
XXH128(const void * input,size_t len,XXH64_hash_t seed)5371*cc02d7e2SAndroid Build Coastguard Worker XXH128(const void* input, size_t len, XXH64_hash_t seed)
5372*cc02d7e2SAndroid Build Coastguard Worker {
5373*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_withSeed(input, len, seed);
5374*cc02d7e2SAndroid Build Coastguard Worker }
5375*cc02d7e2SAndroid Build Coastguard Worker
5376*cc02d7e2SAndroid Build Coastguard Worker
5377*cc02d7e2SAndroid Build Coastguard Worker /* === XXH3 128-bit streaming === */
5378*cc02d7e2SAndroid Build Coastguard Worker
5379*cc02d7e2SAndroid Build Coastguard Worker /*
5380*cc02d7e2SAndroid Build Coastguard Worker * All initialization and update functions are identical to 64-bit streaming variant.
5381*cc02d7e2SAndroid Build Coastguard Worker * The only difference is the finalization routine.
5382*cc02d7e2SAndroid Build Coastguard Worker */
5383*cc02d7e2SAndroid Build Coastguard Worker
5384*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5385*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_128bits_reset(XXH3_state_t * statePtr)5386*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_reset(XXH3_state_t* statePtr)
5387*cc02d7e2SAndroid Build Coastguard Worker {
5388*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_reset(statePtr);
5389*cc02d7e2SAndroid Build Coastguard Worker }
5390*cc02d7e2SAndroid Build Coastguard Worker
5391*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5392*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_128bits_reset_withSecret(XXH3_state_t * statePtr,const void * secret,size_t secretSize)5393*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
5394*cc02d7e2SAndroid Build Coastguard Worker {
5395*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
5396*cc02d7e2SAndroid Build Coastguard Worker }
5397*cc02d7e2SAndroid Build Coastguard Worker
5398*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5399*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_128bits_reset_withSeed(XXH3_state_t * statePtr,XXH64_hash_t seed)5400*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
5401*cc02d7e2SAndroid Build Coastguard Worker {
5402*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_reset_withSeed(statePtr, seed);
5403*cc02d7e2SAndroid Build Coastguard Worker }
5404*cc02d7e2SAndroid Build Coastguard Worker
5405*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5406*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_128bits_reset_withSecretandSeed(XXH3_state_t * statePtr,const void * secret,size_t secretSize,XXH64_hash_t seed)5407*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
5408*cc02d7e2SAndroid Build Coastguard Worker {
5409*cc02d7e2SAndroid Build Coastguard Worker return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
5410*cc02d7e2SAndroid Build Coastguard Worker }
5411*cc02d7e2SAndroid Build Coastguard Worker
5412*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5413*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_128bits_update(XXH3_state_t * state,const void * input,size_t len)5414*cc02d7e2SAndroid Build Coastguard Worker XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
5415*cc02d7e2SAndroid Build Coastguard Worker {
5416*cc02d7e2SAndroid Build Coastguard Worker return XXH3_update(state, (const xxh_u8*)input, len,
5417*cc02d7e2SAndroid Build Coastguard Worker XXH3_accumulate_512, XXH3_scrambleAcc);
5418*cc02d7e2SAndroid Build Coastguard Worker }
5419*cc02d7e2SAndroid Build Coastguard Worker
5420*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH3_128bits_digest(const XXH3_state_t * state)5421*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
5422*cc02d7e2SAndroid Build Coastguard Worker {
5423*cc02d7e2SAndroid Build Coastguard Worker const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
5424*cc02d7e2SAndroid Build Coastguard Worker if (state->totalLen > XXH3_MIDSIZE_MAX) {
5425*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
5426*cc02d7e2SAndroid Build Coastguard Worker XXH3_digest_long(acc, state, secret);
5427*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
5428*cc02d7e2SAndroid Build Coastguard Worker { XXH128_hash_t h128;
5429*cc02d7e2SAndroid Build Coastguard Worker h128.low64 = XXH3_mergeAccs(acc,
5430*cc02d7e2SAndroid Build Coastguard Worker secret + XXH_SECRET_MERGEACCS_START,
5431*cc02d7e2SAndroid Build Coastguard Worker (xxh_u64)state->totalLen * XXH_PRIME64_1);
5432*cc02d7e2SAndroid Build Coastguard Worker h128.high64 = XXH3_mergeAccs(acc,
5433*cc02d7e2SAndroid Build Coastguard Worker secret + state->secretLimit + XXH_STRIPE_LEN
5434*cc02d7e2SAndroid Build Coastguard Worker - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
5435*cc02d7e2SAndroid Build Coastguard Worker ~((xxh_u64)state->totalLen * XXH_PRIME64_2));
5436*cc02d7e2SAndroid Build Coastguard Worker return h128;
5437*cc02d7e2SAndroid Build Coastguard Worker }
5438*cc02d7e2SAndroid Build Coastguard Worker }
5439*cc02d7e2SAndroid Build Coastguard Worker /* len <= XXH3_MIDSIZE_MAX : short code */
5440*cc02d7e2SAndroid Build Coastguard Worker if (state->seed)
5441*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
5442*cc02d7e2SAndroid Build Coastguard Worker return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
5443*cc02d7e2SAndroid Build Coastguard Worker secret, state->secretLimit + XXH_STRIPE_LEN);
5444*cc02d7e2SAndroid Build Coastguard Worker }
5445*cc02d7e2SAndroid Build Coastguard Worker
5446*cc02d7e2SAndroid Build Coastguard Worker /* 128-bit utility functions */
5447*cc02d7e2SAndroid Build Coastguard Worker
5448*cc02d7e2SAndroid Build Coastguard Worker #include <string.h> /* memcmp, memcpy */
5449*cc02d7e2SAndroid Build Coastguard Worker
5450*cc02d7e2SAndroid Build Coastguard Worker /* return : 1 is equal, 0 if different */
5451*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH128_isEqual(XXH128_hash_t h1,XXH128_hash_t h2)5452*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
5453*cc02d7e2SAndroid Build Coastguard Worker {
5454*cc02d7e2SAndroid Build Coastguard Worker /* note : XXH128_hash_t is compact, it has no padding byte */
5455*cc02d7e2SAndroid Build Coastguard Worker return !(memcmp(&h1, &h2, sizeof(h1)));
5456*cc02d7e2SAndroid Build Coastguard Worker }
5457*cc02d7e2SAndroid Build Coastguard Worker
5458*cc02d7e2SAndroid Build Coastguard Worker /* This prototype is compatible with stdlib's qsort().
5459*cc02d7e2SAndroid Build Coastguard Worker * return : >0 if *h128_1 > *h128_2
5460*cc02d7e2SAndroid Build Coastguard Worker * <0 if *h128_1 < *h128_2
5461*cc02d7e2SAndroid Build Coastguard Worker * =0 if *h128_1 == *h128_2 */
5462*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
XXH128_cmp(const void * h128_1,const void * h128_2)5463*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
5464*cc02d7e2SAndroid Build Coastguard Worker {
5465*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
5466*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2;
5467*cc02d7e2SAndroid Build Coastguard Worker int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64);
5468*cc02d7e2SAndroid Build Coastguard Worker /* note : bets that, in most cases, hash values are different */
5469*cc02d7e2SAndroid Build Coastguard Worker if (hcmp) return hcmp;
5470*cc02d7e2SAndroid Build Coastguard Worker return (h1.low64 > h2.low64) - (h2.low64 > h1.low64);
5471*cc02d7e2SAndroid Build Coastguard Worker }
5472*cc02d7e2SAndroid Build Coastguard Worker
5473*cc02d7e2SAndroid Build Coastguard Worker
5474*cc02d7e2SAndroid Build Coastguard Worker /*====== Canonical representation ======*/
5475*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5476*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void
XXH128_canonicalFromHash(XXH128_canonical_t * dst,XXH128_hash_t hash)5477*cc02d7e2SAndroid Build Coastguard Worker XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
5478*cc02d7e2SAndroid Build Coastguard Worker {
5479*cc02d7e2SAndroid Build Coastguard Worker XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t));
5480*cc02d7e2SAndroid Build Coastguard Worker if (XXH_CPU_LITTLE_ENDIAN) {
5481*cc02d7e2SAndroid Build Coastguard Worker hash.high64 = XXH_swap64(hash.high64);
5482*cc02d7e2SAndroid Build Coastguard Worker hash.low64 = XXH_swap64(hash.low64);
5483*cc02d7e2SAndroid Build Coastguard Worker }
5484*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy(dst, &hash.high64, sizeof(hash.high64));
5485*cc02d7e2SAndroid Build Coastguard Worker XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
5486*cc02d7e2SAndroid Build Coastguard Worker }
5487*cc02d7e2SAndroid Build Coastguard Worker
5488*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5489*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH128_hash_t
XXH128_hashFromCanonical(const XXH128_canonical_t * src)5490*cc02d7e2SAndroid Build Coastguard Worker XXH128_hashFromCanonical(const XXH128_canonical_t* src)
5491*cc02d7e2SAndroid Build Coastguard Worker {
5492*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t h;
5493*cc02d7e2SAndroid Build Coastguard Worker h.high64 = XXH_readBE64(src);
5494*cc02d7e2SAndroid Build Coastguard Worker h.low64 = XXH_readBE64(src->digest + 8);
5495*cc02d7e2SAndroid Build Coastguard Worker return h;
5496*cc02d7e2SAndroid Build Coastguard Worker }
5497*cc02d7e2SAndroid Build Coastguard Worker
5498*cc02d7e2SAndroid Build Coastguard Worker
5499*cc02d7e2SAndroid Build Coastguard Worker
5500*cc02d7e2SAndroid Build Coastguard Worker /* ==========================================
5501*cc02d7e2SAndroid Build Coastguard Worker * Secret generators
5502*cc02d7e2SAndroid Build Coastguard Worker * ==========================================
5503*cc02d7e2SAndroid Build Coastguard Worker */
5504*cc02d7e2SAndroid Build Coastguard Worker #define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
5505*cc02d7e2SAndroid Build Coastguard Worker
XXH3_combine16(void * dst,XXH128_hash_t h128)5506*cc02d7e2SAndroid Build Coastguard Worker static void XXH3_combine16(void* dst, XXH128_hash_t h128)
5507*cc02d7e2SAndroid Build Coastguard Worker {
5508*cc02d7e2SAndroid Build Coastguard Worker XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 );
5509*cc02d7e2SAndroid Build Coastguard Worker XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
5510*cc02d7e2SAndroid Build Coastguard Worker }
5511*cc02d7e2SAndroid Build Coastguard Worker
5512*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5513*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API XXH_errorcode
XXH3_generateSecret(void * secretBuffer,size_t secretSize,const void * customSeed,size_t customSeedSize)5514*cc02d7e2SAndroid Build Coastguard Worker XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
5515*cc02d7e2SAndroid Build Coastguard Worker {
5516*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretBuffer != NULL);
5517*cc02d7e2SAndroid Build Coastguard Worker if (secretBuffer == NULL) return XXH_ERROR;
5518*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
5519*cc02d7e2SAndroid Build Coastguard Worker if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
5520*cc02d7e2SAndroid Build Coastguard Worker if (customSeedSize == 0) {
5521*cc02d7e2SAndroid Build Coastguard Worker customSeed = XXH3_kSecret;
5522*cc02d7e2SAndroid Build Coastguard Worker customSeedSize = XXH_SECRET_DEFAULT_SIZE;
5523*cc02d7e2SAndroid Build Coastguard Worker }
5524*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(customSeed != NULL);
5525*cc02d7e2SAndroid Build Coastguard Worker if (customSeed == NULL) return XXH_ERROR;
5526*cc02d7e2SAndroid Build Coastguard Worker
5527*cc02d7e2SAndroid Build Coastguard Worker /* Fill secretBuffer with a copy of customSeed - repeat as needed */
5528*cc02d7e2SAndroid Build Coastguard Worker { size_t pos = 0;
5529*cc02d7e2SAndroid Build Coastguard Worker while (pos < secretSize) {
5530*cc02d7e2SAndroid Build Coastguard Worker size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
5531*cc02d7e2SAndroid Build Coastguard Worker memcpy((char*)secretBuffer + pos, customSeed, toCopy);
5532*cc02d7e2SAndroid Build Coastguard Worker pos += toCopy;
5533*cc02d7e2SAndroid Build Coastguard Worker } }
5534*cc02d7e2SAndroid Build Coastguard Worker
5535*cc02d7e2SAndroid Build Coastguard Worker { size_t const nbSeg16 = secretSize / 16;
5536*cc02d7e2SAndroid Build Coastguard Worker size_t n;
5537*cc02d7e2SAndroid Build Coastguard Worker XXH128_canonical_t scrambler;
5538*cc02d7e2SAndroid Build Coastguard Worker XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
5539*cc02d7e2SAndroid Build Coastguard Worker for (n=0; n<nbSeg16; n++) {
5540*cc02d7e2SAndroid Build Coastguard Worker XXH128_hash_t const h128 = XXH128(&scrambler, sizeof(scrambler), n);
5541*cc02d7e2SAndroid Build Coastguard Worker XXH3_combine16((char*)secretBuffer + n*16, h128);
5542*cc02d7e2SAndroid Build Coastguard Worker }
5543*cc02d7e2SAndroid Build Coastguard Worker /* last segment */
5544*cc02d7e2SAndroid Build Coastguard Worker XXH3_combine16((char*)secretBuffer + secretSize - 16, XXH128_hashFromCanonical(&scrambler));
5545*cc02d7e2SAndroid Build Coastguard Worker }
5546*cc02d7e2SAndroid Build Coastguard Worker return XXH_OK;
5547*cc02d7e2SAndroid Build Coastguard Worker }
5548*cc02d7e2SAndroid Build Coastguard Worker
5549*cc02d7e2SAndroid Build Coastguard Worker /*! @ingroup xxh3_family */
5550*cc02d7e2SAndroid Build Coastguard Worker XXH_PUBLIC_API void
XXH3_generateSecret_fromSeed(void * secretBuffer,XXH64_hash_t seed)5551*cc02d7e2SAndroid Build Coastguard Worker XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
5552*cc02d7e2SAndroid Build Coastguard Worker {
5553*cc02d7e2SAndroid Build Coastguard Worker XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
5554*cc02d7e2SAndroid Build Coastguard Worker XXH3_initCustomSecret(secret, seed);
5555*cc02d7e2SAndroid Build Coastguard Worker XXH_ASSERT(secretBuffer != NULL);
5556*cc02d7e2SAndroid Build Coastguard Worker memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
5557*cc02d7e2SAndroid Build Coastguard Worker }
5558*cc02d7e2SAndroid Build Coastguard Worker
5559*cc02d7e2SAndroid Build Coastguard Worker
5560*cc02d7e2SAndroid Build Coastguard Worker
5561*cc02d7e2SAndroid Build Coastguard Worker /* Pop our optimization override from above */
5562*cc02d7e2SAndroid Build Coastguard Worker #if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
5563*cc02d7e2SAndroid Build Coastguard Worker && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
5564*cc02d7e2SAndroid Build Coastguard Worker && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
5565*cc02d7e2SAndroid Build Coastguard Worker # pragma GCC pop_options
5566*cc02d7e2SAndroid Build Coastguard Worker #endif
5567*cc02d7e2SAndroid Build Coastguard Worker
5568*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_NO_LONG_LONG */
5569*cc02d7e2SAndroid Build Coastguard Worker
5570*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_NO_XXH3 */
5571*cc02d7e2SAndroid Build Coastguard Worker
5572*cc02d7e2SAndroid Build Coastguard Worker /*!
5573*cc02d7e2SAndroid Build Coastguard Worker * @}
5574*cc02d7e2SAndroid Build Coastguard Worker */
5575*cc02d7e2SAndroid Build Coastguard Worker #endif /* XXH_IMPLEMENTATION */
5576*cc02d7e2SAndroid Build Coastguard Worker
5577*cc02d7e2SAndroid Build Coastguard Worker
5578*cc02d7e2SAndroid Build Coastguard Worker #if defined (__cplusplus)
5579*cc02d7e2SAndroid Build Coastguard Worker }
5580*cc02d7e2SAndroid Build Coastguard Worker #endif
5581