diff options
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 179 |
1 files changed, 44 insertions, 135 deletions
diff --git a/src/data.c b/src/data.c index a6bfe50a3bb..4ef326e4cfd 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -22,6 +22,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | #include <stdio.h> | 22 | #include <stdio.h> |
| 23 | 23 | ||
| 24 | #include <byteswap.h> | 24 | #include <byteswap.h> |
| 25 | #include <count-one-bits.h> | ||
| 26 | #include <count-trailing-zeros.h> | ||
| 25 | #include <intprops.h> | 27 | #include <intprops.h> |
| 26 | 28 | ||
| 27 | #include "lisp.h" | 29 | #include "lisp.h" |
| @@ -2971,108 +2973,16 @@ bool_vector_spare_mask (ptrdiff_t nr_bits) | |||
| 2971 | return (((size_t) 1) << (nr_bits % BITS_PER_SIZE_T)) - 1; | 2973 | return (((size_t) 1) << (nr_bits % BITS_PER_SIZE_T)) - 1; |
| 2972 | } | 2974 | } |
| 2973 | 2975 | ||
| 2974 | #if _MSC_VER >= 1500 && (defined _M_IX86 || defined _M_X64) | 2976 | #if SIZE_MAX <= UINT_MAX |
| 2975 | # define USE_MSC_POPCOUNT | 2977 | # define popcount_size_t count_one_bits |
| 2976 | # define POPCOUNT_STATIC_INLINE static inline | 2978 | #elif SIZE_MAX <= ULONG_MAX |
| 2977 | #elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) | 2979 | # define popcount_size_t count_one_bits_l |
| 2978 | # define USE_GCC_POPCOUNT | 2980 | #elif SIZE_MAX <= ULLONG_MAX |
| 2979 | # if 199901L <= __STDC_VERSION__ || !__STRICT_ANSI__ | 2981 | # define popcount_size_t count_one_bits_ll |
| 2980 | # define POPCOUNT_STATIC_INLINE static inline | ||
| 2981 | # endif | ||
| 2982 | #else | 2982 | #else |
| 2983 | # define NEED_GENERIC_POPCOUNT | 2983 | # error "size_t wider than long long? Please file a bug report." |
| 2984 | #endif | ||
| 2985 | #ifndef POPCOUNT_STATIC_INLINE | ||
| 2986 | # define POPCOUNT_STATIC_INLINE static | ||
| 2987 | #endif | ||
| 2988 | |||
| 2989 | #ifdef USE_MSC_POPCOUNT | ||
| 2990 | # define NEED_GENERIC_POPCOUNT | ||
| 2991 | #endif | ||
| 2992 | |||
| 2993 | #ifdef NEED_GENERIC_POPCOUNT | ||
| 2994 | POPCOUNT_STATIC_INLINE unsigned int | ||
| 2995 | popcount_size_t_generic (size_t val) | ||
| 2996 | { | ||
| 2997 | unsigned short j; | ||
| 2998 | unsigned int count = 0; | ||
| 2999 | |||
| 3000 | for (j = 0; j < BITS_PER_SIZE_T; ++j) | ||
| 3001 | count += !!((((size_t) 1) << j) & val); | ||
| 3002 | |||
| 3003 | return count; | ||
| 3004 | } | ||
| 3005 | #endif | 2984 | #endif |
| 3006 | 2985 | ||
| 3007 | #ifdef USE_MSC_POPCOUNT | ||
| 3008 | POPCOUNT_STATIC_INLINE unsigned int | ||
| 3009 | popcount_size_t_msc (size_t val) | ||
| 3010 | { | ||
| 3011 | unsigned int count; | ||
| 3012 | |||
| 3013 | #pragma intrinsic __cpuid | ||
| 3014 | /* While gcc falls back to its own generic code if the machine on | ||
| 3015 | which it's running doesn't support popcount, we need to perform the | ||
| 3016 | detection and fallback ourselves when compiling with Microsoft's | ||
| 3017 | compiler. */ | ||
| 3018 | |||
| 3019 | static enum { | ||
| 3020 | popcount_unknown_support, | ||
| 3021 | popcount_use_generic, | ||
| 3022 | popcount_use_intrinsic | ||
| 3023 | } popcount_state; | ||
| 3024 | |||
| 3025 | if (popcount_state == popcount_unknown_support) | ||
| 3026 | { | ||
| 3027 | int cpu_info[4]; | ||
| 3028 | __cpuid (cpu_info, 1); | ||
| 3029 | if (cpu_info[2] & (1<<23)) /* See MSDN. */ | ||
| 3030 | popcount_state = popcount_use_intrinsic; | ||
| 3031 | else | ||
| 3032 | popcount_state = popcount_use_generic; | ||
| 3033 | } | ||
| 3034 | |||
| 3035 | if (popcount_state == popcount_use_intrinsic) | ||
| 3036 | { | ||
| 3037 | # if BITS_PER_SIZE_T == 64 | ||
| 3038 | # pragma intrinsic __popcnt64 | ||
| 3039 | count = __popcnt64 (val); | ||
| 3040 | # else | ||
| 3041 | # pragma intrinsic __popcnt | ||
| 3042 | count = __popcnt (val); | ||
| 3043 | # endif | ||
| 3044 | } | ||
| 3045 | else | ||
| 3046 | count = popcount_size_t_generic (val); | ||
| 3047 | |||
| 3048 | return count; | ||
| 3049 | } | ||
| 3050 | #endif /* USE_MSC_POPCOUNT */ | ||
| 3051 | |||
| 3052 | #ifdef USE_GCC_POPCOUNT | ||
| 3053 | POPCOUNT_STATIC_INLINE unsigned int | ||
| 3054 | popcount_size_t_gcc (size_t val) | ||
| 3055 | { | ||
| 3056 | # if BITS_PER_SIZE_T == 64 | ||
| 3057 | return __builtin_popcountll (val); | ||
| 3058 | # else | ||
| 3059 | return __builtin_popcount (val); | ||
| 3060 | # endif | ||
| 3061 | } | ||
| 3062 | #endif /* USE_GCC_POPCOUNT */ | ||
| 3063 | |||
| 3064 | POPCOUNT_STATIC_INLINE unsigned int | ||
| 3065 | popcount_size_t (size_t val) | ||
| 3066 | { | ||
| 3067 | #if defined USE_MSC_POPCOUNT | ||
| 3068 | return popcount_size_t_msc (val); | ||
| 3069 | #elif defined USE_GCC_POPCOUNT | ||
| 3070 | return popcount_size_t_gcc (val); | ||
| 3071 | #else | ||
| 3072 | return popcount_size_t_generic (val); | ||
| 3073 | #endif | ||
| 3074 | } | ||
| 3075 | |||
| 3076 | enum bool_vector_op { bool_vector_exclusive_or, | 2986 | enum bool_vector_op { bool_vector_exclusive_or, |
| 3077 | bool_vector_union, | 2987 | bool_vector_union, |
| 3078 | bool_vector_intersection, | 2988 | bool_vector_intersection, |
| @@ -3143,55 +3053,54 @@ bool_vector_binop_driver (Lisp_Object op1, | |||
| 3143 | 3053 | ||
| 3144 | /* Compute the number of trailing zero bits in val. If val is zero, | 3054 | /* Compute the number of trailing zero bits in val. If val is zero, |
| 3145 | return the number of bits in val. */ | 3055 | return the number of bits in val. */ |
| 3146 | static unsigned int | 3056 | static int |
| 3147 | count_trailing_zero_bits (size_t val) | 3057 | count_trailing_zero_bits (size_t val) |
| 3148 | { | 3058 | { |
| 3059 | if (SIZE_MAX == UINT_MAX) | ||
| 3060 | return count_trailing_zeros (val); | ||
| 3061 | if (SIZE_MAX == ULONG_MAX) | ||
| 3062 | return count_trailing_zeros_l (val); | ||
| 3063 | # if HAVE_UNSIGNED_LONG_LONG_INT | ||
| 3064 | if (SIZE_MAX == ULLONG_MAX) | ||
| 3065 | return count_trailing_zeros_ll (val); | ||
| 3066 | # endif | ||
| 3067 | |||
| 3068 | /* The rest of this code is for the unlikely platform where size_t differs | ||
| 3069 | in width from unsigned int, unsigned long, and unsigned long long. */ | ||
| 3149 | if (val == 0) | 3070 | if (val == 0) |
| 3150 | return CHAR_BIT * sizeof (val); | 3071 | return CHAR_BIT * sizeof (val); |
| 3151 | 3072 | if (SIZE_MAX <= UINT_MAX) | |
| 3152 | #if defined USE_GCC_POPCOUNT && BITS_PER_SIZE_T == 64 | 3073 | return count_trailing_zeros (val); |
| 3153 | return __builtin_ctzll (val); | 3074 | if (SIZE_MAX <= ULONG_MAX) |
| 3154 | #elif defined USE_GCC_POPCOUNT && BITS_PER_SIZE_T == 32 | 3075 | return count_trailing_zeros_l (val); |
| 3155 | return __builtin_ctz (val); | ||
| 3156 | #elif _MSC_VER && BITS_PER_SIZE_T == 64 | ||
| 3157 | # pragma intrinsic _BitScanForward64 | ||
| 3158 | { | 3076 | { |
| 3159 | /* No support test needed: support since 386. */ | 3077 | # if HAVE_UNSIGNED_LONG_LONG_INT |
| 3160 | unsigned long result; | 3078 | verify (SIZE_MAX <= ULLONG_MAX); |
| 3161 | _BitScanForward64 (&result, val); | 3079 | return count_trailing_zeros_ll (val); |
| 3162 | return (unsigned int) result; | 3080 | # else |
| 3163 | } | 3081 | verify (SIZE_MAX <= ULONG_MAX); |
| 3164 | #elif _MSC_VER && BITS_PER_SIZE_T == 32 | 3082 | # endif |
| 3165 | # pragma intrinsic _BitScanForward | ||
| 3166 | { | ||
| 3167 | /* No support test needed: support since 386. */ | ||
| 3168 | unsigned long result; | ||
| 3169 | _BitScanForward (&result, val); | ||
| 3170 | return (unsigned int) result; | ||
| 3171 | } | ||
| 3172 | #else | ||
| 3173 | { | ||
| 3174 | unsigned int count; | ||
| 3175 | count = 0; | ||
| 3176 | for (val = ~val; val & 1; val >>= 1) | ||
| 3177 | ++count; | ||
| 3178 | |||
| 3179 | return count; | ||
| 3180 | } | 3083 | } |
| 3181 | #endif | ||
| 3182 | } | 3084 | } |
| 3183 | 3085 | ||
| 3184 | static size_t | 3086 | static size_t |
| 3185 | size_t_to_host_endian (size_t val) | 3087 | size_t_to_host_endian (size_t val) |
| 3186 | { | 3088 | { |
| 3187 | #ifdef WORDS_BIGENDIAN | 3089 | #ifndef WORDS_BIGENDIAN |
| 3188 | # if BITS_PER_SIZE_T == 64 | 3090 | return val; |
| 3189 | return bswap_64 (val); | 3091 | #elif SIZE_MAX >> 31 == 1 |
| 3190 | # else | ||
| 3191 | return bswap_32 (val); | 3092 | return bswap_32 (val); |
| 3192 | # endif | 3093 | #elif SIZE_MAX >> 31 >> 31 >> 1 == 1 |
| 3094 | return bswap_64 (val); | ||
| 3193 | #else | 3095 | #else |
| 3194 | return val; | 3096 | int i; |
| 3097 | size_t r = 0; | ||
| 3098 | for (i = 0; i < sizeof val; i++) | ||
| 3099 | { | ||
| 3100 | r = (r << CHAR_BIT) | (val & ((1u << CHAR_BIT) - 1)); | ||
| 3101 | val >>= CHAR_BIT; | ||
| 3102 | } | ||
| 3103 | return r; | ||
| 3195 | #endif | 3104 | #endif |
| 3196 | } | 3105 | } |
| 3197 | 3106 | ||