1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Hashing algorithm inspired by
6 // wyhash: https://github.com/wangyi-fudan/wyhash
8 //go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
13 "runtime/internal/math"
18 m1 = 0xa0761d6478bd642f
19 m2 = 0xe7037ed1a0b428db
20 m3 = 0x8ebc6af09c88c6e3
21 m4 = 0x589965cc75374cc3
22 m5 = 0x1d8e4e27c47d124f
25 func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr {
27 seed ^= hashkey[0] ^ m1
32 a = uintptr(*(*byte)(p))
33 a |= uintptr(*(*byte)(add(p, s>>1))) << 8
34 a |= uintptr(*(*byte)(add(p, s-1))) << 16
52 for ; l > 48; l -= 48 {
53 seed = mix(r8(p)^m2, r8(add(p, 8))^seed)
54 seed1 = mix(r8(add(p, 16))^m3, r8(add(p, 24))^seed1)
55 seed2 = mix(r8(add(p, 32))^m4, r8(add(p, 40))^seed2)
60 for ; l > 16; l -= 16 {
61 seed = mix(r8(p)^m2, r8(add(p, 8))^seed)
68 return mix(m5^s, mix(a^m2, b^seed))
71 func memhash32Fallback(p unsafe.Pointer, seed uintptr) uintptr {
73 return mix(m5^4, mix(a^m2, a^seed^hashkey[0]^m1))
76 func memhash64Fallback(p unsafe.Pointer, seed uintptr) uintptr {
78 return mix(m5^8, mix(a^m2, a^seed^hashkey[0]^m1))
81 func mix(a, b uintptr) uintptr {
82 hi, lo := math.Mul64(uint64(a), uint64(b))
83 return uintptr(hi ^ lo)
86 func r4(p unsafe.Pointer) uintptr {
87 return uintptr(readUnaligned32(p))
90 func r8(p unsafe.Pointer) uintptr {
91 return uintptr(readUnaligned64(p))