00001 #ifndef BMUTIL__H__INCLUDED__
00002 #define BMUTIL__H__INCLUDED__
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 #include "bmdef.h"
00030 #include "bmconst.h"
00031
00032 namespace bm
00033 {
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 template<typename T>
00054 T bit_scan_fwd(T v)
00055 {
00056 return
00057 DeBruijn_bit_position<true>::_multiply[((word_t)((v & -v) * 0x077CB531U)) >> 27];
00058 }
00059
00060
00061
00062
00063
00064 template<typename T>
00065 T ilog2(T x)
00066 {
00067 unsigned int l = 0;
00068 if(x >= 1<<16) { x>>=16; l |= 16; }
00069 if(x >= 1<<8) { x>>=8; l |= 8; }
00070 if(x >= 1<<4) { x>>=4; l |= 4; }
00071 if(x >= 1<<2) { x>>=2; l |= 2; }
00072 if(x >= 1<<1) l |=1;
00073 return l;
00074 }
00075
00076 template<>
00077 inline bm::gap_word_t ilog2(gap_word_t x)
00078 {
00079 unsigned int l = 0;
00080 if(x >= 1<<8) { x>>=8; l |= 8; }
00081 if(x >= 1<<4) { x>>=4; l |= 4; }
00082 if(x >= 1<<2) { x>>=2; l |= 2; }
00083 if(x >= 1<<1) l |=1;
00084 return l;
00085 }
00086
00087
00088
00089
00090
00091
00092 template<typename T>
00093 T ilog2_LUT(T x)
00094 {
00095 unsigned l = 0;
00096 if (x & 0xffff0000)
00097 {
00098 l += 16; x >>= 16;
00099 }
00100
00101 if (x & 0xff00)
00102 {
00103 l += 8; x >>= 8;
00104 }
00105 return l + first_bit_table<true>::_idx[x];
00106 }
00107
00108
00109
00110
00111 template<>
00112 inline bm::gap_word_t ilog2_LUT<bm::gap_word_t>(bm::gap_word_t x)
00113 {
00114 unsigned l = 0;
00115 if (x & 0xff00)
00116 {
00117 l += 8; x >>= 8;
00118 }
00119 return l + first_bit_table<true>::_idx[x];
00120 }
00121
00122
00123
00124
00125 #ifdef BM_x86
00126 #ifdef __GNUG__
00127
00128 inline
00129 unsigned bsf_asm32(unsigned int v)
00130 {
00131 unsigned r;
00132 asm volatile(" bsfl %1, %0": "=r"(r): "rm"(v) );
00133 return r;
00134 }
00135
00136 BMFORCEINLINE unsigned bsr_asm32(register unsigned int v)
00137 {
00138 unsigned r;
00139 asm volatile(" bsrl %1, %0": "=r"(r): "rm"(v) );
00140 return r;
00141 }
00142
00143 #endif // __GNUG__
00144
00145 #ifdef _MSC_VER
00146
00147 #if defined(_M_AMD64) || defined(_M_X64) // inline assembly not supported
00148
00149 BMFORCEINLINE unsigned int bsr_asm32(unsigned int value)
00150 {
00151 unsigned long r;
00152 _BitScanReverse(&r, value);
00153 return r;
00154 }
00155
00156 BMFORCEINLINE unsigned int bsf_asm32(unsigned int value)
00157 {
00158 unsigned long r;
00159 _BitScanForward(&r, value);
00160 return r;
00161 }
00162
00163 #else
00164
00165 BMFORCEINLINE unsigned int bsr_asm32(register unsigned int value)
00166 {
00167 __asm bsr eax, value
00168 }
00169
00170 BMFORCEINLINE unsigned int bsf_asm32(register unsigned int value)
00171 {
00172 __asm bsf eax, value
00173 }
00174
00175 #endif
00176
00177 #endif // _MSC_VER
00178
00179 #endif // BM_x86
00180
00181
00182
00183 }
00184
00185 #endif