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