~ chicken-core (chicken-5) 1184e6a5ac4a7994be93c415b72b431657d7a877
commit 1184e6a5ac4a7994be93c415b72b431657d7a877 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Mon Nov 20 13:19:38 2017 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Mon Nov 20 13:19:38 2017 +0100 added clz64 implementation for non-GCC compilers diff --git a/runtime.c b/runtime.c index 3088a8b3..877fa822 100644 --- a/runtime.c +++ b/runtime.c @@ -12710,7 +12710,33 @@ C_s_a_u_i_random_int(C_word **ptr, C_word n, C_word rn) #else # define random64() ((((C_u64) random_word()) << 32) | ((C_u64) random_word())) #endif -#define clz64 __builtin_clzll /* XXX GCCism */ + +#ifdef __GNUC__ +# define clz64 __builtin_clzll +#else +/* https://en.wikipedia.org/wiki/Find_first_set#CLZ */ +static const C_uchar clz_table_4bit[16] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + +int clz32(C_u32 x) +{ + int n; + if ((x & 0xFFFF0000) == 0) {n = 16; x <<= 16;} else {n = 0;} + if ((x & 0xFF000000) == 0) {n += 8; x <<= 8;} + if ((x & 0xF0000000) == 0) {n += 4; x <<= 4;} + n += (int)clz_table_4bit[x >> (32-4)]; + return n; +} + +int clz64(C_u64 x) +{ + int y = clz32(x >> 32); + + if(y == 32) return y + clz32(x); + + return y; +} +#endif + C_regparm C_word C_fcall C_a_i_random_real(C_word **ptr, C_word n) { int exponent = -64;Trap