~ 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