00001
00002
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__
00031 #define __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__
00032
00033 EXTERN_C_BEGIN
00034
00035
00036
00037
00038
00039
00040 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT32
00041 L4_INLINE void
00042 l4util_set_bit32(int b, volatile l4_uint32_t * dest)
00043 {
00044 __asm__ __volatile__
00045 (
00046 "btsl %1,%0 \n\t"
00047 :
00048 :
00049 "m" (*dest),
00050 "Ir" (b)
00051 :
00052 "memory", "cc"
00053 );
00054 }
00055
00056 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT64
00057 L4_INLINE void
00058 l4util_set_bit64(int b, volatile l4_uint64_t * dest)
00059 {
00060 __asm__ __volatile__
00061 (
00062 "btsl %1,%0 \n\t"
00063 :
00064 :
00065 "m" (*dest),
00066 "Ir" (b)
00067 :
00068 "memory", "cc"
00069 );
00070 }
00071
00072 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
00073 L4_INLINE void
00074 l4util_set_bit(int b, volatile l4_umword_t * dest)
00075 {
00076 return l4util_set_bit64(b, (volatile l4_uint64_t*)dest);
00077 }
00078
00079
00080 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT32
00081 L4_INLINE void
00082 l4util_clear_bit32(int b, volatile l4_uint32_t * dest)
00083 {
00084 __asm__ __volatile__
00085 (
00086 "btrl %1,%0 \n\t"
00087 :
00088 :
00089 "m" (*dest),
00090 "Ir" (b)
00091 :
00092 "memory", "cc"
00093 );
00094 }
00095
00096 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT64
00097 L4_INLINE void
00098 l4util_clear_bit64(int b, volatile l4_uint64_t * dest)
00099 {
00100 __asm__ __volatile__
00101 (
00102 "btrl %1,%0 \n\t"
00103 :
00104 :
00105 "m" (*dest),
00106 "Ir" (b)
00107 :
00108 "memory", "cc"
00109 );
00110 }
00111
00112 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
00113 L4_INLINE void
00114 l4util_clear_bit(int b, volatile l4_umword_t * dest)
00115 {
00116 return l4util_clear_bit64(b, (volatile l4_uint64_t*)dest);
00117 }
00118
00119
00120 #define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
00121 L4_INLINE void
00122 l4util_complement_bit(int b, volatile l4_umword_t * dest)
00123 {
00124 __asm__ __volatile__
00125 (
00126 "btcq %1,%0 \n\t"
00127 :
00128 :
00129 "m" (*dest),
00130 "Ir" ((l4_umword_t)b)
00131 :
00132 "memory", "cc"
00133 );
00134 }
00135
00136
00137 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT32
00138 L4_INLINE int
00139 l4util_test_bit32(int b, const volatile l4_uint32_t * dest)
00140 {
00141 l4_int8_t bit;
00142
00143 __asm__ __volatile__
00144 (
00145 "btl %2,%1 \n\t"
00146 "setc %0 \n\t"
00147 :
00148 "=r" (bit)
00149 :
00150 "m" (*dest),
00151 "Ir" (b)
00152 :
00153 "memory", "cc"
00154 );
00155
00156 return (int)bit;
00157 }
00158
00159 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT64
00160 L4_INLINE int
00161 l4util_test_bit64(int b, const volatile l4_uint64_t * dest)
00162 {
00163 l4_int8_t bit;
00164
00165 __asm__ __volatile__
00166 (
00167 "btl %2,%1 \n\t"
00168 "setc %0 \n\t"
00169 :
00170 "=r" (bit)
00171 :
00172 "m" (*dest),
00173 "Ir" (b)
00174 :
00175 "memory", "cc"
00176 );
00177
00178 return (int)bit;
00179 }
00180
00181 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
00182 L4_INLINE int
00183 l4util_test_bit(int b, const volatile l4_umword_t * dest)
00184 {
00185 return l4util_test_bit64(b, (const volatile l4_uint64_t *)dest);
00186 }
00187
00188
00189
00190 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
00191 L4_INLINE int
00192 l4util_bts(int b, volatile l4_umword_t * dest)
00193 {
00194 l4_int8_t bit;
00195
00196 __asm__ __volatile__
00197 (
00198 "btsl %2,%1 \n\t"
00199 "setc %0 \n\t"
00200 :
00201 "=r" (bit)
00202 :
00203 "m" (*dest),
00204 "Ir" (b)
00205 :
00206 "memory", "cc"
00207 );
00208
00209 return (int)bit;
00210 }
00211
00212
00213 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
00214 L4_INLINE int
00215 l4util_btr(int b, volatile l4_umword_t * dest)
00216 {
00217 l4_int8_t bit;
00218
00219 __asm__ __volatile__
00220 (
00221 "btrl %2,%1 \n\t"
00222 "setc %0 \n\t"
00223 :
00224 "=r" (bit)
00225 :
00226 "m" (*dest),
00227 "Ir" (b)
00228 :
00229 "memory", "cc"
00230 );
00231
00232 return (int)bit;
00233 }
00234
00235
00236 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
00237 L4_INLINE int
00238 l4util_btc(int b, volatile l4_umword_t * dest)
00239 {
00240 l4_int8_t bit;
00241
00242 __asm__ __volatile__
00243 (
00244 "btc %2,%1 \n\t"
00245 "setc %0 \n\t"
00246 :
00247 "=r" (bit)
00248 :
00249 "m" (*dest),
00250 "Ir" ((l4_umword_t)b)
00251 :
00252 "memory", "cc"
00253 );
00254
00255 return (int)bit;
00256 }
00257
00258
00259 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
00260 L4_INLINE int
00261 l4util_bsr(l4_umword_t word)
00262 {
00263 l4_umword_t tmp;
00264
00265 if (EXPECT_FALSE(word == 0))
00266 return -1;
00267
00268 __asm__ __volatile__
00269 (
00270 "bsr %1,%0 \n\t"
00271 :
00272 "=r" (tmp)
00273 :
00274 "r" (word)
00275 );
00276
00277 return tmp;
00278 }
00279
00280
00281 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
00282 L4_INLINE int
00283 l4util_bsf(l4_umword_t word)
00284 {
00285 l4_umword_t tmp;
00286
00287 if (EXPECT_FALSE(word == 0))
00288 return -1;
00289
00290 __asm__ __volatile__
00291 (
00292 "bsf %1,%0 \n\t"
00293 :
00294 "=r" (tmp)
00295 :
00296 "r" (word)
00297 );
00298
00299 return tmp;
00300 }
00301
00302 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
00303 L4_INLINE int
00304 l4util_find_first_set_bit(const void * dest, l4_size_t size)
00305 {
00306 l4_mword_t dummy0, dummy1, res;
00307
00308 __asm__ __volatile__
00309 (
00310 "xor %%rax,%%rax \n\t"
00311 "repe; scasl \n\t"
00312 "jz 1f \n\t"
00313 "lea -4(%%rdi),%%rdi \n\t"
00314 "bsfq (%%rdi),%%rax \n"
00315 "1: \n\t"
00316 "sub %%rbx,%%rdi \n\t"
00317 "shl $3,%%rdi \n\t"
00318 "add %%rdi,%%rax \n\t"
00319 :
00320 "=a" (res), "=&c" (dummy0), "=&D" (dummy1)
00321 :
00322 "1" ((size + 31) >> 5), "2" (dest), "b" (dest)
00323 :
00324 "cc", "memory");
00325
00326 return res;
00327 }
00328
00329 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
00330 L4_INLINE int
00331 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
00332 {
00333 l4_mword_t dummy0, dummy1, dummy2, res;
00334
00335 if (!size)
00336 return 0;
00337
00338 __asm__ __volatile__
00339 (
00340 "mov $-1,%%rax \n\t"
00341 "xor %%rdx,%%rdx \n\t"
00342 "repe; scasl \n\t"
00343 "je 1f \n\t"
00344 "xor -4(%%rdi),%%rax \n\t"
00345 "sub $4,%%rdi \n\t"
00346 "bsf %%rax,%%rdx \n"
00347 "1: \n\t"
00348 "sub %[dest],%%rdi \n\t"
00349 "shl $3,%%rdi \n\t"
00350 "add %%rdi,%%rdx \n\t"
00351 :
00352 "=d" (res), "=&c" (dummy0), "=&D" (dummy1), "=&a" (dummy2)
00353 :
00354 "1" ((size + 31) >> 5), "2" (dest), [dest] "S" (dest)
00355 :
00356 "cc", "memory");
00357
00358 return res;
00359 }
00360
00361 EXTERN_C_END
00362
00363 #endif