aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_hashmap.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2015-01-21 16:08:17 +0100
committerBjörn-Egil Dahlberg <[email protected]>2015-03-12 19:15:25 +0100
commit0d10df770cfd1407bb79c31da34108dda1b868a5 (patch)
treefc928d9ef3e768a98e691734c531dc9b3f1bf68c /erts/emulator/beam/erl_hashmap.c
parent3cdd2d25859275fd0bc2111c52a8bbd2505ff048 (diff)
downloadotp-0d10df770cfd1407bb79c31da34108dda1b868a5.tar.gz
otp-0d10df770cfd1407bb79c31da34108dda1b868a5.tar.bz2
otp-0d10df770cfd1407bb79c31da34108dda1b868a5.zip
erts: Add fallback for builtin clz
* __builtin_clz may not exist * fix bitcount fallback
Diffstat (limited to 'erts/emulator/beam/erl_hashmap.c')
-rw-r--r--erts/emulator/beam/erl_hashmap.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_hashmap.c b/erts/emulator/beam/erl_hashmap.c
index 6bca2f1665..3da2a53333 100644
--- a/erts/emulator/beam/erl_hashmap.c
+++ b/erts/emulator/beam/erl_hashmap.c
@@ -1273,3 +1273,30 @@ BIF_RETTYPE hashmap_info_1(BIF_ALIST_1) {
}
BIF_ERROR(BIF_P, BADARG);
}
+
+/* implementation of builtin emulations */
+
+#if !defined(__GNUC__)
+/* Count leading zeros emulation */
+Uint32 hashmap_clz(Uint32 x) {
+ Uint32 y;
+ int n = 32;
+ y = x >>16; if (y != 0) {n = n -16; x = y;}
+ y = x >> 8; if (y != 0) {n = n - 8; x = y;}
+ y = x >> 4; if (y != 0) {n = n - 4; x = y;}
+ y = x >> 2; if (y != 0) {n = n - 2; x = y;}
+ y = x >> 1; if (y != 0) return n - 2;
+ return n - x;
+}
+const Uint32 SK5 = 0x55555555, SK3 = 0x33333333;
+const Uint32 SKF0 = 0xF0F0F0F, SKFF = 0xFF00FF;
+
+/* CTPOP emulation */
+Uint32 hashmap_bitcount(Uint32 x) {
+ x -= ((x >> 1 ) & SK5);
+ x = (x & SK3 ) + ((x >> 2 ) & SK3 );
+ x = (x & SKF0) + ((x >> 4 ) & SKF0);
+ x += x >> 8;
+ return (x + (x >> 16)) & 0x3F;
+}
+#endif