Go to the documentation of this file.00001 #ifndef OSL_MISC_BITOP_H
00002 #define OSL_MISC_BITOP_H
00003
00004 #include "osl/config.h"
00005 #include <cassert>
00006 namespace osl
00007 {
00008 namespace misc
00009 {
00013 template <class Integer> struct Bsf;
00014
00015 template <>
00016 struct Bsf<unsigned int>
00017 {
00018 static int bsf(unsigned int mask)
00019 {
00020 assert(mask);
00021 #ifdef __x86_64__
00022 int ret;
00023 __asm__("bsfl %1,%0" : "=r"(ret) : "r"(mask));
00024 return ret;
00025 #else
00026 # ifdef __i386__
00027 int ret;
00028 __asm__("bsfl %1,%0" : "=r"(ret) : "r"(mask));
00029 return ret;
00030 # elif defined __GNUC__
00031 return __builtin_ctzl(mask);
00032 # else
00033 for (int i=0;i<32;i++)
00034 if (mask & (1<<i))
00035 return i;
00036 # endif
00037 #endif
00038 assert(0);
00039 return -1;
00040 }
00041 };
00042 template <>
00043 struct Bsf<unsigned short>
00044 {
00045 static unsigned short bsf(unsigned short mask)
00046 {
00047 assert(mask);
00048 #ifdef __x86_64__
00049 unsigned short ret;
00050 __asm__("bsfw %1,%0" : "=r"(ret) : "r"(mask));
00051 return ret;
00052 #else
00053 # ifdef __i386__
00054 unsigned short ret;
00055 __asm__("bsfw %1,%0" : "=r"(ret) : "r"(mask));
00056 return ret;
00057 # else
00058 return __builtin_ctzl(mask);
00059 # endif
00060 #endif
00061 }
00062 };
00063
00064 template <>
00065 struct Bsf<unsigned long long>
00066 {
00067 static int bsf(unsigned long long mask)
00068 {
00069 assert(mask);
00070 #ifdef __x86_64__
00071 long long ret;
00072 __asm__("bsfq %1,%0" : "=r"(ret) : "r"(mask));
00073 return static_cast<int>(ret);
00074 #else
00075 unsigned int mask32 = static_cast<unsigned int>(mask);
00076 if (mask32)
00077 return Bsf<unsigned int>::bsf(mask32);
00078 mask32 = static_cast<unsigned int>(mask >> 32);
00079 return 32+Bsf<unsigned int>::bsf(mask32);
00080 #endif
00081 }
00082 };
00083
00084 template <class Integer> struct Bsr;
00085
00086 template <>
00087 struct Bsr<unsigned int>
00088 {
00089 static int bsr(unsigned int mask)
00090 {
00091 assert(mask);
00092 #ifdef __x86_64__
00093 int ret;
00094 __asm__("bsrl %1,%0" : "=r"(ret) : "r"(mask));
00095 return ret;
00096 #else
00097 # ifdef __i386__
00098 int ret;
00099 __asm__("bsrl %1,%0" : "=r"(ret) : "r"(mask));
00100 return ret;
00101 # elif __GNUC__
00102 return __builtin_clzl(mask);
00103 # else
00104 for (int i=31; i>=0; --i)
00105 if (mask & (1<<i))
00106 return i;
00107 # endif
00108 #endif
00109 assert(0);
00110 return -1;
00111 }
00112 };
00113
00114 template <>
00115 struct Bsr<unsigned long long>
00116 {
00117 static int bsr(unsigned long long mask)
00118 {
00119 assert(mask);
00120 #ifdef __x86_64__
00121 long long ret;
00122 __asm__("bsrq %1,%0" : "=r"(ret) : "r"(mask));
00123 return static_cast<int>(ret);
00124 #else
00125 unsigned int mask32 = static_cast<unsigned int>(mask >> 32);
00126 if (mask32)
00127 return 32+Bsr<unsigned int>::bsr(mask32);
00128 mask32 = static_cast<unsigned int>(mask);
00129 return Bsr<unsigned int>::bsr(mask32);
00130 #endif
00131 }
00132 };
00133
00134 struct BitOp
00135 {
00136 template <class Integer>
00137 static int bsf(Integer mask)
00138 {
00139 return Bsf<Integer>::bsf(mask);
00140 }
00141 template <class Integer>
00142 static int bsr(Integer mask)
00143 {
00144 return Bsr<Integer>::bsr(mask);
00145 }
00146 template <class Integer>
00147 static int takeOneBit(Integer& mask){
00148 assert(mask);
00149 const int num=bsf(mask);
00150 mask &= mask-1;
00151 return num;
00152 }
00153
00154 template <class Integer>
00155 static int
00156 #ifdef __GNUC__
00157 __attribute__ ((const))
00158 #endif
00159 countBit(Integer mask)
00160 {
00161 int count=0;
00162 while (mask)
00163 {
00164 ++count;
00165 mask &= (mask-1);
00166 }
00167 return count;
00168 }
00169 template <class Integer>
00170 static bool hasMultipleBit(Integer mask){
00171 assert(mask);
00172 return (mask & (mask-1));
00173 }
00177 template <class Integer>
00178 static Integer lowestBit(Integer mask){
00179 assert(mask);
00180 return static_cast<Integer>(mask & (-mask));
00181 }
00182 };
00183
00184 #if 0
00185
00198 inline int countBitDense(unsigned int mask)
00199 {
00200 mask = ((mask>>1)&0x55555555)+(mask&0x55555555);
00201 mask = ((mask>>2)&0x33333333)+(mask&0x33333333);
00202 mask = ((mask>>4)+mask)&0xf0f0f0f;
00203 mask = (mask>>8)+mask;
00204 return ((mask>>16)+mask)&0x3f;
00205 }
00206 #endif
00207 }
00208 }
00209 #endif // _BITOP_H
00210
00211
00212
00213