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