L4Re Operating System Framework
Interface and Usage Documentation
•All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
bitops_arch.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2000-2009 Technische Universität Dresden (Germany)
3 * Copyright (C) 2016, 2022, 2024 Kernkonzept GmbH. All rights reserved.
4 * Author(s): Lars Reuther <reuther@os.inf.tu-dresden.de>
5 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
6 * Frank Mehnert <frank.mehnert@kernkonzept.com>
7 *
8 * License: see LICENSE.spdx (in this directory or the directories above)
9 */
10
17#pragma once
18
19/*
20 * Note: The following Assembler statement may produce wrong code:
21 * asm volatile ("btsl %1, %2" : "=@ccc"(r) : "Jr"(63), "m"(m) : "memory");
22 *
23 * The compiler might chose the first variant because the bit number is smaller
24 * than 64. However, 'bts' is encoded as 32-bit variant ('btsl') and thus only
25 * supports immediate bit values up to 31. Some assemblers support immediate
26 * offsets > 31 by adapting the memory address accordingly but GAS does not.
27 * With GAS, the instruction will encode an immediate value of 63 but the CPU
28 * will set bit 31 instead of bit 63!
29 *
30 * Therefore, if we would use 'btsl' instead of 'btsq', the correct constraint
31 * for the bit number parameter would be "Ir" instead of "Jr".
32 */
33
35
36/* set bit */
37#define __L4UTIL_BITOPS_HAVE_ARCH_SET_BIT
38L4_INLINE void
39l4util_set_bit(int b, volatile l4_umword_t * dest)
40{
41 __asm__ __volatile__
42 (
43 "lock; btsq %1,%0 \n\t"
44 :
45 :
46 "m" (*dest), /* 0 mem, destination operand */
47 "Jr" ((l4_umword_t)b) /* 1, bit number */
48 :
49 "memory", "cc"
50 );
51}
52
53/* clear bit */
54#define __L4UTIL_BITOPS_HAVE_ARCH_CLEAR_BIT
55L4_INLINE void
56l4util_clear_bit(int b, volatile l4_umword_t * dest)
57{
58 __asm__ __volatile__
59 (
60 "lock; btrq %1,%0 \n\t"
61 :
62 :
63 "m" (*dest), /* 0 mem, destination operand */
64 "Jr" ((l4_umword_t)b) /* 1, bit number */
65 :
66 "memory", "cc"
67 );
68}
69
70/* change bit */
71#define __L4UTIL_BITOPS_HAVE_ARCH_COMPLEMENT_BIT
72L4_INLINE void
73l4util_complement_bit(int b, volatile l4_umword_t * dest)
74{
75 __asm__ __volatile__
76 (
77 "lock; btcq %1,%0 \n\t"
78 :
79 :
80 "m" (*dest), /* 0 mem, destination operand */
81 "Jr" ((l4_umword_t)b) /* 1, bit number */
82 :
83 "memory", "cc"
84 );
85}
86
87/* test bit */
88#define __L4UTIL_BITOPS_HAVE_ARCH_TEST_BIT
89L4_INLINE int
90l4util_test_bit(int b, const volatile l4_umword_t * dest)
91{
92 l4_int8_t bit;
93
94 __asm__ __volatile__
95 (
96 "btq %2,%1 \n\t"
97 :
98 "=@ccc" (bit) /* 0, old bit value */
99 :
100 "m" (*dest), /* 1 mem, destination operand */
101 "Jr" ((l4_umword_t)b) /* 2, bit number */
102 :
103 "memory"
104 );
105
106 return bit;
107}
108
109/* bit test and set */
110#define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_SET
111L4_INLINE int
112l4util_bts(int b, volatile l4_umword_t * dest)
113{
114 l4_int8_t bit;
115
116 __asm__ __volatile__
117 (
118 "lock; btsq %2,%1 \n\t"
119 :
120 "=@ccc" (bit) /* 0, old bit value */
121 :
122 "m" (*dest), /* 1 mem, destination operand */
123 "Jr" ((l4_umword_t)b) /* 2, bit number */
124 :
125 "memory"
126 );
127
128 return bit;
129}
130
131/* bit test and reset */
132#define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_RESET
133L4_INLINE int
134l4util_btr(int b, volatile l4_umword_t * dest)
135{
136 l4_int8_t bit;
137
138 __asm__ __volatile__
139 (
140 "lock; btrq %2,%1 \n\t"
141 :
142 "=@ccc" (bit) /* 0, old bit value */
143 :
144 "m" (*dest), /* 1 mem, destination operand */
145 "Jr" ((l4_umword_t)b) /* 2, bit number */
146 :
147 "memory"
148 );
149
150 return bit;
151}
152
153/* bit test and complement */
154#define __L4UTIL_BITOPS_HAVE_ARCH_BIT_TEST_AND_COMPLEMENT
155L4_INLINE int
156l4util_btc(int b, volatile l4_umword_t * dest)
157{
158 l4_int8_t bit;
159
160 __asm__ __volatile__
161 (
162 "lock; btcq %2,%1 \n\t"
163 :
164 "=@ccc" (bit) /* 0, old bit value */
165 :
166 "m" (*dest), /* 1 mem, destination operand */
167 "Jr" ((l4_umword_t)b) /* 2, bit number */
168 :
169 "memory"
170 );
171
172 return bit;
173}
174
175/* bit scan reverse */
176#define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_REVERSE
177L4_INLINE int
178l4util_bsr(l4_umword_t word)
179{
180 l4_umword_t tmp;
181
182 if (L4_UNLIKELY(word == 0))
183 return -1;
184
185 __asm__ __volatile__
186 (
187 "bsrq %1,%0 \n\t"
188 :
189 "=r" (tmp) /* 0, index of most significant set bit */
190 :
191 "r" (word) /* 1, argument */
192 );
193
194 return tmp;
195}
196
197/* bit scan forward */
198#define __L4UTIL_BITOPS_HAVE_ARCH_BIT_SCAN_FORWARD
199L4_INLINE int
200l4util_bsf(l4_umword_t word)
201{
202 l4_umword_t tmp;
203
204 if (L4_UNLIKELY(word == 0))
205 return -1;
206
207 __asm__ __volatile__
208 (
209 "bsfq %1,%0 \n\t"
210 :
211 "=r" (tmp) /* 0, index of least significant set bit */
212 :
213 "r" (word) /* 1, argument */
214 );
215
216 return tmp;
217}
218
219#define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_SET_BIT
220L4_INLINE int
221l4util_find_first_set_bit(const void * dest, l4_size_t size)
222{
223 l4_mword_t dummy0, dummy1, res;
224
225 __asm__ __volatile__
226 (
227 "repe; scasq \n\t"
228 "jz 1f \n\t"
229 "lea -8(%%rdi),%%rdi \n\t"
230 "bsf (%%rdi),%%rax \n"
231 "1: \n\t"
232 "sub %%rbx,%%rdi \n\t"
233 "shl $3,%%rdi \n\t"
234 "add %%rdi,%%rax \n\t"
235 :
236 "=a" (res), "=c" (dummy0), "=D" (dummy1)
237 :
238 "a" (0), "b" (dest), "c" ((size + 63) >> 6), "D" (dest)
239 :
240 "cc", "memory");
241
242 return res;
243}
244
245#define __L4UTIL_BITOPS_HAVE_ARCH_FIND_FIRST_ZERO_BIT
246L4_INLINE int
247l4util_find_first_zero_bit(const void * dest, l4_size_t size)
248{
249 l4_mword_t dummy0, dummy1, dummy2, res;
250
251 if (!size)
252 return 0;
253
254 __asm__ __volatile__
255 (
256 "repe; scasq \n\t"
257 "je 1f \n\t"
258 "xor -8(%%rdi),%%rax \n\t"
259 "sub $8,%%rdi \n\t"
260 "bsf %%rax,%%rdx \n"
261 "1: \n\t"
262 "sub %%rsi,%%rdi \n\t"
263 "shl $3,%%rdi \n\t"
264 "add %%rdi,%%rdx \n\t"
265 :
266 "=a" (dummy0), "=c" (dummy1), "=d" (res), "=D" (dummy2)
267 :
268 "a" (~0UL), "c" ((size + 63) >> 6), "d" (0), "D" (dest), "S" (dest)
269 :
270 "cc", "memory");
271
272 return res;
273}
274
unsigned int l4_size_t
Unsigned size type.
Definition l4int.h:24
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
signed long l4_mword_t
Signed machine word.
Definition l4int.h:37
signed char l4_int8_t
Signed 8bit value.
Definition l4int.h:24
#define __END_DECLS
End section with C types and functions.
Definition compiler.h:167
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Definition compiler.h:275
#define L4_INLINE
L4 Inline function attribute.
Definition compiler.h:51
#define __BEGIN_DECLS
Start section with C types and functions.
Definition compiler.h:164