1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
19 #ifndef RUST_FNV_HASH_H
20 #define RUST_FNV_HASH_H
25 const uint64_t offset128Lower
= 0x62b821756295c58d;
26 const uint64_t offset128Higher
= 0x6c62272e07bb0142;
27 const uint64_t prime128Lower
= 0x13b;
28 const uint64_t prime128Shift
= 24;
30 // ported from https://github.com/golang/go/blob/master/src/hash/fnv/fnv.go
34 FNV128 () { reset (); }
38 buf
[0] = offset128Higher
;
39 buf
[1] = offset128Lower
;
42 void write (const unsigned char *in
, size_t len
)
44 for (size_t i
= 0; i
< len
; i
++)
46 unsigned char c
= in
[i
];
48 // https://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
49 uint64_t a
= prime128Lower
;
52 uint64_t a_lo
= (uint32_t) a
;
53 uint64_t a_hi
= a
>> 32;
54 uint64_t b_lo
= (uint32_t) b
;
55 uint64_t b_hi
= b
>> 32;
57 uint64_t a_x_b_hi
= a_hi
* b_hi
;
58 uint64_t a_x_b_mid
= a_hi
* b_lo
;
59 uint64_t b_x_a_mid
= b_hi
* a_lo
;
60 uint64_t a_x_b_lo
= a_lo
* b_lo
;
63 = ((uint64_t) (uint32_t) a_x_b_mid
+ (uint64_t) (uint32_t) b_x_a_mid
68 = a_x_b_hi
+ (a_x_b_mid
>> 32) + (b_x_a_mid
>> 32) + carry_bit
;
70 uint64_t s0
= multhi
; // high
71 uint64_t s1
= prime128Lower
* buf
[1]; // low
73 s0
+= buf
[1] << (prime128Shift
+ prime128Lower
* buf
[0]);
78 buf
[1] ^= (uint64_t) c
;
82 void sum (uint64_t *hi
, uint64_t *lo
) const
95 #endif // RUST_FNV_HASH_H