Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00044
00045
00046
00047
00048
00049
00050 #ifndef _bit_scan_h
00051 #define _bit_scan_h
00052
00053 #include <limits.h>
00054
00056 #if defined __CPU_i386 && ! defined __CPU_x86
00057 #define __CPU_x86
00058 #endif
00059
00060
00061 #ifdef CC_GCC_LIKE_ASM
00062 #if defined __CPU_x86 || defined __CPU_x86_64
00063 #define BIT_SCAN_ASM
00064 #endif
00065 #endif
00066
00067
00071 #ifdef BIT_SCAN_ASM
00072
00073
00074 #define bit_scan_forward32(i) bit_scan_forward_asm32(i)
00075 #define bit_scan_forward64(i) bit_scan_forward_asm64(i)
00076 #define bit_scan_reverse32(i) bit_scan_reverse_asm32(i)
00077 #define bit_scan_reverse64(i) bit_scan_reverse_asm64(i)
00078
00079 #elif defined __CPU_x86 || defined __CPU_x86_64
00080
00081
00082
00083 #ifndef BIT_SCAN_DEBRUIJN
00084 #define BIT_SCAN_DEBRUIJN
00085 #endif
00086 #ifndef BIT_SCAN_BRANCH
00087 #define BIT_SCAN_BRANCH
00088 #endif
00089
00090 #define bit_scan_forward32(i) bit_scan_forward_debruijn32(i)
00091 #define bit_scan_forward64(i) bit_scan_forward_debruijn64(i)
00092 #define bit_scan_reverse32(i) bit_scan_reverse_br32(i)
00093 #define bit_scan_reverse64(i) bit_scan_reverse_br64(i)
00094
00095 #elif defined __CPU_sparc64
00096
00097
00098
00099
00100 #ifndef BIT_SCAN_BRANCH
00101 #define BIT_SCAN_BRANCH
00102 #endif
00103
00104 #define bit_scan_reverse32(i) bit_scan_reverse_br32(i)
00105 #define bit_scan_reverse64(i) bit_scan_reverse_br64(i)
00106 #ifdef LP64
00107 #define bit_scan_forward32(i) bit_scan_forward_br32(i)
00108 #define bit_scan_forward64(i) bit_scan_forward_br64(i)
00109 #else
00110
00111 #ifndef BIT_SCAN_DEBRUIJN
00112 #define BIT_SCAN_DEBRUIJN
00113 #endif
00114 #define bit_scan_forward32(i) bit_scan_forward_debruijn32(i)
00115 #define bit_scan_forward64(i) bit_scan_forward_debruijn64(i)
00116 #endif
00117
00118 #else
00119
00120
00121 #ifndef BIT_SCAN_DEBRUIJN
00122 #define BIT_SCAN_DEBRUIJN
00123 #endif
00124 #ifndef BIT_SCAN_BRANCH
00125 #define BIT_SCAN_BRANCH
00126 #endif
00127
00128 #define bit_scan_forward32(i) bit_scan_forward_debruijn32(i)
00129 #define bit_scan_forward64(i) bit_scan_forward_debruijn64(i)
00130 #define bit_scan_reverse32(i) bit_scan_reverse_br32(i)
00131 #define bit_scan_reverse64(i) bit_scan_reverse_br64(i)
00132
00133 #endif
00134
00135
00138 #if (defined (ULONG_MAX) && ULONG_MAX > 4294967295) || defined LP64
00139
00140 #define bit_scan_forward(l) bit_scan_forward64((unsigned long long)(l))
00141 #define bit_scan_reverse(l) bit_scan_reverse64((unsigned long long)(l))
00142
00143 #else
00144
00145 #define bit_scan_forward(l) bit_scan_forward32((l))
00146 #define bit_scan_reverse(l) bit_scan_reverse32((l))
00147 #endif
00148
00149
00150
00151
00152 #ifdef BIT_SCAN_DEBRUIJN
00153
00164 extern unsigned char _debruijn_hash32[32];
00165 extern unsigned char _debruijn_hash64[64];
00166
00167 #define DEBRUIJN_CT32 0x04653ADFU
00168 #define DEBRUIJN_CT64 0x0218A392CD3D5DBFULL
00169
00170 #define DEBRUIJN_HASH32(x)\
00171 (((x)*DEBRUIJN_CT32)>>(sizeof(x)*8-5))
00172
00173 #define DEBRUIJN_HASH64(x)\
00174 (((x)*DEBRUIJN_CT64)>>(sizeof(x)*8-6))
00175
00176 #define bit_scan_forward_debruijn32(x) \
00177 ( _debruijn_hash32[DEBRUIJN_HASH32((x) & (-(x)))])
00178
00179 #define bit_scan_forward_debruijn64(x) \
00180 ( _debruijn_hash64[DEBRUIJN_HASH64((x) & (-(x)))])
00181
00182
00183 static inline int bit_scan_reverse_debruijn32(unsigned int v)
00184 {
00185 unsigned int last;
00186
00187 do{
00188 last=v;
00189 v=v&(v-1);
00190 }while(v);
00191 return _debruijn_hash32[DEBRUIJN_HASH32(last)];
00192 }
00193
00194
00195 static inline int bit_scan_reverse_debruijn64(unsigned long long v)
00196 {
00197 unsigned long long last;
00198
00199 do{
00200 last=v;
00201 v=v&(v-1);
00202 }while(v);
00203 return _debruijn_hash64[DEBRUIJN_HASH64(last)];
00204 }
00205
00206
00207 #endif
00208
00209 #ifdef BIT_SCAN_SLOW
00210
00211
00212 static inline int bit_scan_forward_slow32(unsigned int v)
00213 {
00214 int r;
00215 for(r=0; r<(sizeof(v)*8); r++, v>>=1)
00216 if (v&1) return r;
00217 return 0;
00218 }
00219
00220
00221 static inline int bit_scan_reverse_slow32(unsigned int v)
00222 {
00223 int r;
00224 for(r=sizeof(v)*8-1; r>0; r--, v<<=1)
00225 if (v& (1UL<<(sizeof(v)*8-1))) return r;
00226 return 0;
00227 }
00228
00229
00230 static inline int bit_scan_forward_slow64(unsigned long long v)
00231 {
00232 int r;
00233 for(r=0; r<(sizeof(v)*8); r++, v>>=1)
00234 if (v&1ULL) return r;
00235 return 0;
00236 }
00237
00238
00239 static inline int bit_scan_reverse_slow64(unsigned long long v)
00240 {
00241 int r;
00242 for(r=sizeof(v)*8-1; r>0; r--, v<<=1)
00243 if (v& (1ULL<<(sizeof(v)*8-1))) return r;
00244 return 0;
00245 }
00246
00247
00248 #endif
00249
00250
00251 #ifdef BIT_SCAN_BRANCH
00252
00253 static inline int bit_scan_forward_br32(unsigned int v)
00254 {
00255 int b;
00256
00257 b=0;
00258 if (v&0x01)
00259 return 0;
00260 if (!(v & 0xffff)){
00261 b+=16;
00262 v>>=16;
00263 }
00264 if (!(v&0xff)){
00265 b+=8;
00266 v>>=8;
00267 }
00268 if (!(v&0x0f)){
00269 b+=4;
00270 v>>=4;
00271 }
00272 if (!(v&0x03)){
00273 b+=2;
00274 v>>=2;
00275 }
00276 b+= !(v&0x01);
00277 return b;
00278 }
00279
00280
00281 static inline int bit_scan_reverse_br32(unsigned int v)
00282 {
00283 int b;
00284
00285 b=0;
00286 if (v & 0xffff0000){
00287 b+=16;
00288 v>>=16;
00289 }
00290 if (v&0xff00){
00291 b+=8;
00292 v>>=8;
00293 }
00294 if (v&0xf0){
00295 b+=4;
00296 v>>=4;
00297 }
00298 if (v&0x0c){
00299 b+=2;
00300 v>>=2;
00301 }
00302 b+= !!(v&0x02);
00303 return b;
00304 }
00305
00306
00307 static inline int bit_scan_forward_br64(unsigned long long v)
00308 {
00309 int b;
00310
00311 b=0;
00312 if (v&0x01ULL)
00313 return 0;
00314 if (!(v & 0xffffffffULL)){
00315 b+=32;
00316 v>>=32;
00317 }
00318 if (!(v & 0xffffULL)){
00319 b+=16;
00320 v>>=16;
00321 }
00322 if (!(v&0xffULL)){
00323 b+=8;
00324 v>>=8;
00325 }
00326 if (!(v&0x0fULL)){
00327 b+=4;
00328 v>>=4;
00329 }
00330 if (!(v&0x03ULL)){
00331 b+=2;
00332 v>>=2;
00333 }
00334 b+= !(v&0x01ULL);
00335 return b;
00336 }
00337
00338
00339 static inline int bit_scan_reverse_br64(unsigned long long v)
00340 {
00341 int b;
00342
00343 b=0;
00344 if (v & 0xffffffff00000000ULL){
00345 b+=32;
00346 v>>=32;
00347 }
00348 if (v & 0xffff0000ULL){
00349 b+=16;
00350 v>>=16;
00351 }
00352 if (v&0xff00ULL){
00353 b+=8;
00354 v>>=8;
00355 }
00356 if (v&0xf0ULL){
00357 b+=4;
00358 v>>=4;
00359 }
00360 if (v&0x0cULL){
00361 b+=2;
00362 v>>=2;
00363 }
00364 b+= !!(v&0x02ULL);
00365 return b;
00366 }
00367 #endif
00368
00369
00370
00371 #ifdef BIT_SCAN_ASM
00372 #if defined __CPU_x86 || defined __CPU_x86_64
00373 #define HAS_BIT_SCAN_ASM
00374
00375 static inline int bit_scan_forward_asm32(unsigned int v)
00376 {
00377 int r;
00378 asm volatile(" bsfl %1, %0": "=r"(r): "rm"(v) );
00379 return r;
00380 }
00381
00382 static inline int bit_scan_reverse_asm32(unsigned int v)
00383 {
00384 int r;
00385 asm volatile(" bsrl %1, %0": "=r"(r): "rm"(v) );
00386 return r;
00387 }
00388
00389 #ifdef __CPU_x86_64
00390 static inline int bit_scan_forward_asm64(unsigned long long v)
00391 {
00392 long r;
00393 asm volatile(" bsfq %1, %0": "=r"(r): "rm"(v) );
00394 return r;
00395 }
00396
00397 static inline int bit_scan_reverse_asm64(unsigned long long v)
00398 {
00399 long r;
00400 asm volatile(" bsrq %1, %0": "=r"(r): "rm"(v) );
00401 return r;
00402 }
00403 #else
00404 static inline int bit_scan_forward_asm64(unsigned long long v)
00405 {
00406 if ((unsigned int)v)
00407 return bit_scan_forward_asm32((unsigned int)v);
00408 return 32+bit_scan_forward_asm32(*(((unsigned int*)(void*)&v)+1));
00409 }
00410
00411 static inline int bit_scan_reverse_asm64(unsigned long long v)
00412 {
00413 if (v & 0xffffffff00000000ULL)
00414 return 32+bit_scan_reverse_asm32(*(((unsigned int*)(void*)&v)+1));
00415 return bit_scan_reverse_asm32((unsigned int)v);
00416 }
00417 #endif
00418
00419 #endif
00420 #endif
00421
00422 #endif