Marc:
I found a few more problems---in FIXLENGTH you want to set ___temp to -___temp (not ~temp) when ___temp is negative (try (fxlength -1)), and you needed to ___FIX(___temp&0xff) in 64-bit ___BITCOUNT_TEMP..
I imagine that using some configurey to use gcc's __builtin_popcountl, __builtin_ffsl, and __builtin_clzl when available would speed up these functions in some special cases.
This has been rather extensively tested on 32-bit (ppc) and 64-bit (x86-64) platforms by comparing it with the R6RS definitions of the same functions. The diff is from the original gambit.h.
Brad
[brad:~/programs/gambc-4.0b18/include] lucier% rcsdiff -r1.1 gambit.h =================================================================== RCS file: RCS/gambit.h,v retrieving revision 1.1 diff -r1.1 gambit.h 2548,2551c2548,2613 < #define ___FIXBITCOUNT(x)___FIX(1111)/****brad will fix this****/ < #define ___FIXLENGTH(x)___FIX(2222)/****brad will fix this****/ < #define ___FIXFIRSTBITSET(x)___FIX(3333)/****brad will fix this****/ < #define ___FIXBITSETP(x,y)((x)&(1<<(___INT(y)+___TB))) ---
#if ___SCMOBJ_WIDTH == 32 #define ___SCMOBJ_MASK(x,y)y #define ___BITCOUNT_TEMP() \ (___temp=(___temp&___SCMOBJ_MASK(0x55555555,0x55555555))+ \ ((___temp>>1)&___SCMOBJ_MASK(0x55555555,0x55555555)), \ ___temp=(___temp&___SCMOBJ_MASK(0x33333333,0x33333333))+ \ ((___temp>>2)&___SCMOBJ_MASK(0x33333333,0x33333333)), \ ___temp=(___temp&___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f))+ \ ((___temp>>4)&___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f)), \ ___temp=___temp+(___temp>>8), \ ___temp=___temp+(___temp>>16), \ ___FIX(___temp&0xff)) #define ___FIXLENGTH(x) \ (((___temp=___INT(x))<0)&&(___temp=-___temp), \ ___temp|=(___temp>>1), \ ___temp|=(___temp>>2), \ ___temp|=(___temp>>4), \ ___temp|=(___temp>>8), \ ___temp|=(___temp>>16), \ ___BITCOUNT_TEMP()) #define ___FIXFIRSTBITSET(x) \ (((___temp=(x))==0) \ ?___FIX(-1) \ :(___temp=(___temp&-___temp), \ ___FIX((((___temp&~___SCMOBJ_MASK(0x55555555,0x55555555))!=0)| \ (((___temp&~___SCMOBJ_MASK(0x33333333,0x33333333))!=0)
<<1)| \
(((___temp&~___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f))!=0)
<<2)| \
(((___temp&~___SCMOBJ_MASK(0x00ff00ff,0x00ff00ff))!=0)
<<3)| \
(((___temp&~___SCMOBJ_MASK(0x0000ffff,0x0000ffff))!=0)
<<4))-___TB)))
#else #define ___SCMOBJ_MASK(x,y)((___CAST(___SCMOBJ,x)<<32)|y) #define ___BITCOUNT_TEMP() \ (___temp=((___temp)&___SCMOBJ_MASK(0x55555555,0x55555555))+ \ (((___temp)>>1)&___SCMOBJ_MASK(0x55555555,0x55555555)), \ ___temp=(___temp&___SCMOBJ_MASK(0x33333333,0x33333333))+ \ ((___temp>>2)&___SCMOBJ_MASK(0x33333333,0x33333333)), \ ___temp=(___temp&___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f))+ \ ((___temp>>4)&___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f)), \ ___temp=___temp+(___temp>>8), \ ___temp=___temp+(___temp>>16), \ ___temp=___temp+(___temp>>32), \ ___FIX(___temp&0xff)) #define ___FIXLENGTH(x) \ (((___temp=___INT(x))<0)&&(___temp=-___temp), \ ___temp|=(___temp>>1), \ ___temp|=(___temp>>2), \ ___temp|=(___temp>>4), \ ___temp|=(___temp>>8), \ ___temp|=(___temp>>16), \ ___temp|=(___temp>>32), \ ___BITCOUNT_TEMP()) #define ___FIXFIRSTBITSET(x) \ (((___temp=(x))==0) \ ?___FIX(-1) \ :(___temp=(___temp&-___temp), \ ___FIX((((___temp&~___SCMOBJ_MASK(0x55555555,0x55555555))!=0)| \ (((___temp&~___SCMOBJ_MASK(0x33333333,0x33333333))!=0)
<<1)| \
(((___temp&~___SCMOBJ_MASK(0x0f0f0f0f,0x0f0f0f0f))!=0)
<<2)| \
(((___temp&~___SCMOBJ_MASK(0x00ff00ff,0x00ff00ff))!=0)
<<3)| \
(((___temp&~___SCMOBJ_MASK(0x0000ffff,0x0000ffff))!=0)
<<4)| \
(((___temp&~___SCMOBJ_MASK(0x00000000,0xffffffff))!=0)
<<5))-___TB)))
#endif #define ___FIXBITCOUNT(x) \ ((((___temp=___INT(x))<0)&&(___temp=~___temp)),___BITCOUNT_TEMP()) #define ___FIXBITSETP(x,y)((x)&(___CAST(___SCMOBJ,1)<<(___INT(y)
+___TB)))