1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#ifndef QEMU_XXHASH_H
35#define QEMU_XXHASH_H
36
37#include "qemu/bitops.h"
38
39#define PRIME32_1 2654435761U
40#define PRIME32_2 2246822519U
41#define PRIME32_3 3266489917U
42#define PRIME32_4 668265263U
43#define PRIME32_5 374761393U
44
45#define QEMU_XXHASH_SEED 1
46
47
48
49
50
51static inline uint32_t
52qemu_xxhash7(uint64_t ab, uint64_t cd, uint32_t e, uint32_t f, uint32_t g)
53{
54 uint32_t v1 = QEMU_XXHASH_SEED + PRIME32_1 + PRIME32_2;
55 uint32_t v2 = QEMU_XXHASH_SEED + PRIME32_2;
56 uint32_t v3 = QEMU_XXHASH_SEED + 0;
57 uint32_t v4 = QEMU_XXHASH_SEED - PRIME32_1;
58 uint32_t a = ab;
59 uint32_t b = ab >> 32;
60 uint32_t c = cd;
61 uint32_t d = cd >> 32;
62 uint32_t h32;
63
64 v1 += a * PRIME32_2;
65 v1 = rol32(v1, 13);
66 v1 *= PRIME32_1;
67
68 v2 += b * PRIME32_2;
69 v2 = rol32(v2, 13);
70 v2 *= PRIME32_1;
71
72 v3 += c * PRIME32_2;
73 v3 = rol32(v3, 13);
74 v3 *= PRIME32_1;
75
76 v4 += d * PRIME32_2;
77 v4 = rol32(v4, 13);
78 v4 *= PRIME32_1;
79
80 h32 = rol32(v1, 1) + rol32(v2, 7) + rol32(v3, 12) + rol32(v4, 18);
81 h32 += 28;
82
83 h32 += e * PRIME32_3;
84 h32 = rol32(h32, 17) * PRIME32_4;
85
86 h32 += f * PRIME32_3;
87 h32 = rol32(h32, 17) * PRIME32_4;
88
89 h32 += g * PRIME32_3;
90 h32 = rol32(h32, 17) * PRIME32_4;
91
92 h32 ^= h32 >> 15;
93 h32 *= PRIME32_2;
94 h32 ^= h32 >> 13;
95 h32 *= PRIME32_3;
96 h32 ^= h32 >> 16;
97
98 return h32;
99}
100
101static inline uint32_t qemu_xxhash2(uint64_t ab)
102{
103 return qemu_xxhash7(ab, 0, 0, 0, 0);
104}
105
106static inline uint32_t qemu_xxhash4(uint64_t ab, uint64_t cd)
107{
108 return qemu_xxhash7(ab, cd, 0, 0, 0);
109}
110
111static inline uint32_t qemu_xxhash5(uint64_t ab, uint64_t cd, uint32_t e)
112{
113 return qemu_xxhash7(ab, cd, e, 0, 0);
114}
115
116static inline uint32_t qemu_xxhash6(uint64_t ab, uint64_t cd, uint32_t e,
117 uint32_t f)
118{
119 return qemu_xxhash7(ab, cd, e, f, 0);
120}
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL
165#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL
166#define XXH_PRIME64_3 0x165667B19E3779F9ULL
167#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL
168#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL
169
170static inline uint64_t XXH64_round(uint64_t acc, uint64_t input)
171{
172 return rol64(acc + input * XXH_PRIME64_2, 31) * XXH_PRIME64_1;
173}
174
175static inline uint64_t XXH64_mergeround(uint64_t acc, uint64_t val)
176{
177 return (acc ^ XXH64_round(0, val)) * XXH_PRIME64_1 + XXH_PRIME64_4;
178}
179
180static inline uint64_t XXH64_mergerounds(uint64_t v1, uint64_t v2,
181 uint64_t v3, uint64_t v4)
182{
183 uint64_t h64;
184
185 h64 = rol64(v1, 1) + rol64(v2, 7) + rol64(v3, 12) + rol64(v4, 18);
186 h64 = XXH64_mergeround(h64, v1);
187 h64 = XXH64_mergeround(h64, v2);
188 h64 = XXH64_mergeround(h64, v3);
189 h64 = XXH64_mergeround(h64, v4);
190
191 return h64;
192}
193
194static inline uint64_t XXH64_avalanche(uint64_t h64)
195{
196 h64 ^= h64 >> 33;
197 h64 *= XXH_PRIME64_2;
198 h64 ^= h64 >> 29;
199 h64 *= XXH_PRIME64_3;
200 h64 ^= h64 >> 32;
201 return h64;
202}
203
204static inline uint64_t qemu_xxhash64_4(uint64_t a, uint64_t b,
205 uint64_t c, uint64_t d)
206{
207 uint64_t v1 = QEMU_XXHASH_SEED + XXH_PRIME64_1 + XXH_PRIME64_2;
208 uint64_t v2 = QEMU_XXHASH_SEED + XXH_PRIME64_2;
209 uint64_t v3 = QEMU_XXHASH_SEED + 0;
210 uint64_t v4 = QEMU_XXHASH_SEED - XXH_PRIME64_1;
211
212 v1 = XXH64_round(v1, a);
213 v2 = XXH64_round(v2, b);
214 v3 = XXH64_round(v3, c);
215 v4 = XXH64_round(v4, d);
216
217 return XXH64_avalanche(XXH64_mergerounds(v1, v2, v3, v4));
218}
219
220#endif
221