Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // Copyright (c) 2019 Facebook
0003 #include <features.h>
0004 
0005 typedef unsigned int u32;
0006 
0007 static __always_inline u32 rol32(u32 word, unsigned int shift)
0008 {
0009     return (word << shift) | (word >> ((-shift) & 31));
0010 }
0011 
0012 #define __jhash_mix(a, b, c)            \
0013 {                       \
0014     a -= c;  a ^= rol32(c, 4);  c += b; \
0015     b -= a;  b ^= rol32(a, 6);  a += c; \
0016     c -= b;  c ^= rol32(b, 8);  b += a; \
0017     a -= c;  a ^= rol32(c, 16); c += b; \
0018     b -= a;  b ^= rol32(a, 19); a += c; \
0019     c -= b;  c ^= rol32(b, 4);  b += a; \
0020 }
0021 
0022 #define __jhash_final(a, b, c)          \
0023 {                       \
0024     c ^= b; c -= rol32(b, 14);      \
0025     a ^= c; a -= rol32(c, 11);      \
0026     b ^= a; b -= rol32(a, 25);      \
0027     c ^= b; c -= rol32(b, 16);      \
0028     a ^= c; a -= rol32(c, 4);       \
0029     b ^= a; b -= rol32(a, 14);      \
0030     c ^= b; c -= rol32(b, 24);      \
0031 }
0032 
0033 #define JHASH_INITVAL       0xdeadbeef
0034 
0035 static ATTR
0036 u32 jhash(const void *key, u32 length, u32 initval)
0037 {
0038     u32 a, b, c;
0039     const unsigned char *k = key;
0040 
0041     a = b = c = JHASH_INITVAL + length + initval;
0042 
0043     while (length > 12) {
0044         a += *(volatile u32 *)(k);
0045         b += *(volatile u32 *)(k + 4);
0046         c += *(volatile u32 *)(k + 8);
0047         __jhash_mix(a, b, c);
0048         length -= 12;
0049         k += 12;
0050     }
0051     switch (length) {
0052     case 12: c += (u32)k[11]<<24;
0053     case 11: c += (u32)k[10]<<16;
0054     case 10: c += (u32)k[9]<<8;
0055     case 9:  c += k[8];
0056     case 8:  b += (u32)k[7]<<24;
0057     case 7:  b += (u32)k[6]<<16;
0058     case 6:  b += (u32)k[5]<<8;
0059     case 5:  b += k[4];
0060     case 4:  a += (u32)k[3]<<24;
0061     case 3:  a += (u32)k[2]<<16;
0062     case 2:  a += (u32)k[1]<<8;
0063     case 1:  a += k[0];
0064          c ^= a;
0065          __jhash_final(a, b, c);
0066     case 0: /* Nothing left to add */
0067         break;
0068     }
0069 
0070     return c;
0071 }