From 3d98741fa1bacf02f7fa74b477c1b9741e98d027 Mon Sep 17 00:00:00 2001 From: Marcus Comstedt <marcus@mc.pp.se> Date: Sat, 30 May 2020 16:21:15 +0200 Subject: [PATCH] CritBit: Fix FloatTree with 128bit floats --- src/bitvector.h | 17 +++++++++++++++++ src/post_modules/CritBit/critbit/key_float.h | 11 +++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/bitvector.h b/src/bitvector.h index c53fba1449..30763bf3e0 100644 --- a/src/bitvector.h +++ b/src/bitvector.h @@ -165,6 +165,23 @@ static INLINE unsigned INT64 ATTRIBUTE((unused)) bswap64(unsigned INT64 x) { } #endif /* !HAVE___BSWAP64 && !HAVE_BSWAP64 */ +#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16 +/** + * Counts the number of leading zeros in a 128-bit unsigned + * integer. Returns a value between 0 and 128. + */ +static INLINE unsigned INT32 PIKE_UNUSED_ATTRIBUTE clz128(unsigned __int128 i) { +# if SIZEOF_LONG == 16 && defined(HAS___BUILTIN_CLZL) + return i ? __builtin_clzl(i) : 128; +# elif SIZEOF_LONG_LONG == 16 && defined(HAS___BUILTIN_CLZLL) + return i ? __builtin_clzll(i) : 128; +# else + unsigned INT64 hi = i >> 64; + return hi? clz64(hi) : 64 + clz64((unsigned INT64)i); +# endif +} +#endif /* __SIZEOF_INT128__ */ + static INLINE unsigned INT64 PIKE_UNUSED_ATTRIBUTE round_up64(unsigned INT64 v) { unsigned INT32 i; diff --git a/src/post_modules/CritBit/critbit/key_float.h b/src/post_modules/CritBit/critbit/key_float.h index 8eee37d159..3dd40f73ae 100644 --- a/src/post_modules/CritBit/critbit/key_float.h +++ b/src/post_modules/CritBit/critbit/key_float.h @@ -7,9 +7,14 @@ #if SIZEOF_FLOAT_TYPE == 8 typedef unsigned INT64 CB_NAME(string); typedef unsigned INT64 CB_NAME(char); -#else +#elif SIZEOF_FLOAT_TYPE == 4 typedef unsigned INT32 CB_NAME(string); typedef unsigned INT32 CB_NAME(char); +#elif SIZEOF_FLOAT_TYPE == 16 && defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16 +typedef unsigned __int128 CB_NAME(string); +typedef unsigned __int128 CB_NAME(char); +#else +#error Size of FLOAT_TYPE not supported. #endif @@ -26,8 +31,10 @@ typedef unsigned INT32 CB_NAME(char); #ifdef CB_SOURCE #if SIZEOF_FLOAT_TYPE == 4 # define gclz(x) clz32(x) -#else +#elif SIZEOF_FLOAT_TYPE == 8 # define gclz(x) clz64(x) +#else +# define gclz(x) clz128(x) #endif #define bitsof(x) (sizeof(x)*8) #define int2float(x) (*(FLOAT_TYPE*)&(x)) -- GitLab