annotate lib/count-leading-zeros.h @ 17255:d81be792518a

update from texinfo
author Karl Berry <karl@freefriends.org>
date Tue, 01 Jan 2013 15:51:49 -0800
parents e542fd46ad6f
children 1f9070ef79b0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
1 /* count-leading-zeros.h -- counts the number of leading 0 bits in a word.
17249
e542fd46ad6f maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents: 17166
diff changeset
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
3
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
4 This program is free software: you can redistribute it and/or modify
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
6 the Free Software Foundation; either version 3 of the License, or
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
7 (at your option) any later version.
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
8
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
9 This program is distributed in the hope that it will be useful,
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
12 GNU General Public License for more details.
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
13
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
16
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
17 /* Written by Eric Blake. */
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
18
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
19 #ifndef COUNT_LEADING_ZEROS_H
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
20 # define COUNT_LEADING_ZEROS_H 1
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
21
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
22 #include <limits.h>
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
23 #include <stdlib.h>
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
24 #include "verify.h"
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
25
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
26 _GL_INLINE_HEADER_BEGIN
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
27 #ifndef COUNT_LEADING_ZEROS_INLINE
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
28 # define COUNT_LEADING_ZEROS_INLINE _GL_INLINE
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
29 #endif
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
30
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
31 /* Expand the code which computes the number of leading zeros of the local
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
32 variable 'x' of type TYPE (an unsigned integer type) and returns it
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
33 from the current function. */
17038
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
34 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
35 # define COUNT_LEADING_ZEROS(BUILTIN, TYPE) \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
36 return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
37 #else
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
38 # define COUNT_LEADING_ZEROS(BUILTIN, TYPE) \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
39 /* This condition is written so as to avoid shifting by more than \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
40 31 bits at once, and also avoids a random HP-UX cc bug. */ \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
41 verify (((TYPE) -1 >> 31 >> 31 >> 2) == 0); /* TYPE has at most 64 bits */ \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
42 int count = 0; \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
43 if (1 < (TYPE) -1 >> 31) { /* TYPE has more than 32 bits? */ \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
44 count = count_leading_zeros_32 (x >> 31 >> 1); \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
45 if (count < 32) \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
46 return count; \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
47 } \
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
48 return count + count_leading_zeros_32 (x);
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
49
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
50 /* Compute and return the number of leading zeros in the least
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
51 significant 32 bits of X. */
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
52 COUNT_LEADING_ZEROS_INLINE int
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
53 count_leading_zeros_32 (unsigned int x)
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
54 {
17038
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
55 /* http://graphics.stanford.edu/~seander/bithacks.html */
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
56 static const char deBruijnLookup[32] = {
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
57 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
58 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
59 };
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
60
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
61 x &= 0xffffffffU;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
62 if (!x)
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
63 return 32;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
64 x |= x >> 1;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
65 x |= x >> 2;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
66 x |= x >> 4;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
67 x |= x >> 8;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
68 x |= x >> 16;
86928fc41efe count-leading-zeros: use a lookup table on non-gcc compilers
Eric Blake <eblake@redhat.com>
parents: 17037
diff changeset
69 return 31 - deBruijnLookup[(x * 0x07c4acddU) >> 27];
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
70 }
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
71 #endif
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
72
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
73 /* Compute and return the number of leading zeros in X. */
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
74 COUNT_LEADING_ZEROS_INLINE int
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
75 count_leading_zeros (unsigned int x)
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
76 {
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
77 COUNT_LEADING_ZEROS (__builtin_clz, unsigned int);
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
78 }
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
79
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
80 /* Compute and return the number of leading zeros in X. */
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
81 COUNT_LEADING_ZEROS_INLINE int
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
82 count_leading_zeros_l (unsigned long int x)
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
83 {
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
84 COUNT_LEADING_ZEROS (__builtin_clzl, unsigned long int);
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
85 }
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
86
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
87 #if HAVE_UNSIGNED_LONG_LONG_INT
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
88 /* Compute and return the number of leading zeros in X. */
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
89 COUNT_LEADING_ZEROS_INLINE int
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
90 count_leading_zeros_ll (unsigned long long int x)
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
91 {
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
92 COUNT_LEADING_ZEROS (__builtin_clzll, unsigned long long int);
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
93 }
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
94 #endif
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
95
17166
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
96 _GL_INLINE_HEADER_END
22a948de1761 count-leading-zeros: better 'inline'
Paul Eggert <eggert@cs.ucla.edu>
parents: 17038
diff changeset
97
17037
abd788a78228 count-leading-zeros: new module
Eric Blake <eblake@redhat.com>
parents:
diff changeset
98 #endif /* COUNT_LEADING_ZEROS_H */