00001
00002
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
00029 #define __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
00030
00031
00032
00033
00034
00035 EXTERN_C_BEGIN
00036
00037
00038 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT32
00039 L4_INLINE void
00040 l4util_set_bit32(int b, volatile l4_uint32_t * dest)
00041 {
00042 __asm__ __volatile__
00043 (
00044 "btsl %1,%0 \n\t"
00045 :
00046 :
00047 "m" (*dest),
00048 "Ir" (b)
00049 :
00050 "memory", "cc"
00051 );
00052 }
00053
00054 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
00055 L4_INLINE void
00056 l4util_set_bit(int b, volatile l4_umword_t * dest)
00057 {
00058 return l4util_set_bit32(b, (volatile l4_uint32_t*)dest);
00059 }
00060
00061
00062 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT32
00063 L4_INLINE void
00064 l4util_clear_bit32(int b, volatile l4_uint32_t * dest)
00065 {
00066 __asm__ __volatile__
00067 (
00068 "btrl %1,%0 \n\t"
00069 :
00070 :
00071 "m" (*dest),
00072 "Ir" (b)
00073 :
00074 "memory", "cc"
00075 );
00076 }
00077
00078 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
00079 L4_INLINE void
00080 l4util_clear_bit(int b, volatile l4_umword_t * dest)
00081 {
00082 return l4util_clear_bit32(b, (volatile l4_uint32_t*)dest);
00083 }
00084
00085
00086 #define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
00087 L4_INLINE void
00088 l4util_complement_bit(int b, volatile l4_umword_t * dest)
00089 {
00090 __asm__ __volatile__
00091 (
00092 "btcl %1,%0 \n\t"
00093 :
00094 :
00095 "m" (*dest),
00096 "Ir" (b)
00097 :
00098 "memory", "cc"
00099 );
00100 }
00101
00102
00103 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT32
00104 L4_INLINE int
00105 l4util_test_bit32(int b, const volatile l4_uint32_t * dest)
00106 {
00107 l4_int8_t bit;
00108
00109 __asm__ __volatile__
00110 (
00111 "btl %2,%1 \n\t"
00112 "setc %0 \n\t"
00113 :
00114 "=q" (bit)
00115 :
00116 "m" (*dest),
00117 "Ir" (b)
00118 :
00119 "memory", "cc"
00120 );
00121
00122 return (int)bit;
00123 }
00124
00125
00126 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
00127 L4_INLINE int
00128 l4util_test_bit(int b, const volatile l4_umword_t * dest)
00129 {
00130 return l4util_test_bit32(b, (const volatile l4_uint32_t*)dest);
00131 }
00132
00133
00134 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
00135 L4_INLINE int
00136 l4util_bts(int b, volatile l4_umword_t * dest)
00137 {
00138 l4_int8_t bit;
00139
00140 __asm__ __volatile__
00141 (
00142 "btsl %2,%1 \n\t"
00143 "setc %0 \n\t"
00144 :
00145 "=q" (bit)
00146 :
00147 "m" (*dest),
00148 "Ir" (b)
00149 :
00150 "memory", "cc"
00151 );
00152
00153 return (int)bit;
00154 }
00155
00156
00157 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
00158 L4_INLINE int
00159 l4util_btr(int b, volatile l4_umword_t * dest)
00160 {
00161 l4_int8_t bit;
00162
00163 __asm__ __volatile__
00164 (
00165 "btrl %2,%1 \n\t"
00166 "setc %0 \n\t"
00167 :
00168 "=q" (bit)
00169 :
00170 "m" (*dest),
00171 "Ir" (b)
00172 :
00173 "memory", "cc"
00174 );
00175
00176 return (int)bit;
00177 }
00178
00179
00180 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
00181 L4_INLINE int
00182 l4util_btc(int b, volatile l4_umword_t * dest)
00183 {
00184 l4_int8_t bit;
00185
00186 __asm__ __volatile__
00187 (
00188 "btcl %2,%1 \n\t"
00189 "setc %0 \n\t"
00190 :
00191 "=q" (bit)
00192 :
00193 "m" (*dest),
00194 "Ir" (b)
00195 :
00196 "memory", "cc"
00197 );
00198
00199 return (int)bit;
00200 }
00201
00202
00203 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
00204 L4_INLINE int
00205 l4util_bsr(l4_umword_t word)
00206 {
00207 int tmp;
00208
00209 if (EXPECT_FALSE(word == 0))
00210 return -1;
00211
00212 __asm__ __volatile__
00213 (
00214 "bsrl %1,%0 \n\t"
00215 :
00216 "=r" (tmp)
00217 :
00218 "r" (word)
00219 );
00220
00221 return tmp;
00222 }
00223
00224
00225 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
00226 L4_INLINE int
00227 l4util_bsf(l4_umword_t word)
00228 {
00229 int tmp;
00230
00231 if (EXPECT_FALSE(word == 0))
00232 return -1;
00233
00234 __asm__ __volatile__
00235 (
00236 "bsfl %1,%0 \n\t"
00237 :
00238 "=r" (tmp)
00239 :
00240 "r" (word)
00241 );
00242
00243 return tmp;
00244 }
00245
00246 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
00247 L4_INLINE int
00248 l4util_find_first_set_bit(const void * dest, l4_size_t size)
00249 {
00250 l4_mword_t dummy0, dummy1, res;
00251
00252 __asm__ __volatile__
00253 (
00254 "repe; scasl \n\t"
00255 "jz 1f \n\t"
00256 "leal -4(%%edi),%%edi \n\t"
00257 "bsfl (%%edi),%%eax \n"
00258 "1: \n\t"
00259 "subl %%esi,%%edi \n\t"
00260 "shll $3,%%edi \n\t"
00261 "addl %%edi,%%eax \n\t"
00262 :
00263 "=a" (res), "=c" (dummy0), "=D" (dummy1)
00264 :
00265 "a"(0), "c" ((size+31) >> 5), "D" (dest), "S" (dest)
00266 :
00267 "cc", "memory");
00268
00269 return res;
00270 }
00271
00272 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
00273 L4_INLINE int
00274 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
00275 {
00276 l4_mword_t dummy0, dummy1, dummy2, res;
00277
00278 if (!size)
00279 return 0;
00280
00281 __asm__ __volatile__
00282 (
00283 "repe; scasl \n\t"
00284 "je 1f \n\t"
00285 "xorl -4(%%edi),%%eax \n\t"
00286 "subl $4,%%edi \n\t"
00287 "bsfl %%eax,%%edx \n"
00288 "1: \n\t"
00289 "subl %%esi,%%edi \n\t"
00290 "shll $3,%%edi \n\t"
00291 "addl %%edi,%%edx \n\t"
00292 :
00293 "=d" (res), "=c" (dummy0), "=D" (dummy1), "=a" (dummy2)
00294 :
00295 "a" (~0), "c" ((size+31) >> 5), "d"(0), "D" (dest), "S" (dest)
00296 :
00297 "cc", "memory");
00298
00299 return res;
00300 }
00301
00302 EXTERN_C_END
00303
00304 #endif