The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
xxhash.c
Go to the documentation of this file.
1 
52 #ifdef EXTRA_CHECKS
53 
54 //**************************************
55 // Tuning parameters
56 //**************************************
57 // Unaligned memory access is automatically enabled for "common" CPU, such as x86.
58 // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected.
59 // If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance.
60 // You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32).
61 #if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
62 #define XXH_USE_UNALIGNED_ACCESS 1
63 #endif
64 
65 // XXH_ACCEPT_NULL_INPUT_POINTER :
66 // If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
67 // When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
68 // This option has a very small performance cost (only measurable on small inputs).
69 // By default, this option is disabled. To enable it, uncomment below define :
70 // #define XXH_ACCEPT_NULL_INPUT_POINTER 1
71 
72 // XXH_FORCE_NATIVE_FORMAT :
73 // By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
74 // Results are therefore identical for little-endian and big-endian CPU.
75 // This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
76 // Should endian-independance be of no importance for your application, you may set the #define below to 1.
77 // It will improve speed for Big-endian CPU.
78 // This option has no impact on Little_Endian CPU.
79 #define XXH_FORCE_NATIVE_FORMAT 0
80 
81 //**************************************
82 // Compiler Specific Options
83 //**************************************
84 // Disable some Visual warning messages
85 #ifdef _MSC_VER // Visual Studio
86 #pragma warning(disable : 4127) // disable: C4127: conditional expression is constant
87 #endif
88 
89 #ifdef _MSC_VER // Visual Studio
90 #define FORCE_INLINE static __forceinline
91 #else
92 #ifdef __GNUC__
93 #define FORCE_INLINE static inline __attribute__((always_inline))
94 #else
95 #define FORCE_INLINE static inline
96 #endif
97 #endif
98 
99 //**************************************
100 // Includes & Memory related functions
101 //**************************************
102 #include "xxhash.h"
103 
104 //**************************************
105 // Basic Types
106 //**************************************
107 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99
108 #include <stdint.h>
109 typedef uint8_t BYTE;
110 typedef uint16_t U16;
111 typedef uint32_t U32;
112 typedef int32_t S32;
113 typedef uint64_t U64;
114 #else
115 typedef unsigned char BYTE;
116 typedef unsigned short U16;
117 typedef unsigned int U32;
118 typedef signed int S32;
119 typedef unsigned long long U64;
120 #endif
121 
122 #if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS)
123 #define _PACKED __attribute__ ((packed))
124 #else
125 #define _PACKED
126 #endif
127 
128 #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
129 #ifdef __IBMC__
130 #pragma pack(1)
131 #else
132 #pragma pack(push, 1)
133 #endif
134 #endif
135 
136 typedef struct _U32_S {
137  U32 v;
138 } _PACKED U32_S;
139 typedef struct _U64_S {
140  U64 v;
141 } _PACKED U64_S;
142 
143 #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)
144 #pragma pack(pop)
145 #endif
146 
147 #define A32(x) (((U32_S *)(x))->v)
148 #define A64(x) (((U64_S *)(x))->v)
149 
150 //***************************************
151 // Compiler-specific Functions and Macros
152 //***************************************
153 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
154 
155 // Note : although _rotl exists for minGW (GCC under windows), performance seems poor
156 #if defined(_MSC_VER)
157 #define XXH_rotl32(x,r) _rotl(x,r)
158 #define XXH_rotl64(x,r) _rotl64(x,r)
159 #else
160 #define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
161 #define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
162 #endif
163 
164 #if defined(_MSC_VER) // Visual Studio
165 #define XXH_swap32 _byteswap_ulong
166 #define XXH_swap64 _byteswap_uint64
167 #elif GCC_VERSION >= 403
168 #define XXH_swap32 __builtin_bswap32
169 #define XXH_swap64 __builtin_bswap64
170 #else
171 static inline U32 XXH_swap32(U32 x)
172 {
173  return ((x << 24) & 0xff000000) |
174  ((x << 8) & 0x00ff0000) |
175  ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff);
176 }
177 
178 static inline U64 XXH_swap64(U64 x)
179 {
180  return ((x << 56) & 0xff00000000000000ULL) |
181  ((x << 40) & 0x00ff000000000000ULL) |
182  ((x << 24) & 0x0000ff0000000000ULL) |
183  ((x << 8) & 0x000000ff00000000ULL) |
184  ((x >> 8) & 0x00000000ff000000ULL) |
185  ((x >> 24) & 0x0000000000ff0000ULL) |
186  ((x >> 40) & 0x000000000000ff00ULL) |
187  ((x >> 56) & 0x00000000000000ffULL);
188 }
189 #endif
190 
191 //**************************************
192 // Constants
193 //**************************************
194 #define PRIME32_1 2654435761U
195 #define PRIME32_2 2246822519U
196 #define PRIME32_3 3266489917U
197 #define PRIME32_4 668265263U
198 #define PRIME32_5 374761393U
199 
200 #define PRIME64_1 11400714785074694791ULL
201 #define PRIME64_2 14029467366897019727ULL
202 #define PRIME64_3 1609587929392839161ULL
203 #define PRIME64_4 9650029242287828579ULL
204 #define PRIME64_5 2870177450012600261ULL
205 
206 //**************************************
207 // Architecture Macros
208 //**************************************
209 typedef enum { XXH_bigEndian = 0, XXH_littleEndian = 1 } XXH_endianess;
210 #ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch
211 static const int one = 1;
212 #define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))
213 #endif
214 
215 //**************************************
216 // Macros
217 //**************************************
218 #define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations
219 
220 //****************************
221 // Memory reads
222 //****************************
223 typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
224 
225 FORCE_INLINE U32 XXH_readLE32_align(const void *ptr, XXH_endianess endian,
226  XXH_alignment align)
227 {
228  if (align == XXH_unaligned)
229  return endian ==
230  XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr));
231  else
232  return endian ==
233  XXH_littleEndian ? *(U32 *) ptr : XXH_swap32(*(U32 *) ptr);
234 }
235 
236 FORCE_INLINE U32 XXH_readLE32(const void *ptr, XXH_endianess endian)
237 {
238  return XXH_readLE32_align(ptr, endian, XXH_unaligned);
239 }
240 
241 FORCE_INLINE U64 XXH_readLE64_align(const void *ptr, XXH_endianess endian,
242  XXH_alignment align)
243 {
244  if (align == XXH_unaligned)
245  return endian ==
246  XXH_littleEndian ? A64(ptr) : XXH_swap64(A64(ptr));
247  else
248  return endian ==
249  XXH_littleEndian ? *(U64 *) ptr : XXH_swap64(*(U64 *) ptr);
250 }
251 
252 FORCE_INLINE U64 XXH_readLE64(const void *ptr, XXH_endianess endian)
253 {
254  return XXH_readLE64_align(ptr, endian, XXH_unaligned);
255 }
256 
257 //****************************
258 // Simple Hash Functions
259 //****************************
260 FORCE_INLINE U32 XXH32_endian_align(const void *input, size_t len, U32 seed,
261  XXH_endianess endian, XXH_alignment align)
262 {
263  const BYTE *p = (const BYTE *)input;
264  const BYTE *bEnd = p + len;
265  U32 h32;
266 #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
267 
268 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
269  if (p == NULL) {
270  len = 0;
271  bEnd = p = (const BYTE *)(size_t)16;
272  }
273 #endif
274 
275  if (len >= 16) {
276  const BYTE *const limit = bEnd - 16;
277  U32 v1 = seed + PRIME32_1 + PRIME32_2;
278  U32 v2 = seed + PRIME32_2;
279  U32 v3 = seed + 0;
280  U32 v4 = seed - PRIME32_1;
281 
282  do {
283  v1 += XXH_get32bits(p) * PRIME32_2;
284  v1 = XXH_rotl32(v1, 13);
285  v1 *= PRIME32_1;
286  p += 4;
287  v2 += XXH_get32bits(p) * PRIME32_2;
288  v2 = XXH_rotl32(v2, 13);
289  v2 *= PRIME32_1;
290  p += 4;
291  v3 += XXH_get32bits(p) * PRIME32_2;
292  v3 = XXH_rotl32(v3, 13);
293  v3 *= PRIME32_1;
294  p += 4;
295  v4 += XXH_get32bits(p) * PRIME32_2;
296  v4 = XXH_rotl32(v4, 13);
297  v4 *= PRIME32_1;
298  p += 4;
299  }
300  while (p <= limit);
301 
302  h32 =
303  XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3,
304  12) +
305  XXH_rotl32(v4, 18);
306  } else {
307  h32 = seed + PRIME32_5;
308  }
309 
310  h32 += (U32) len;
311 
312  while (p + 4 <= bEnd) {
313  h32 += XXH_get32bits(p) * PRIME32_3;
314  h32 = XXH_rotl32(h32, 17) * PRIME32_4;
315  p += 4;
316  }
317 
318  while (p < bEnd) {
319  h32 += (*p) * PRIME32_5;
320  h32 = XXH_rotl32(h32, 11) * PRIME32_1;
321  p++;
322  }
323 
324  h32 ^= h32 >> 15;
325  h32 *= PRIME32_2;
326  h32 ^= h32 >> 13;
327  h32 *= PRIME32_3;
328  h32 ^= h32 >> 16;
329 
330  return h32;
331 }
332 
333 unsigned int XXH32(const void *input, size_t len, unsigned seed)
334 {
335 #if 0
336  // Simple version, good for code maintenance, but unfortunately slow for small inputs
337  XXH32_state_t state;
338  XXH32_reset(&state, seed);
339  XXH32_update(&state, input, len);
340  return XXH32_digest(&state);
341 #else
342  XXH_endianess endian_detected = (XXH_endianess) XXH_CPU_LITTLE_ENDIAN;
343 
344 #if !defined(XXH_USE_UNALIGNED_ACCESS)
345  if ((((size_t)input) & 3) == 0) // Input is aligned, let's leverage the speed advantage
346  {
347  if ((endian_detected == XXH_littleEndian)
348  || XXH_FORCE_NATIVE_FORMAT)
349  return XXH32_endian_align(input, len, seed,
350  XXH_littleEndian,
351  XXH_aligned);
352  else
353  return XXH32_endian_align(input, len, seed,
354  XXH_bigEndian, XXH_aligned);
355  }
356 #endif
357 
358  if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
359  return XXH32_endian_align(input, len, seed, XXH_littleEndian,
360  XXH_unaligned);
361  else
362  return XXH32_endian_align(input, len, seed, XXH_bigEndian,
363  XXH_unaligned);
364 #endif
365 }
366 
367 FORCE_INLINE U64 XXH64_endian_align(const void *input, size_t len, U64 seed,
368  XXH_endianess endian, XXH_alignment align)
369 {
370  const BYTE *p = (const BYTE *)input;
371  const BYTE *bEnd = p + len;
372  U64 h64;
373 #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
374 
375 #ifdef XXH_ACCEPT_NULL_INPUT_POINTER
376  if (p == NULL) {
377  len = 0;
378  bEnd = p = (const BYTE *)(size_t)32;
379  }
380 #endif
381 
382  if (len >= 32) {
383  const BYTE *const limit = bEnd - 32;
384  U64 v1 = seed + PRIME64_1 + PRIME64_2;
385  U64 v2 = seed + PRIME64_2;
386  U64 v3 = seed + 0;
387  U64 v4 = seed - PRIME64_1;
388 
389  do {
390  v1 += XXH_get64bits(p) * PRIME64_2;
391  p += 8;
392  v1 = XXH_rotl64(v1, 31);
393  v1 *= PRIME64_1;
394  v2 += XXH_get64bits(p) * PRIME64_2;
395  p += 8;
396  v2 = XXH_rotl64(v2, 31);
397  v2 *= PRIME64_1;
398  v3 += XXH_get64bits(p) * PRIME64_2;
399  p += 8;
400  v3 = XXH_rotl64(v3, 31);
401  v3 *= PRIME64_1;
402  v4 += XXH_get64bits(p) * PRIME64_2;
403  p += 8;
404  v4 = XXH_rotl64(v4, 31);
405  v4 *= PRIME64_1;
406  }
407  while (p <= limit);
408 
409  h64 =
410  XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3,
411  12) +
412  XXH_rotl64(v4, 18);
413 
414  v1 *= PRIME64_2;
415  v1 = XXH_rotl64(v1, 31);
416  v1 *= PRIME64_1;
417  h64 ^= v1;
418  h64 = h64 * PRIME64_1 + PRIME64_4;
419 
420  v2 *= PRIME64_2;
421  v2 = XXH_rotl64(v2, 31);
422  v2 *= PRIME64_1;
423  h64 ^= v2;
424  h64 = h64 * PRIME64_1 + PRIME64_4;
425 
426  v3 *= PRIME64_2;
427  v3 = XXH_rotl64(v3, 31);
428  v3 *= PRIME64_1;
429  h64 ^= v3;
430  h64 = h64 * PRIME64_1 + PRIME64_4;
431 
432  v4 *= PRIME64_2;
433  v4 = XXH_rotl64(v4, 31);
434  v4 *= PRIME64_1;
435  h64 ^= v4;
436  h64 = h64 * PRIME64_1 + PRIME64_4;
437  } else {
438  h64 = seed + PRIME64_5;
439  }
440 
441  h64 += (U64) len;
442 
443  while (p + 8 <= bEnd) {
444  U64 k1 = XXH_get64bits(p);
445  k1 *= PRIME64_2;
446  k1 = XXH_rotl64(k1, 31);
447  k1 *= PRIME64_1;
448  h64 ^= k1;
449  h64 = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
450  p += 8;
451  }
452 
453  if (p + 4 <= bEnd) {
454  h64 ^= (U64) (XXH_get32bits(p)) * PRIME64_1;
455  h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
456  p += 4;
457  }
458 
459  while (p < bEnd) {
460  h64 ^= (*p) * PRIME64_5;
461  h64 = XXH_rotl64(h64, 11) * PRIME64_1;
462  p++;
463  }
464 
465  h64 ^= h64 >> 33;
466  h64 *= PRIME64_2;
467  h64 ^= h64 >> 29;
468  h64 *= PRIME64_3;
469  h64 ^= h64 >> 32;
470 
471  return h64;
472 }
473 
474 unsigned long long XXH64(const void *input, size_t len, unsigned long long seed)
475 {
476 #if 0
477  // Simple version, good for code maintenance, but unfortunately slow for small inputs
478  XXH64_state_t state;
479  XXH64_reset(&state, seed);
480  XXH64_update(&state, input, len);
481  return XXH64_digest(&state);
482 #else
483  XXH_endianess endian_detected = (XXH_endianess) XXH_CPU_LITTLE_ENDIAN;
484 
485 #if !defined(XXH_USE_UNALIGNED_ACCESS)
486  if ((((size_t)input) & 7) == 0) // Input is aligned, let's leverage the speed advantage
487  {
488  if ((endian_detected == XXH_littleEndian)
489  || XXH_FORCE_NATIVE_FORMAT)
490  return XXH64_endian_align(input, len, seed,
491  XXH_littleEndian,
492  XXH_aligned);
493  else
494  return XXH64_endian_align(input, len, seed,
495  XXH_bigEndian, XXH_aligned);
496  }
497 #endif
498 
499  if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
500  return XXH64_endian_align(input, len, seed, XXH_littleEndian,
501  XXH_unaligned);
502  else
503  return XXH64_endian_align(input, len, seed, XXH_bigEndian,
504  XXH_unaligned);
505 #endif
506 }
507 
508 #endif /* EXTRA_CHECKS */
Definition: xxhash.c:139
Definition: xxhash.c:136
Fast Hash Algorithm.