]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/l4util/include/ARCH-x86/bitops_arch.h
Update
[l4.git] / l4 / pkg / l4re-core / l4util / include / ARCH-x86 / bitops_arch.h
1 /*****************************************************************************/
2 /**
3  * \file
4  * \brief   x86 bit manipulation functions
5  * \ingroup bitops
6  *
7  * \date    07/03/2001
8  * \author  Lars Reuther <reuther@os.inf.tu-dresden.de> */
9 /*
10  * (c) 2000-2009 Author(s)
11  *     economic rights: Technische Universität Dresden (Germany)
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU Lesser General Public License 2.1.
14  * Please see the COPYING-LGPL-2.1 file for details.
15  */
16
17 /*****************************************************************************/
18 #ifndef __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
19 #define __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__
20
21 /*****************************************************************************
22  *** Implementation
23  *****************************************************************************/
24
25 EXTERN_C_BEGIN
26
27 /* set bit */
28 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT32
29 L4_INLINE void
30 l4util_set_bit32(int b, volatile l4_uint32_t * dest)
31 {
32   __asm__ __volatile__
33     (
34      "btsl  %1,%0   \n\t"
35      :
36      :
37      "m"   (*dest),   /* 0 mem, destination operand */
38      "Ir"  (b)       /* 1,     bit number */
39      :
40      "memory", "cc"
41      );
42 }
43
44 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
45 L4_INLINE void
46 l4util_set_bit(int b, volatile l4_umword_t * dest)
47 {
48   return l4util_set_bit32(b, (volatile l4_uint32_t*)dest);
49 }
50
51 /* clear bit */
52 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT32
53 L4_INLINE void
54 l4util_clear_bit32(int b, volatile l4_uint32_t * dest)
55 {
56   __asm__ __volatile__
57     (
58      "btrl  %1,%0   \n\t"
59      :
60      :
61      "m"   (*dest),   /* 0 mem, destination operand */
62      "Ir"  (b)        /* 1,     bit number */
63      :
64      "memory", "cc"
65      );
66 }
67
68 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
69 L4_INLINE void
70 l4util_clear_bit(int b, volatile l4_umword_t * dest)
71 {
72   return l4util_clear_bit32(b, (volatile l4_uint32_t*)dest);
73 }
74
75 /* change bit */
76 #define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
77 L4_INLINE void
78 l4util_complement_bit(int b, volatile l4_umword_t * dest)
79 {
80   __asm__ __volatile__
81     (
82      "btcl  %1,%0   \n\t"
83      :
84      :
85      "m"   (*dest),   /* 0 mem, destination operand */
86      "Ir"  (b)        /* 1,     bit number */
87      :
88      "memory", "cc"
89      );
90 }
91
92 /* test bit */
93 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT32
94 L4_INLINE int
95 l4util_test_bit32(int b, const volatile l4_uint32_t * dest)
96 {
97   l4_int8_t bit;
98
99   __asm__ __volatile__
100     (
101      "btl   %2,%1   \n\t"
102      "setc  %0      \n\t"
103      :
104      "=q"  (bit)      /* 0,     old bit value */
105      :
106      "m"   (*dest),   /* 1 mem, destination operand */
107      "Ir"  (b)        /* 2,     bit number */
108      :
109      "memory", "cc"
110      );
111
112   return (int)bit;
113 }
114
115 /* test bit */
116 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
117 L4_INLINE int
118 l4util_test_bit(int b, const volatile l4_umword_t * dest)
119 {
120   return l4util_test_bit32(b, (const volatile l4_uint32_t*)dest);
121 }
122
123 /* bit test and set */
124 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
125 L4_INLINE int 
126 l4util_bts(int b, volatile l4_umword_t * dest)
127 {
128   l4_int8_t bit;
129
130   __asm__ __volatile__
131     (
132      "btsl  %2,%1   \n\t"
133      "setc  %0      \n\t"
134      :
135      "=q"  (bit)      /* 0,     old bit value */
136      :
137      "m"   (*dest),   /* 1 mem, destination operand */
138      "Ir"  (b)        /* 2,     bit number */
139      :
140      "memory", "cc"
141      );
142
143   return (int)bit;
144 }
145
146 /* bit test and reset */
147 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
148 L4_INLINE int
149 l4util_btr(int b, volatile l4_umword_t * dest)
150 {
151   l4_int8_t bit;
152
153   __asm__ __volatile__
154     (
155      "btrl  %2,%1   \n\t"
156      "setc  %0      \n\t"
157      :
158      "=q"  (bit)      /* 0,     old bit value */
159      :
160      "m"   (*dest),   /* 1 mem, destination operand */
161      "Ir"  (b)        /* 2,     bit number */
162      :
163      "memory", "cc"
164      );
165
166   return (int)bit;
167 }
168
169 /* bit test and complement */
170 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
171 L4_INLINE int
172 l4util_btc(int b, volatile l4_umword_t * dest)
173 {
174   l4_int8_t bit;
175
176   __asm__ __volatile__
177     (
178      "btcl  %2,%1   \n\t"
179      "setc  %0      \n\t"
180      :
181      "=q"  (bit)      /* 0,     old bit value */
182      :
183      "m"   (*dest),   /* 1 mem, destination operand */
184      "Ir"  (b)        /* 2,     bit number */
185      :
186      "memory", "cc"
187      );
188
189   return (int)bit;
190 }
191
192 /* bit scan reverse */
193 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
194 L4_INLINE int
195 l4util_bsr(l4_umword_t word)
196 {
197   int tmp;
198
199   if (L4_UNLIKELY(word == 0))
200     return -1;
201
202   __asm__ __volatile__
203     (
204      "bsrl %1,%0 \n\t"
205      :
206      "=r" (tmp)       /* 0, index of most significant set bit */
207      :
208      "r"  (word)      /* 1, argument */
209      );
210
211   return tmp;
212 }
213
214 /* bit scan forwad */
215 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
216 L4_INLINE int
217 l4util_bsf(l4_umword_t word)
218 {
219   int tmp;
220
221   if (L4_UNLIKELY(word == 0))
222     return -1;
223
224   __asm__ __volatile__
225     (
226      "bsfl %1,%0 \n\t"
227      :
228      "=r" (tmp)       /* 0, index of least significant set bit */
229      :
230      "r"  (word)      /* 1, argument */
231      );
232
233   return tmp;
234 }
235
236 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
237 L4_INLINE int
238 l4util_find_first_set_bit(const void * dest, l4_size_t size)
239 {
240   l4_mword_t dummy0, dummy1, res;
241
242   __asm__ __volatile__
243     (
244      "repe; scasl               \n\t"
245      "jz    1f                  \n\t"
246      "leal  -4(%%edi),%%edi     \n\t"
247      "bsfl  (%%edi),%%eax       \n"
248      "1:                        \n\t"
249      "subl  %%esi,%%edi         \n\t"
250      "shll  $3,%%edi            \n\t"
251      "addl  %%edi,%%eax         \n\t"
252      :
253      "=a" (res), "=c" (dummy0), "=D" (dummy1)
254      :
255      "a"(0), "c" ((size+31) >> 5), "D" (dest), "S" (dest)
256      :
257      "cc", "memory");
258
259   return res;
260 }
261
262 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
263 L4_INLINE int
264 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
265 {
266   l4_mword_t dummy0, dummy1, dummy2, res;
267
268   if (!size)
269     return 0;
270
271   __asm__ __volatile__
272     (
273      "repe;  scasl              \n\t"
274      "je     1f                 \n\t"
275      "xorl   -4(%%edi),%%eax    \n\t"
276      "subl   $4,%%edi           \n\t"
277      "bsfl   %%eax,%%edx        \n"
278      "1:                        \n\t"
279      "subl   %%esi,%%edi        \n\t"
280      "shll   $3,%%edi           \n\t"
281      "addl   %%edi,%%edx        \n\t"
282      :
283      "=d" (res), "=c" (dummy0), "=D" (dummy1), "=a" (dummy2)
284      :
285      "a" (~0), "c" ((size+31) >> 5), "d"(0), "D" (dest), "S" (dest)
286      :
287      "cc", "memory");
288
289   return res;
290 }
291
292 EXTERN_C_END
293
294 #endif /* ! __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__ */