1 // FARMHASH ASSUMPTIONS: Modify as needed, or use -DFARMHASH_ASSUME_SSE42 etc.
2 // Note that if you use -DFARMHASH_ASSUME_SSE42 you likely need -msse42
3 // (or its equivalent for your compiler); if you use -DFARMHASH_ASSUME_AESNI
4 // you likely need -maes (or its equivalent for your compiler).
5 
6 #ifdef FARMHASH_ASSUME_SSSE3
7 #undef FARMHASH_ASSUME_SSSE3
8 #define FARMHASH_ASSUME_SSSE3 1
9 #endif
10 
11 #ifdef FARMHASH_ASSUME_SSE41
12 #undef FARMHASH_ASSUME_SSE41
13 #define FARMHASH_ASSUME_SSE41 1
14 #endif
15 
16 #ifdef FARMHASH_ASSUME_SSE42
17 #undef FARMHASH_ASSUME_SSE42
18 #define FARMHASH_ASSUME_SSE42 1
19 #endif
20 
21 #ifdef FARMHASH_ASSUME_AESNI
22 #undef FARMHASH_ASSUME_AESNI
23 #define FARMHASH_ASSUME_AESNI 1
24 #endif
25 
26 #ifdef FARMHASH_ASSUME_AVX
27 #undef FARMHASH_ASSUME_AVX
28 #define FARMHASH_ASSUME_AVX 1
29 #endif
30 
31 #if !defined(FARMHASH_CAN_USE_CXX11) && defined(LANG_CXX11)
32 #define FARMHASH_CAN_USE_CXX11 1
33 #else
34 #undef FARMHASH_CAN_USE_CXX11
35 #define FARMHASH_CAN_USE_CXX11 0
36 #endif
37 
38 // FARMHASH PORTABILITY LAYER: Runtime error if misconfigured
39 
40 #ifndef FARMHASH_DIE_IF_MISCONFIGURED
41 #define FARMHASH_DIE_IF_MISCONFIGURED do { *(char*)(len % 17) = 0; } while (0)
42 #endif
43 
44 // FARMHASH PORTABILITY LAYER: "static inline" or similar
45 
46 #ifndef STATIC_INLINE
47 #define STATIC_INLINE static inline
48 #endif
49 
50 // FARMHASH PORTABILITY LAYER: LIKELY and UNLIKELY
51 
52 #if !defined(LIKELY)
53 #if defined(FARMHASH_NO_BUILTIN_EXPECT) || (defined(FARMHASH_OPTIONAL_BUILTIN_EXPECT) && !defined(HAVE_BUILTIN_EXPECT))
54 #define LIKELY(x) (x)
55 #else
56 #define LIKELY(x) (__builtin_expect(!!(x), 1))
57 #endif
58 #endif
59 
60 #undef UNLIKELY
61 #define UNLIKELY(x) !LIKELY(!(x))
62 
63 // FARMHASH PORTABILITY LAYER: endianness and byteswapping functions
64 
65 #ifdef WORDS_BIGENDIAN
66 #undef FARMHASH_BIG_ENDIAN
67 #define FARMHASH_BIG_ENDIAN 1
68 #endif
69 
70 #if defined(FARMHASH_LITTLE_ENDIAN) && defined(FARMHASH_BIG_ENDIAN)
71 #error
72 #endif
73 
74 #if !defined(FARMHASH_LITTLE_ENDIAN) && !defined(FARMHASH_BIG_ENDIAN)
75 #define FARMHASH_UNKNOWN_ENDIAN 1
76 #endif
77 
78 #if !defined(bswap_32) || !defined(bswap_64)
79 #undef bswap_32
80 #undef bswap_64
81 
82 #if defined(HAVE_BUILTIN_BSWAP) || defined(__clang__) ||                \
83   (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) ||      \
84                          __GNUC__ >= 5))
85 // Easy case for bswap: no header file needed.
86 #define bswap_32(x) __builtin_bswap32(x)
87 #define bswap_64(x) __builtin_bswap64(x)
88 #endif
89 
90 #endif
91 
92 #if defined(FARMHASH_UNKNOWN_ENDIAN) || !defined(bswap_64)
93 
94 #ifdef _MSC_VER
95 
96 #undef bswap_32
97 #undef bswap_64
98 #define bswap_32(x) _byteswap_ulong(x)
99 #define bswap_64(x) _byteswap_uint64(x)
100 
101 #elif defined(__APPLE__)
102 
103 // Mac OS X / Darwin features
104 #include <libkern/OSByteOrder.h>
105 #undef bswap_32
106 #undef bswap_64
107 #define bswap_32(x) OSSwapInt32(x)
108 #define bswap_64(x) OSSwapInt64(x)
109 
110 #elif defined(__sun) || defined(sun)
111 
112 #include <sys/byteorder.h>
113 #undef bswap_32
114 #undef bswap_64
115 #define bswap_32(x) BSWAP_32(x)
116 #define bswap_64(x) BSWAP_64(x)
117 
118 #elif defined(__FreeBSD__) || defined(__DragonFly__)
119 
120 #include <sys/endian.h>
121 #undef bswap_32
122 #undef bswap_64
123 #define bswap_32(x) bswap32(x)
124 #define bswap_64(x) bswap64(x)
125 
126 #elif defined(__OpenBSD__)
127 
128 #include <sys/types.h>
129 #undef bswap_32
130 #undef bswap_64
131 #define bswap_32(x) swap32(x)
132 #define bswap_64(x) swap64(x)
133 
134 #elif defined(__NetBSD__)
135 
136 #include <sys/types.h>
137 #include <machine/bswap.h>
138 #if defined(__BSWAP_RENAME) && !defined(__bswap_32)
139 #undef bswap_32
140 #undef bswap_64
141 #define bswap_32(x) bswap32(x)
142 #define bswap_64(x) bswap64(x)
143 #endif
144 
145 #else
146 
147 #undef bswap_32
148 #undef bswap_64
149 #include <byteswap.h>
150 
151 #endif
152 
153 #ifdef WORDS_BIGENDIAN
154 #define FARMHASH_BIG_ENDIAN 1
155 #endif
156 
157 #endif
158 
159 #ifdef FARMHASH_BIG_ENDIAN
160 #define uint32_in_expected_order(x) (bswap_32(x))
161 #define uint64_in_expected_order(x) (bswap_64(x))
162 #else
163 #define uint32_in_expected_order(x) (x)
164 #define uint64_in_expected_order(x) (x)
165 #endif
166 
167 namespace NAMESPACE_FOR_HASH_FUNCTIONS {
168 
Fetch64(const char * p)169 STATIC_INLINE uint64_t Fetch64(const char *p) {
170   uint64_t result;
171   memcpy(&result, p, sizeof(result));
172   return uint64_in_expected_order(result);
173 }
174 
Fetch32(const char * p)175 STATIC_INLINE uint32_t Fetch32(const char *p) {
176   uint32_t result;
177   memcpy(&result, p, sizeof(result));
178   return uint32_in_expected_order(result);
179 }
180 
Bswap32(uint32_t val)181 STATIC_INLINE uint32_t Bswap32(uint32_t val) { return bswap_32(val); }
Bswap64(uint64_t val)182 STATIC_INLINE uint64_t Bswap64(uint64_t val) { return bswap_64(val); }
183 
184 // FARMHASH PORTABILITY LAYER: bitwise rot
185 
BasicRotate32(uint32_t val,int shift)186 STATIC_INLINE uint32_t BasicRotate32(uint32_t val, int shift) {
187   // Avoid shifting by 32: doing so yields an undefined result.
188   return shift == 0 ? val : ((val >> shift) | (val << (32 - shift)));
189 }
190 
BasicRotate64(uint64_t val,int shift)191 STATIC_INLINE uint64_t BasicRotate64(uint64_t val, int shift) {
192   // Avoid shifting by 64: doing so yields an undefined result.
193   return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
194 }
195 
196 #if defined(_MSC_VER) && defined(FARMHASH_ROTR)
197 
Rotate32(uint32_t val,int shift)198 STATIC_INLINE uint32_t Rotate32(uint32_t val, int shift) {
199   return sizeof(unsigned long) == sizeof(val) ?
200       _lrotr(val, shift) :
201       BasicRotate32(val, shift);
202 }
203 
Rotate64(uint64_t val,int shift)204 STATIC_INLINE uint64_t Rotate64(uint64_t val, int shift) {
205   return sizeof(unsigned long) == sizeof(val) ?
206       _lrotr(val, shift) :
207       BasicRotate64(val, shift);
208 }
209 
210 #else
211 
Rotate32(uint32_t val,int shift)212 STATIC_INLINE uint32_t Rotate32(uint32_t val, int shift) {
213   return BasicRotate32(val, shift);
214 }
Rotate64(uint64_t val,int shift)215 STATIC_INLINE uint64_t Rotate64(uint64_t val, int shift) {
216   return BasicRotate64(val, shift);
217 }
218 
219 #endif
220 
221 }  // namespace NAMESPACE_FOR_HASH_FUNCTIONS
222 
223 // FARMHASH PORTABILITY LAYER: debug mode or max speed?
224 // One may use -DFARMHASH_DEBUG=1 or -DFARMHASH_DEBUG=0 to force the issue.
225 
226 #if !defined(FARMHASH_DEBUG) && (!defined(NDEBUG) || defined(_DEBUG))
227 #define FARMHASH_DEBUG 1
228 #endif
229 
230 #undef debug_mode
231 #if FARMHASH_DEBUG
232 #define debug_mode 1
233 #else
234 #define debug_mode 0
235 #endif
236 
237 // PLATFORM-SPECIFIC FUNCTIONS AND MACROS
238 
239 #undef x86_64
240 #if defined (__x86_64) || defined (__x86_64__)
241 #define x86_64 1
242 #else
243 #define x86_64 0
244 #endif
245 
246 #undef x86
247 #if defined(__i386__) || defined(__i386) || defined(__X86__)
248 #define x86 1
249 #else
250 #define x86 x86_64
251 #endif
252 
253 #if !defined(is_64bit)
254 #define is_64bit (x86_64 || (sizeof(void*) == 8))
255 #endif
256 
257 #undef can_use_ssse3
258 #if defined(__SSSE3__) || defined(FARMHASH_ASSUME_SSSE3)
259 
260 #include <immintrin.h>
261 #define can_use_ssse3 1
262 // Now we can use _mm_hsub_epi16 and so on.
263 
264 #else
265 #define can_use_ssse3 0
266 #endif
267 
268 #undef can_use_sse41
269 #if defined(__SSE4_1__) || defined(FARMHASH_ASSUME_SSE41)
270 
271 #include <immintrin.h>
272 #define can_use_sse41 1
273 // Now we can use _mm_insert_epi64 and so on.
274 
275 #else
276 #define can_use_sse41 0
277 #endif
278 
279 #undef can_use_sse42
280 #if defined(__SSE4_2__) || defined(FARMHASH_ASSUME_SSE42)
281 
282 #include <nmmintrin.h>
283 #define can_use_sse42 1
284 // Now we can use _mm_crc32_u{32,16,8}.  And on 64-bit platforms, _mm_crc32_u64.
285 
286 #else
287 #define can_use_sse42 0
288 #endif
289 
290 #undef can_use_aesni
291 #if defined(__AES__) || defined(FARMHASH_ASSUME_AESNI)
292 
293 #include <wmmintrin.h>
294 #define can_use_aesni 1
295 // Now we can use _mm_aesimc_si128 and so on.
296 
297 #else
298 #define can_use_aesni 0
299 #endif
300 
301 #undef can_use_avx
302 #if defined(__AVX__) || defined(FARMHASH_ASSUME_AVX)
303 
304 #include <immintrin.h>
305 #define can_use_avx 1
306 
307 #else
308 #define can_use_avx 0
309 #endif
310 
311 #if can_use_ssse3 || can_use_sse41 || can_use_sse42 || can_use_aesni || can_use_avx
Fetch128(const char * s)312 STATIC_INLINE __m128i Fetch128(const char* s) {
313   return _mm_loadu_si128(reinterpret_cast<const __m128i*>(s));
314 }
315 #endif
316