L4Re - L4 Runtime Environment
bitops_arch.h
Go to the documentation of this file.
1 /*****************************************************************************/
11 /*
12  * (c) 2000-2009 Author(s)
13  * economic rights: Technische Universit├Ąt Dresden (Germany)
14  * This file is part of TUD:OS and distributed under the terms of the
15  * GNU Lesser General Public License 2.1.
16  * Please see the COPYING-LGPL-2.1 file for details.
17  */
18 
19 /*****************************************************************************/
20 #ifndef __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__
21 #define __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__
22 
24 
25 /*****************************************************************************
26  *** Implementation
27  *****************************************************************************/
28 
29 #define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
30 L4_INLINE void
31 l4util_set_bit(int b, volatile l4_umword_t * dest)
32 {
33  __asm__ __volatile__
34  (
35  "lock; bts %1,%0 \n\t"
36  :
37  :
38  "m" (*dest), /* 0 mem, destination operand */
39  "Ir" (b) /* 1, bit number */
40  :
41  "memory", "cc"
42  );
43 }
44 
45 /* clear bit */
46 #define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
47 L4_INLINE void
48 l4util_clear_bit(int b, volatile l4_umword_t * dest)
49 {
50  __asm__ __volatile__
51  (
52  "lock; btr %1,%0 \n\t"
53  :
54  :
55  "m" (*dest), /* 0 mem, destination operand */
56  "Ir" (b) /* 1, bit number */
57  :
58  "memory", "cc"
59  );
60 }
61 
62 /* change bit */
63 #define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
64 L4_INLINE void
65 l4util_complement_bit(int b, volatile l4_umword_t * dest)
66 {
67  __asm__ __volatile__
68  (
69  "lock; btc %1,%0 \n\t"
70  :
71  :
72  "m" (*dest), /* 0 mem, destination operand */
73  "Ir" (b) /* 1, bit number */
74  :
75  "memory", "cc"
76  );
77 }
78 
79 /* test bit */
80 #define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
81 L4_INLINE int
82 l4util_test_bit(int b, const volatile l4_umword_t * dest)
83 {
84  l4_int8_t bit;
85 
86  __asm__ __volatile__
87  (
88  "bt %2,%1 \n\t"
89  "setc %0 \n\t"
90  :
91  "=r" (bit) /* 0, old bit value */
92  :
93  "m" (*dest), /* 1 mem, destination operand */
94  "Ir" (b) /* 2, bit number */
95  :
96  "memory", "cc"
97  );
98 
99  return (int)bit;
100 }
101 
102 
103 /* bit test and set */
104 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
105 L4_INLINE int
106 l4util_bts(int b, volatile l4_umword_t * dest)
107 {
108  l4_int8_t bit;
109 
110  __asm__ __volatile__
111  (
112  "lock; bts %2,%1 \n\t"
113  "setc %0 \n\t"
114  :
115  "=r" (bit) /* 0, old bit value */
116  :
117  "m" (*dest), /* 1 mem, destination operand */
118  "Ir" (b) /* 2, bit number */
119  :
120  "memory", "cc"
121  );
122 
123  return (int)bit;
124 }
125 
126 /* bit test and reset */
127 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
128 L4_INLINE int
129 l4util_btr(int b, volatile l4_umword_t * dest)
130 {
131  l4_int8_t bit;
132 
133  __asm__ __volatile__
134  (
135  "lock; btr %2,%1 \n\t"
136  "setc %0 \n\t"
137  :
138  "=r" (bit) /* 0, old bit value */
139  :
140  "m" (*dest), /* 1 mem, destination operand */
141  "Ir" (b) /* 2, bit number */
142  :
143  "memory", "cc"
144  );
145 
146  return (int)bit;
147 }
148 
149 /* bit test and complement */
150 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
151 L4_INLINE int
152 l4util_btc(int b, volatile l4_umword_t * dest)
153 {
154  l4_int8_t bit;
155 
156  __asm__ __volatile__
157  (
158  "lock; btc %2,%1 \n\t"
159  "setc %0 \n\t"
160  :
161  "=r" (bit) /* 0, old bit value */
162  :
163  "m" (*dest), /* 1 mem, destination operand */
164  "Ir" ((l4_umword_t)b) /* 2, bit number */
165  :
166  "memory", "cc"
167  );
168 
169  return (int)bit;
170 }
171 
172 /* bit scan reverse */
173 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
174 L4_INLINE int
176 {
177  l4_umword_t tmp;
178 
179  if (L4_UNLIKELY(word == 0))
180  return -1;
181 
182  __asm__ __volatile__
183  (
184  "bsr %1,%0 \n\t"
185  :
186  "=r" (tmp) /* 0, index of most significant set bit */
187  :
188  "r" (word) /* 1, argument */
189  );
190 
191  return tmp;
192 }
193 
194 /* bit scan forwad */
195 #define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
196 L4_INLINE int
198 {
199  l4_umword_t tmp;
200 
201  if (L4_UNLIKELY(word == 0))
202  return -1;
203 
204  __asm__ __volatile__
205  (
206  "bsf %1,%0 \n\t"
207  :
208  "=r" (tmp) /* 0, index of least significant set bit */
209  :
210  "r" (word) /* 1, argument */
211  );
212 
213  return tmp;
214 }
215 
216 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
217 L4_INLINE int
218 l4util_find_first_set_bit(const void * dest, l4_size_t size)
219 {
220  l4_mword_t dummy0, dummy1, res;
221 
222  __asm__ __volatile__
223  (
224  "xor %%rax,%%rax \n\t"
225  "repe; scasl \n\t"
226  "jz 1f \n\t"
227  "lea -4(%%rdi),%%rdi \n\t"
228  "bsfq (%%rdi),%%rax \n"
229  "1: \n\t"
230  "sub %%rbx,%%rdi \n\t"
231  "shl $3,%%rdi \n\t"
232  "add %%rdi,%%rax \n\t"
233  :
234  "=a" (res), "=&c" (dummy0), "=&D" (dummy1)
235  :
236  "1" ((size + 31) >> 5), "2" (dest), "b" (dest)
237  :
238  "cc", "memory");
239 
240  return res;
241 }
242 
243 #define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
244 L4_INLINE int
245 l4util_find_first_zero_bit(const void * dest, l4_size_t size)
246 {
247  l4_mword_t dummy0, dummy1, dummy2, res;
248 
249  if (!size)
250  return 0;
251 
252  __asm__ __volatile__
253  (
254  "mov $-1,%%rax \n\t"
255  "xor %%rdx,%%rdx \n\t"
256  "repe; scasl \n\t"
257  "je 1f \n\t"
258  "xor -4(%%rdi),%%rax \n\t"
259  "sub $4,%%rdi \n\t"
260  "bsf %%rax,%%rdx \n"
261  "1: \n\t"
262  "sub %[dest],%%rdi \n\t"
263  "shl $3,%%rdi \n\t"
264  "add %%rdi,%%rdx \n\t"
265  :
266  "=d" (res), "=&c" (dummy0), "=&D" (dummy1), "=&a" (dummy2)
267  :
268  "1" ((size + 31) >> 5), "2" (dest), [dest] "S" (dest)
269  :
270  "cc", "memory");
271 
272  return res;
273 }
274 
276 
277 #endif /* ! __L4UTIL__INCLUDE__ARCH_AMD64__BITOPS_ARCH_H__ */
unsigned int l4_size_t
Unsigned size type.
Definition: l4int.h:35
signed char l4_int8_t
Signed 8bit value.
Definition: l4int.h:35
int l4util_test_bit(int b, const volatile l4_umword_t *dest)
Test bit (return value of bit)
Definition: bitops.h:244
signed long l4_mword_t
Signed machine word.
Definition: l4int.h:49
#define EXTERN_C_END
End section with C types and functions.
Definition: compiler.h:187
int l4util_btc(int b, volatile l4_umword_t *dest)
Bit test and complement.
Definition: bitops.h:394
int l4util_btr(int b, volatile l4_umword_t *dest)
Bit test and reset.
Definition: bitops.h:278
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition: compiler.h:234
int l4util_find_first_zero_bit(const void *dest, l4_size_t size)
Find the first zero bit in a memory region.
Definition: bitops.h:333
void l4util_complement_bit(int b, volatile l4_umword_t *dest)
Complement bit in memory.
Definition: bitops.h:359
int l4util_bsf(l4_umword_t word)
Bit scan forward.
Definition: bitops.h:316
void l4util_set_bit(int b, volatile l4_umword_t *dest)
Set bit in memory.
Definition: bitops.h:207
unsigned long l4_umword_t
Unsigned machine word.
Definition: l4int.h:52
#define EXTERN_C_BEGIN
Start section with C types and functions.
Definition: compiler.h:186
int l4util_bts(int b, volatile l4_umword_t *dest)
Bit test and set.
Definition: bitops.h:256
int l4util_find_first_set_bit(const void *dest, l4_size_t size)
Find the first set bit in a memory region.
Definition: bitops.h:400
void l4util_clear_bit(int b, volatile l4_umword_t *dest)
Clear bit in memory.
Definition: bitops.h:226
int l4util_bsr(l4_umword_t word)
Bit scan reverse.
Definition: bitops.h:299