00001
00002
00010
00011
00012
00013 #ifndef _BITINDEX_H_
00014 #define _BITINDEX_H_
00015
00016 #include <assert.h>
00017
00018 namespace HL {
00019
00020 class BitIndex {
00021 private:
00022
00023 enum { debruijn32 = 0x077CB531UL };
00024 static int index32[32];
00025 static unsigned long lgtable[16];
00026 static unsigned long on[32];
00027 static unsigned long off[32];
00028
00029 void setup (void);
00030
00031 public:
00032
00033 BitIndex (void);
00034 ~BitIndex (void) {}
00035
00036
00037 static void set (unsigned long &b, int index)
00038 {
00039 assert (index >= 0);
00040 assert (index < 32);
00041 b |= on[index];
00042 }
00043
00044
00045 static void reset (unsigned long &b, int index)
00046 {
00047 assert (index >= 0);
00048 assert (index < 32);
00049 b &= off[index];
00050 }
00051
00052
00053 static int lsb (unsigned long b)
00054 {
00055
00056 #if 0 // i386
00057
00058 register unsigned long index = 0;
00059 if (b > 0) {
00060 asm ("bsfl %1, %0" : "=r" (index) : "r" (b));
00061 }
00062 return index;
00063 #else
00064 b &= (unsigned long) -((signed long) b);
00065 b *= debruijn32;
00066 b >>= 27;
00067 return index32[b];
00068 #endif
00069 }
00070
00071
00072 static int msb (unsigned long b)
00073 {
00074 #if 0 // i386
00075
00076 register unsigned long index = 0;
00077 if (b > 0) {
00078 asm ("bsrl %1, %0" : "=r" (index) : "r" (b));
00079 }
00080 return index;
00081 #else
00082 int l = 0;
00083
00084 if (b >= 65536) {
00085 l += 16;
00086 b >>= 16;
00087 }
00088
00089 if (b >= 256) {
00090 l += 8;
00091 b >>= 8;
00092 }
00093
00094 if (b >= 16) {
00095 l += 4;
00096 b >>= 4;
00097 }
00098 return l + lgtable[b];
00099 #endif
00100 }
00101
00102
00103 };
00104
00105 };
00106
00107 #endif