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