Main Page   File List  

bitops_arch.h

Go to the documentation of this file.
00001 /* $Id: bitops_arch.h 30108 2007-09-24 07:13:48Z adam $ */
00002 /*****************************************************************************/
00013 /*
00014  * Copyright (C) 2000-2002
00015  * Dresden University of Technology, Operating Systems Research Group
00016  *
00017  * This file contains free software, you can redistribute it and/or modify
00018  * it under the terms of the GNU General Public License, Version 2 as
00019  * published by the Free Software Foundation (see the file COPYING).
00020  *
00021  * This program is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  * GNU General Public License for more details.
00025  *
00026  * For different licensing schemes please contact
00027  * <contact@os.inf.tu-dresden.de>.
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  *** Implementation
00037  *****************************************************************************/
00038 
00039 /* set bit */
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),   /* 0 mem, destination operand */
00050      "Ir"  (b)       /* 1,     bit number */
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),   /* 0 mem, destination operand */
00066      "Ir"  (b)       /* 1,     bit number */
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 /* clear bit */
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),   /* 0 mem, destination operand */
00090      "Ir"  (b)        /* 1,     bit number */
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),   /* 0 mem, destination operand */
00106      "Ir"  (b)        /* 1,     bit number */
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 /* change bit */
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),   /* 0 mem, destination operand */
00130      "Ir"  ((l4_umword_t)b)        /* 1,     bit number */
00131      :
00132      "memory", "cc"
00133      );
00134 }
00135 
00136 /* test bit */
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)      /* 0,     old bit value */
00149      :
00150      "m"   (*dest),   /* 1 mem, destination operand */
00151      "Ir"  (b)        /* 2,     bit number */
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)      /* 0,     old bit value */
00171      :
00172      "m"   (*dest),   /* 1 mem, destination operand */
00173      "Ir"  (b)        /* 2,     bit number */
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 /* bit test and set */
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)      /* 0,     old bit value */
00202      :
00203      "m"   (*dest),   /* 1 mem, destination operand */
00204      "Ir"  (b)        /* 2,     bit number */
00205      :
00206      "memory", "cc"
00207      );
00208 
00209   return (int)bit;
00210 }
00211 
00212 /* bit test and reset */
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)      /* 0,     old bit value */
00225      :
00226      "m"   (*dest),   /* 1 mem, destination operand */
00227      "Ir"  (b)        /* 2,     bit number */
00228      :
00229      "memory", "cc"
00230      );
00231 
00232   return (int)bit;
00233 }
00234 
00235 /* bit test and complement */
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)      /* 0,     old bit value */
00248      :
00249      "m"   (*dest),   /* 1 mem, destination operand */
00250      "Ir"  ((l4_umword_t)b)        /* 2,     bit number */
00251      :
00252      "memory", "cc"
00253      );
00254 
00255   return (int)bit;
00256 }
00257 
00258 /* bit scan reverse */
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)       /* 0, index of most significant set bit */
00273      :
00274      "r"  (word)      /* 1, argument */
00275      );
00276 
00277   return tmp;
00278 }
00279 
00280 /* bit scan forwad */
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)       /* 0, index of least significant set bit */
00295      :
00296      "r"  (word)      /* 1, argument */
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 /* ! __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__ */

L4 Utilities, part of DROPS  © 2000-2003