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_BIT
29 L4_INLINE void
l4util_set_bit(int b,volatile l4_umword_t * dest)30 l4util_set_bit(int b, volatile l4_umword_t * dest)
31 {
32 __asm__ __volatile__
33 (
34 "lock; 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 /* clear bit */
45 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
46 L4_INLINE void
l4util_clear_bit(int b,volatile l4_umword_t * dest)47 l4util_clear_bit(int b, volatile l4_umword_t * dest)
48 {
49 __asm__ __volatile__
50 (
51 "lock; btrl %1,%0 \n\t"
52 :
53 :
54 "m" (*dest), /* 0 mem, destination operand */
55 "Ir" (b) /* 1, bit number */
56 :
57 "memory", "cc"
58 );
59 }
60
61 /* change bit */
62 #define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
63 L4_INLINE void
l4util_complement_bit(int b,volatile l4_umword_t * dest)64 l4util_complement_bit(int b, volatile l4_umword_t * dest)
65 {
66 __asm__ __volatile__
67 (
68 "lock; btcl %1,%0 \n\t"
69 :
70 :
71 "m" (*dest), /* 0 mem, destination operand */
72 "Ir" (b) /* 1, bit number */
73 :
74 "memory", "cc"
75 );
76 }
77
78 /* test bit */
79 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
80 L4_INLINE int
l4util_test_bit(int b,const volatile l4_umword_t * dest)81 l4util_test_bit(int b, const volatile l4_umword_t * dest)
82 {
83 l4_int8_t bit;
84
85 __asm__ __volatile__
86 (
87 "btl %2,%1 \n\t"
88 "setc %0 \n\t"
89 :
90 "=q" (bit) /* 0, old bit value */
91 :
92 "m" (*dest), /* 1 mem, destination operand */
93 "Ir" (b) /* 2, bit number */
94 :
95 "memory", "cc"
96 );
97
98 return (int)bit;
99 }
100
101 /* bit test and set */
102 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
103 L4_INLINE int
l4util_bts(int b,volatile l4_umword_t * dest)104 l4util_bts(int b, volatile l4_umword_t * dest)
105 {
106 l4_int8_t bit;
107
108 __asm__ __volatile__
109 (
110 "lock; btsl %2,%1 \n\t"
111 "setc %0 \n\t"
112 :
113 "=q" (bit) /* 0, old bit value */
114 :
115 "m" (*dest), /* 1 mem, destination operand */
116 "Ir" (b) /* 2, bit number */
117 :
118 "memory", "cc"
119 );
120
121 return (int)bit;
122 }
123
124 /* bit test and reset */
125 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
126 L4_INLINE int
l4util_btr(int b,volatile l4_umword_t * dest)127 l4util_btr(int b, volatile l4_umword_t * dest)
128 {
129 l4_int8_t bit;
130
131 __asm__ __volatile__
132 (
133 "lock; btrl %2,%1 \n\t"
134 "setc %0 \n\t"
135 :
136 "=q" (bit) /* 0, old bit value */
137 :
138 "m" (*dest), /* 1 mem, destination operand */
139 "Ir" (b) /* 2, bit number */
140 :
141 "memory", "cc"
142 );
143
144 return (int)bit;
145 }
146
147 /* bit test and complement */
148 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
149 L4_INLINE int
l4util_btc(int b,volatile l4_umword_t * dest)150 l4util_btc(int b, volatile l4_umword_t * dest)
151 {
152 l4_int8_t bit;
153
154 __asm__ __volatile__
155 (
156 "lock; btcl %2,%1 \n\t"
157 "setc %0 \n\t"
158 :
159 "=q" (bit) /* 0, old bit value */
160 :
161 "m" (*dest), /* 1 mem, destination operand */
162 "Ir" (b) /* 2, bit number */
163 :
164 "memory", "cc"
165 );
166
167 return (int)bit;
168 }
169
170 /* bit scan reverse */
171 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
172 L4_INLINE int
l4util_bsr(l4_umword_t word)173 l4util_bsr(l4_umword_t word)
174 {
175 int tmp;
176
177 if (L4_UNLIKELY(word == 0))
178 return -1;
179
180 __asm__ __volatile__
181 (
182 "bsrl %1,%0 \n\t"
183 :
184 "=r" (tmp) /* 0, index of most significant set bit */
185 :
186 "r" (word) /* 1, argument */
187 );
188
189 return tmp;
190 }
191
192 /* bit scan forwad */
193 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
194 L4_INLINE int
l4util_bsf(l4_umword_t word)195 l4util_bsf(l4_umword_t word)
196 {
197 int tmp;
198
199 if (L4_UNLIKELY(word == 0))
200 return -1;
201
202 __asm__ __volatile__
203 (
204 "bsfl %1,%0 \n\t"
205 :
206 "=r" (tmp) /* 0, index of least significant set bit */
207 :
208 "r" (word) /* 1, argument */
209 );
210
211 return tmp;
212 }
213
214 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
215 L4_INLINE int
l4util_find_first_set_bit(const void * dest,l4_size_t size)216 l4util_find_first_set_bit(const void * dest, l4_size_t size)
217 {
218 l4_mword_t dummy0, dummy1, res;
219
220 __asm__ __volatile__
221 (
222 "repe; scasl \n\t"
223 "jz 1f \n\t"
224 "leal -4(%%edi),%%edi \n\t"
225 "bsfl (%%edi),%%eax \n"
226 "1: \n\t"
227 "subl %%esi,%%edi \n\t"
228 "shll $3,%%edi \n\t"
229 "addl %%edi,%%eax \n\t"
230 :
231 "=a" (res), "=c" (dummy0), "=D" (dummy1)
232 :
233 "a"(0), "c" ((size+31) >> 5), "D" (dest), "S" (dest)
234 :
235 "cc", "memory");
236
237 return res;
238 }
239
240 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
241 L4_INLINE int
l4util_find_first_zero_bit(const void * dest,l4_size_t size)242 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
243 {
244 l4_mword_t dummy0, dummy1, dummy2, res;
245
246 if (!size)
247 return 0;
248
249 __asm__ __volatile__
250 (
251 "repe; scasl \n\t"
252 "je 1f \n\t"
253 "xorl -4(%%edi),%%eax \n\t"
254 "subl $4,%%edi \n\t"
255 "bsfl %%eax,%%edx \n"
256 "1: \n\t"
257 "subl %%esi,%%edi \n\t"
258 "shll $3,%%edi \n\t"
259 "addl %%edi,%%edx \n\t"
260 :
261 "=d" (res), "=c" (dummy0), "=D" (dummy1), "=a" (dummy2)
262 :
263 "a" (~0), "c" ((size+31) >> 5), "d"(0), "D" (dest), "S" (dest)
264 :
265 "cc", "memory");
266
267 return res;
268 }
269
270 EXTERN_C_END
271
272 #endif /* ! __L4UTIL__INCLUDE__ARCH_X86__BITOPS_ARCH_H__ */
273