summaryrefslogtreecommitdiff
path: root/libguile/whippet/src/address-hash.h
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/whippet/src/address-hash.h')
-rw-r--r--libguile/whippet/src/address-hash.h45
1 files changed, 45 insertions, 0 deletions
diff --git a/libguile/whippet/src/address-hash.h b/libguile/whippet/src/address-hash.h
new file mode 100644
index 000000000..49c33be97
--- /dev/null
+++ b/libguile/whippet/src/address-hash.h
@@ -0,0 +1,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