diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-04-12 12:01:51 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-04-12 12:01:51 +0000 |
commit | 16a2acca20c3ddc0454331df4c6a0cd2a8a0807c (patch) | |
tree | 062957e8ec2437e353f2919ceb7dd03461da8efb /bignum.c | |
parent | 3da834800e40980d7a75b82cc1a3b1abd9539e99 (diff) | |
download | ruby-16a2acca20c3ddc0454331df4c6a0cd2a8a0807c.tar.gz |
* bignum.c (ones): Use __builtin_popcountl if available.
* internal.h (GCC_VERSION_SINCE): Macro moved from pack.c.
* pack.c: Include internal.h for GCC_VERSION_SINCE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r-- | bignum.c | 30 |
1 files changed, 17 insertions, 13 deletions
@@ -887,27 +887,31 @@ static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *mo static inline int ones(register unsigned long x) { -#if SIZEOF_LONG == 8 -# define MASK_55 0x5555555555555555UL -# define MASK_33 0x3333333333333333UL -# define MASK_0f 0x0f0f0f0f0f0f0f0fUL +#if GCC_VERSION_SINCE(3, 4, 0) + return __builtin_popcountl(x); #else -# define MASK_55 0x55555555UL -# define MASK_33 0x33333333UL -# define MASK_0f 0x0f0f0f0fUL -#endif +# if SIZEOF_LONG == 8 +# define MASK_55 0x5555555555555555UL +# define MASK_33 0x3333333333333333UL +# define MASK_0f 0x0f0f0f0f0f0f0f0fUL +# else +# define MASK_55 0x55555555UL +# define MASK_33 0x33333333UL +# define MASK_0f 0x0f0f0f0fUL +# endif x -= (x >> 1) & MASK_55; x = ((x >> 2) & MASK_33) + (x & MASK_33); x = ((x >> 4) + x) & MASK_0f; x += (x >> 8); x += (x >> 16); -#if SIZEOF_LONG == 8 +# if SIZEOF_LONG == 8 x += (x >> 32); -#endif +# endif return (int)(x & 0x7f); -#undef MASK_0f -#undef MASK_33 -#undef MASK_55 +# undef MASK_0f +# undef MASK_33 +# undef MASK_55 +#endif } static inline unsigned long |