From 16a2acca20c3ddc0454331df4c6a0cd2a8a0807c Mon Sep 17 00:00:00 2001 From: akr Date: Fri, 12 Apr 2013 12:01:51 +0000 Subject: * 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 --- ChangeLog | 8 ++++++++ bignum.c | 30 +++++++++++++++++------------- internal.h | 6 ++++++ pack.c | 7 +------ 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 66b5029b92..e78debfce3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Fri Apr 12 20:59:24 2013 Tanaka Akira + + * 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. + Fri Apr 12 18:29:42 2013 Tanaka Akira * common.mk: version.o depends on $(srcdir)/include/ruby/version.h diff --git a/bignum.c b/bignum.c index 6236ff32f7..306231c0df 100644 --- a/bignum.c +++ b/bignum.c @@ -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 diff --git a/internal.h b/internal.h index 964f8a3467..90388533dc 100644 --- a/internal.h +++ b/internal.h @@ -19,6 +19,12 @@ extern "C" { #endif #endif +#define GCC_VERSION_SINCE(major, minor, patchlevel) \ + (defined(__GNUC__) && !defined(__INTEL_COMPILER) && \ + ((__GNUC__ > (major)) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \ + (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel)))) + #if SIGNEDNESS_OF_TIME_T < 0 /* signed */ # define TIMET_MAX (time_t)((~(unsigned_time_t)0) >> 1) # define TIMET_MIN (time_t)(((unsigned_time_t)1) << (sizeof(time_t) * CHAR_BIT - 1)) diff --git a/pack.c b/pack.c index 7a12cfcf24..fb6472c809 100644 --- a/pack.c +++ b/pack.c @@ -11,16 +11,11 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" +#include "internal.h" #include #include #include -#define GCC_VERSION_SINCE(major, minor, patchlevel) \ - (defined(__GNUC__) && !defined(__INTEL_COMPILER) && \ - ((__GNUC__ > (major)) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \ - (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel)))) - /* * It is intentional that the condition for natstr is HAVE_TRUE_LONG_LONG * instead of HAVE_LONG_LONG or LONG_LONG. -- cgit v1.2.3