diff --git a/boot/pb/scheme.h b/boot/pb/scheme.h index b8ae62c3f..a00c05858 100644 --- a/boot/pb/scheme.h +++ b/boot/pb/scheme.h @@ -140,6 +140,22 @@ typedef unsigned char octet; #define Sstring_length(x) ((iptr)((uptr)(*((iptr *)TO_VOIDP((uptr)(x)+1)))>>4)) #define Sstring_ref(x,i) Schar_value(((string_char *)TO_VOIDP((uptr)(x)+9))[i]) #define Sunbox(x) (*((ptr *)TO_VOIDP((uptr)(x)+9))) +static inline int Spopcount(uptr x) { +#if defined(__clang__) || defined(__GNUC__) + return __builtin_popcountll((unsigned long)x); +#else + /* count bits of each 2-bit chunk */ + x = x - ((x >> 1) & 0x5555555555555555ULL); + /* count bits of each 4-bit chunk */ + x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL); + /* count bits of each 8-bit chunk */ + x = x + (x >> 4); + /* mask out junk */ + x &= 0x0F0F0F0F0F0F0F0FULL; + /* add all 8-bit chunks */ + return (x * 0x0101010101010101ULL) >> 56; +#endif +} #define Sstencil_vector_length(x) Spopcount(((uptr)(*((iptr *)TO_VOIDP((uptr)(x)+1))))>>6) #define Sstencil_vector_ref(x,i) (((ptr *)TO_VOIDP((uptr)(x)+9))[i]) EXPORT iptr Sinteger_value(ptr); diff --git a/c/alloc.c b/c/alloc.c index baf4bcc6b..23bb80b02 100644 --- a/c/alloc.c +++ b/c/alloc.c @@ -15,7 +15,6 @@ */ #include "system.h" -#include "popcount.h" /* locally defined functions */ static void maybe_queue_fire_collector(thread_gc *tgc); diff --git a/c/build.zuo b/c/build.zuo index 34df04987..dde5b3b6b 100644 --- a/c/build.zuo +++ b/c/build.zuo @@ -119,7 +119,7 @@ (map at-source (list "system.h" "types.h" "version.h" "globals.h" "externs.h" "segment.h" "atomic.h" "thread.h" "sort.h" "compress-io.h" - "nocurses.h" "popcount.h")) + "nocurses.h")) (list c-config-file) (map at-mach (list "equates.h" diff --git a/c/fasl.c b/c/fasl.c index d6d8d972a..96b2915b6 100644 --- a/c/fasl.c +++ b/c/fasl.c @@ -195,7 +195,6 @@ #include "system.h" #include "zlib.h" -#include "popcount.h" #ifdef WIN32 #include diff --git a/c/gc.c b/c/gc.c index 4906e4a75..905e2e35e 100644 --- a/c/gc.c +++ b/c/gc.c @@ -18,7 +18,6 @@ #ifndef WIN32 #include #endif /* WIN32 */ -#include "popcount.h" #include /* diff --git a/c/gcwrapper.c b/c/gcwrapper.c index 1b4b42096..8d53d9767 100644 --- a/c/gcwrapper.c +++ b/c/gcwrapper.c @@ -15,7 +15,6 @@ */ #include "system.h" -#include "popcount.h" /* locally defined functions */ static void segment_tell(uptr seg); diff --git a/c/popcount.h b/c/popcount.h deleted file mode 100644 index 134b6b368..000000000 --- a/c/popcount.h +++ /dev/null @@ -1,35 +0,0 @@ - -#if __GNUC__ >= 5 -static int Spopcount_32(U32 x) -{ - return __builtin_popcount(x); -} -#else -static int Spopcount_32(U32 x) -{ - /* http://bits.stephan-brumme.com/countBits.html */ - /* count bits of each 2-bit chunk */ - x = x - ((x >> 1) & 0x55555555); - /* count bits of each 4-bit chunk */ - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - /* count bits of each 8-bit chunk */ - x = x + (x >> 4); - /* mask out junk */ - x &= 0xF0F0F0F; - /* add all four 8-bit chunks */ - return (x * 0x01010101) >> 24; -} -#endif - -#if ptr_bits == 32 -static int Spopcount(uptr x) -{ - return Spopcount_32((U32)x); -} -#elif ptr_bits == 64 -static int Spopcount(uptr x) -{ - return Spopcount_32((U32)(x & 0xFFFFFFFF)) + Spopcount_32((U32)(x >> 32)); -} -#endif - diff --git a/release_notes/release_notes.stex b/release_notes/release_notes.stex index 7980eb7cb..57dd3668e 100644 --- a/release_notes/release_notes.stex +++ b/release_notes/release_notes.stex @@ -2987,6 +2987,12 @@ in fasl files does not generally make sense. %----------------------------------------------------------------------------- \section{Bug Fixes}\label{section:bugfixes} + +\subsection{Declare \scheme{Spopcount} in scheme.h (10.4.0)} + +A bug where the header file scheme.h refers to an undeclared \scheme{Spopcount} function +has been fixed. + \subsection{Eager port closing on error in \scheme{open-source-file} (10.4.0)} When \scheme{open-source-file} fails on a non-seekable device, the file descriptor port diff --git a/s/mkheader.ss b/s/mkheader.ss index 214611a27..8ee98002b 100644 --- a/s/mkheader.ss +++ b/s/mkheader.ss @@ -339,7 +339,30 @@ (format "Schar_value~a" (access "x" "i" string data))) (defref Sunbox box ref) - + + (let-values + ([(suffix fives threes junk-mask ones shift) + (constant-case ptr-bits + [(32) (values "l" "0x55555555" "0x33333333" "0xF0F0F0F" "0x01010101" 24)] + [(64) (values "ll" "0x5555555555555555ULL" "0x3333333333333333ULL" + "0x0F0F0F0F0F0F0F0FULL" "0x0101010101010101ULL" 56)])]) + (pr "static inline int Spopcount(uptr x) {\n") + (pr "#if defined(__clang__) || defined(__GNUC__)\n") + (pr " return __builtin_popcount~a((unsigned long)x);\n" suffix) + (pr "#else\n") + (pr " /* count bits of each 2-bit chunk */\n") + (pr " x = x - ((x >> 1) & ~a);\n" fives) + (pr " /* count bits of each 4-bit chunk */\n") + (pr " x = (x & ~a) + ((x >> 2) & ~a);\n" threes threes) + (pr " /* count bits of each 8-bit chunk */\n") + (pr " x = x + (x >> 4);\n") + (pr " /* mask out junk */\n") + (pr " x &= ~a;\n" junk-mask) + (pr " /* add all 8-bit chunks */\n") + (pr " return (x * ~a) >> ~d;\n" ones shift) + (pr "#endif\n") + (pr "}\n")) + (def "Sstencil_vector_length(x)" (format "Spopcount(((uptr)~a)>>~d)" (access "x" stencil-vector type)