summaryrefslogtreecommitdiff
path: root/libguile/whippet/src/address-hash.h
blob: 49c33be97fe5bdcfe7750394b8c780193bbb779d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef ADDRESS_HASH_H
#define ADDRESS_HASH_H

#include <stdint.h>

static uintptr_t hash_address(uintptr_t x) {
  if (sizeof (x) < 8) {
    // Chris Wellon's lowbias32, from https://nullprogram.com/blog/2018/07/31/.
    x ^= x >> 16;
    x *= 0x7feb352dU;
    x ^= x >> 15;
    x *= 0x846ca68bU;
    x ^= x >> 16;
    return x;
  } else {
    // Sebastiano Vigna's splitmix64 integer mixer, from
    // https://prng.di.unimi.it/splitmix64.c.
    x ^= x >> 30;
    x *= 0xbf58476d1ce4e5b9U;
    x ^= x >> 27;
    x *= 0x94d049bb133111ebU;
    x ^= x >> 31;
    return x;
  }
}
// Inverse of hash_address from https://nullprogram.com/blog/2018/07/31/.
static uintptr_t unhash_address(uintptr_t x) {
  if (sizeof (x) < 8) {
    x ^= x >> 16;
    x *= 0x43021123U;
    x ^= x >> 15 ^ x >> 30;
    x *= 0x1d69e2a5U;
    x ^= x >> 16;
    return x;
  } else {
    x ^= x >> 31 ^ x >> 62;
    x *= 0x319642b2d24d8ec3U;
    x ^= x >> 27 ^ x >> 54;
    x *= 0x96de1b173f119089U;
    x ^= x >> 30 ^ x >> 60;
    return x;
  }
}

#endif // ADDRESS_HASH_H