From 0d10df770cfd1407bb79c31da34108dda1b868a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 21 Jan 2015 16:08:17 +0100 Subject: erts: Add fallback for builtin clz * __builtin_clz may not exist * fix bitcount fallback --- erts/emulator/beam/erl_hashmap.c | 27 +++++++++++++++++++++++++++ erts/emulator/beam/erl_hashmap.h | 17 ++++------------- 2 files changed, 31 insertions(+), 13 deletions(-) (limited to 'erts/emulator/beam') 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 diff --git a/erts/emulator/beam/erl_hashmap.h b/erts/emulator/beam/erl_hashmap.h index 8ba249b053..1964787218 100644 --- a/erts/emulator/beam/erl_hashmap.h +++ b/erts/emulator/beam/erl_hashmap.h @@ -40,21 +40,12 @@ int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp); /* HASH */ - #if defined(__GNUC__) -#define hashmap_bitcount(x) (Uint32) __builtin_popcount((unsigned int) (x)) +#define hashmap_clz(x) ((Uint32) __builtin_clz((unsigned int)(x))) +#define hashmap_bitcount(x) ((Uint32) __builtin_popcount((unsigned int) (x))) #else -const Uint32 SK5 = 0x55555555, SK3 = 0x33333333; -const Uint32 SKF0 = 0xF0F0F0F, SKFF = 0xFF00FF; - -/* CTPOP emulation */ -Uint32 hashmap_bitcount(Uint32 map) { - map -= (( map >> 1 ) & SK5 ); - map = ( map & SK3 ) + (( map >> 2 ) & SK3 ); - map = ( map & SKF0 ) + (( map >> 4 ) & SKF0); - map += map >> 8; - return ( map + ( map >> 16)) & 0x3F; -} +Uint32 hashmap_clz(Uint32 x); +Uint32 hashmap_bitcount(Uint32 x); #endif /* hamt nodes v2.0 -- cgit v1.2.3