1#ifndef _LINUX_HASH_H
2#define _LINUX_HASH_H
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <asm/types.h>
18#include <asm/hash.h>
19#include <linux/compiler.h>
20
21
22#define GOLDEN_RATIO_PRIME_32 0x9e370001UL
23
24#define GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001UL
25
26#if BITS_PER_LONG == 32
27#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_32
28#define hash_long(val, bits) hash_32(val, bits)
29#elif BITS_PER_LONG == 64
30#define hash_long(val, bits) hash_64(val, bits)
31#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_64
32#else
33#error Wordsize not 32 or 64
34#endif
35
36static __always_inline u64 hash_64(u64 val, unsigned int bits)
37{
38 u64 hash = val;
39
40#if defined(CONFIG_ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
41 hash = hash * GOLDEN_RATIO_PRIME_64;
42#else
43
44 u64 n = hash;
45 n <<= 18;
46 hash -= n;
47 n <<= 33;
48 hash -= n;
49 n <<= 3;
50 hash += n;
51 n <<= 3;
52 hash -= n;
53 n <<= 4;
54 hash += n;
55 n <<= 2;
56 hash += n;
57#endif
58
59
60 return hash >> (64 - bits);
61}
62
63static inline u32 hash_32(u32 val, unsigned int bits)
64{
65
66 u32 hash = val * GOLDEN_RATIO_PRIME_32;
67
68
69 return hash >> (32 - bits);
70}
71
72static inline unsigned long hash_ptr(const void *ptr, unsigned int bits)
73{
74 return hash_long((unsigned long)ptr, bits);
75}
76
77static inline u32 hash32_ptr(const void *ptr)
78{
79 unsigned long val = (unsigned long)ptr;
80
81#if BITS_PER_LONG == 64
82 val ^= (val >> 32);
83#endif
84 return (u32)val;
85}
86
87struct fast_hash_ops {
88 u32 (*hash)(const void *data, u32 len, u32 seed);
89 u32 (*hash2)(const u32 *data, u32 len, u32 seed);
90};
91
92
93
94
95
96
97
98
99
100
101
102
103
104extern u32 arch_fast_hash(const void *data, u32 len, u32 seed);
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119extern u32 arch_fast_hash2(const u32 *data, u32 len, u32 seed);
120
121#endif
122