Main Page   File List  

bitops_arch.h

Go to the documentation of this file.
00001 /* $Id: bitops_arch.h 34933 2009-03-21 23:44:07Z adam $ */
00002 /*****************************************************************************/
00011 /*
00012  * Copyright (C) 2000-2002
00013  * Dresden University of Technology, Operating Systems Research Group
00014  *
00015  * This file contains free software, you can redistribute it and/or modify
00016  * it under the terms of the GNU General Public License, Version 2 as
00017  * published by the Free Software Foundation (see the file COPYING).
00018  *
00019  * This program is distributed in the hope that it will be useful,
00020  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  * GNU General Public License for more details.
00023  *
00024  * For different licensing schemes please contact
00025  * <contact@os.inf.tu-dresden.de>.
00026  */
00027 /*****************************************************************************/
00028 #ifndef __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
00029 #define __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
00030 
00031 /*****************************************************************************
00032  *** Implementation
00033  *****************************************************************************/
00034 
00035 EXTERN_C_BEGIN
00036 
00037 /* set bit */
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),   /* 0 mem, destination operand */
00048      "Ir"  (b)       /* 1,     bit number */
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 /* clear bit */
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),   /* 0 mem, destination operand */
00072      "Ir"  (b)        /* 1,     bit number */
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 /* change bit */
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),   /* 0 mem, destination operand */
00096      "Ir"  (b)        /* 1,     bit number */
00097      :
00098      "memory", "cc"
00099      );
00100 }
00101 
00102 /* test bit */
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)      /* 0,     old bit value */
00115      :
00116      "m"   (*dest),   /* 1 mem, destination operand */
00117      "Ir"  (b)        /* 2,     bit number */
00118      :
00119      "memory", "cc"
00120      );
00121 
00122   return (int)bit;
00123 }
00124 
00125 /* test bit */
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 /* bit test and set */
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)      /* 0,     old bit value */
00146      :
00147      "m"   (*dest),   /* 1 mem, destination operand */
00148      "Ir"  (b)        /* 2,     bit number */
00149      :
00150      "memory", "cc"
00151      );
00152 
00153   return (int)bit;
00154 }
00155 
00156 /* bit test and reset */
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)      /* 0,     old bit value */
00169      :
00170      "m"   (*dest),   /* 1 mem, destination operand */
00171      "Ir"  (b)        /* 2,     bit number */
00172      :
00173      "memory", "cc"
00174      );
00175 
00176   return (int)bit;
00177 }
00178 
00179 /* bit test and complement */
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)      /* 0,     old bit value */
00192      :
00193      "m"   (*dest),   /* 1 mem, destination operand */
00194      "Ir"  (b)        /* 2,     bit number */
00195      :
00196      "memory", "cc"
00197      );
00198 
00199   return (int)bit;
00200 }
00201 
00202 /* bit scan reverse */
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)       /* 0, index of most significant set bit */
00217      :
00218      "r"  (word)      /* 1, argument */
00219      );
00220 
00221   return tmp;
00222 }
00223 
00224 /* bit scan forwad */
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)       /* 0, index of least significant set bit */
00239      :
00240      "r"  (word)      /* 1, argument */
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 /* ! __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__ */

L4 Utilities, part of DROPS  © 2000-2003