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. 4 5// Hashing algorithm inspired by 6// wyhash: https://github.com/wangyi-fudan/wyhash/blob/ceb019b530e2c1c14d70b79bfa2bc49de7d95bc1/Modern%20Non-Cryptographic%20Hash%20Function%20and%20Pseudorandom%20Number%20Generator.pdf 7 8//go:build 386 || arm || mips || mipsle 9 10package runtime 11 12import "unsafe" 13 14func memhash32Fallback(p unsafe.Pointer, seed uintptr) uintptr { 15 a, b := mix32(uint32(seed), uint32(4^hashkey[0])) 16 t := readUnaligned32(p) 17 a ^= t 18 b ^= t 19 a, b = mix32(a, b) 20 a, b = mix32(a, b) 21 return uintptr(a ^ b) 22} 23 24func memhash64Fallback(p unsafe.Pointer, seed uintptr) uintptr { 25 a, b := mix32(uint32(seed), uint32(8^hashkey[0])) 26 a ^= readUnaligned32(p) 27 b ^= readUnaligned32(add(p, 4)) 28 a, b = mix32(a, b) 29 a, b = mix32(a, b) 30 return uintptr(a ^ b) 31} 32 33func memhashFallback(p unsafe.Pointer, seed, s uintptr) uintptr { 34 35 a, b := mix32(uint32(seed), uint32(s^hashkey[0])) 36 if s == 0 { 37 return uintptr(a ^ b) 38 } 39 for ; s > 8; s -= 8 { 40 a ^= readUnaligned32(p) 41 b ^= readUnaligned32(add(p, 4)) 42 a, b = mix32(a, b) 43 p = add(p, 8) 44 } 45 if s >= 4 { 46 a ^= readUnaligned32(p) 47 b ^= readUnaligned32(add(p, s-4)) 48 } else { 49 t := uint32(*(*byte)(p)) 50 t |= uint32(*(*byte)(add(p, s>>1))) << 8 51 t |= uint32(*(*byte)(add(p, s-1))) << 16 52 b ^= t 53 } 54 a, b = mix32(a, b) 55 a, b = mix32(a, b) 56 return uintptr(a ^ b) 57} 58 59func mix32(a, b uint32) (uint32, uint32) { 60 c := uint64(a^uint32(hashkey[1])) * uint64(b^uint32(hashkey[2])) 61 return uint32(c), uint32(c >> 32) 62} 63