DPDK 23.11.2
Loading...
Searching...
No Matches
rte_bitops.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Arm Limited
3 * Copyright(c) 2010-2019 Intel Corporation
4 * Copyright(c) 2023 Microsoft Corporation
5 */
6
7#ifndef _RTE_BITOPS_H_
8#define _RTE_BITOPS_H_
9
18#include <stdint.h>
19
20#include <rte_debug.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
32#define RTE_BIT64(nr) (UINT64_C(1) << (nr))
33
40#define RTE_BIT32(nr) (UINT32_C(1) << (nr))
41
42/*------------------------ 32-bit relaxed operations ------------------------*/
43
54static inline uint32_t
55rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
56{
57 RTE_ASSERT(nr < 32);
58
59 uint32_t mask = UINT32_C(1) << nr;
60 return (*addr) & mask;
61}
62
71static inline void
72rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
73{
74 RTE_ASSERT(nr < 32);
75
76 uint32_t mask = RTE_BIT32(nr);
77 *addr = (*addr) | mask;
78}
79
88static inline void
89rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
90{
91 RTE_ASSERT(nr < 32);
92
93 uint32_t mask = RTE_BIT32(nr);
94 *addr = (*addr) & (~mask);
95}
96
108static inline uint32_t
109rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
110{
111 RTE_ASSERT(nr < 32);
112
113 uint32_t mask = RTE_BIT32(nr);
114 uint32_t val = *addr;
115 *addr = val | mask;
116 return val & mask;
117}
118
130static inline uint32_t
131rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
132{
133 RTE_ASSERT(nr < 32);
134
135 uint32_t mask = RTE_BIT32(nr);
136 uint32_t val = *addr;
137 *addr = val & (~mask);
138 return val & mask;
139}
140
141/*------------------------ 64-bit relaxed operations ------------------------*/
142
153static inline uint64_t
154rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
155{
156 RTE_ASSERT(nr < 64);
157
158 uint64_t mask = RTE_BIT64(nr);
159 return (*addr) & mask;
160}
161
170static inline void
171rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
172{
173 RTE_ASSERT(nr < 64);
174
175 uint64_t mask = RTE_BIT64(nr);
176 (*addr) = (*addr) | mask;
177}
178
187static inline void
188rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
189{
190 RTE_ASSERT(nr < 64);
191
192 uint64_t mask = RTE_BIT64(nr);
193 *addr = (*addr) & (~mask);
194}
195
207static inline uint64_t
208rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
209{
210 RTE_ASSERT(nr < 64);
211
212 uint64_t mask = RTE_BIT64(nr);
213 uint64_t val = *addr;
214 *addr = val | mask;
215 return val;
216}
217
229static inline uint64_t
230rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
231{
232 RTE_ASSERT(nr < 64);
233
234 uint64_t mask = RTE_BIT64(nr);
235 uint64_t val = *addr;
236 *addr = val & (~mask);
237 return val & mask;
238}
239
240#ifdef RTE_TOOLCHAIN_MSVC
241
250static inline unsigned int
251rte_clz32(uint32_t v)
252{
253 unsigned long rv;
254
255 (void)_BitScanReverse(&rv, v);
256
257 return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv);
258}
259
268static inline unsigned int
269rte_clz64(uint64_t v)
270{
271 unsigned long rv;
272
273 (void)_BitScanReverse64(&rv, v);
274
275 return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv);
276}
277
286static inline unsigned int
287rte_ctz32(uint32_t v)
288{
289 unsigned long rv;
290
291 (void)_BitScanForward(&rv, v);
292
293 return (unsigned int)rv;
294}
295
304static inline unsigned int
305rte_ctz64(uint64_t v)
306{
307 unsigned long rv;
308
309 (void)_BitScanForward64(&rv, v);
310
311 return (unsigned int)rv;
312}
313
322static inline unsigned int
323rte_popcount32(uint32_t v)
324{
325 return (unsigned int)__popcnt(v);
326}
327
336static inline unsigned int
337rte_popcount64(uint64_t v)
338{
339 return (unsigned int)__popcnt64(v);
340}
341
342#else
343
352static inline unsigned int
353rte_clz32(uint32_t v)
354{
355 return (unsigned int)__builtin_clz(v);
356}
357
366static inline unsigned int
367rte_clz64(uint64_t v)
368{
369 return (unsigned int)__builtin_clzll(v);
370}
371
380static inline unsigned int
381rte_ctz32(uint32_t v)
382{
383 return (unsigned int)__builtin_ctz(v);
384}
385
394static inline unsigned int
395rte_ctz64(uint64_t v)
396{
397 return (unsigned int)__builtin_ctzll(v);
398}
399
408static inline unsigned int
409rte_popcount32(uint32_t v)
410{
411 return (unsigned int)__builtin_popcount(v);
412}
413
422static inline unsigned int
423rte_popcount64(uint64_t v)
424{
425 return (unsigned int)__builtin_popcountll(v);
426}
427
428#endif
429
440static inline uint32_t
442{
443 x |= x >> 1;
444 x |= x >> 2;
445 x |= x >> 4;
446 x |= x >> 8;
447 x |= x >> 16;
448
449 return x;
450}
451
462static inline uint64_t
464{
465 v |= v >> 1;
466 v |= v >> 2;
467 v |= v >> 4;
468 v |= v >> 8;
469 v |= v >> 16;
470 v |= v >> 32;
471
472 return v;
473}
474
486static inline uint32_t
487rte_bsf32(uint32_t v)
488{
489 return (uint32_t)rte_ctz32(v);
490}
491
506static inline int
507rte_bsf32_safe(uint32_t v, uint32_t *pos)
508{
509 if (v == 0)
510 return 0;
511
512 *pos = rte_bsf32(v);
513 return 1;
514}
515
527static inline uint32_t
528rte_bsf64(uint64_t v)
529{
530 return (uint32_t)rte_ctz64(v);
531}
532
547static inline int
548rte_bsf64_safe(uint64_t v, uint32_t *pos)
549{
550 if (v == 0)
551 return 0;
552
553 *pos = rte_bsf64(v);
554 return 1;
555}
556
568static inline uint32_t
569rte_fls_u32(uint32_t x)
570{
571 return (x == 0) ? 0 : 32 - rte_clz32(x);
572}
573
586static inline uint32_t
587rte_fls_u64(uint64_t x)
588{
589 return (x == 0) ? 0 : 64 - rte_clz64(x);
590}
591
592/*********** Macros to work with powers of 2 ********/
593
597#define RTE_IS_POWER_OF_2(n) ((n) && !(((n) - 1) & (n)))
598
605static inline int
607{
608 return n && !(n & (n - 1));
609}
610
620static inline uint32_t
622{
623 x--;
624 x = rte_combine32ms1b(x);
625
626 return x + 1;
627}
628
638static inline uint32_t
640{
641 x = rte_combine32ms1b(x);
642
643 return x - (x >> 1);
644}
645
655static inline uint64_t
657{
658 v--;
659 v = rte_combine64ms1b(v);
660
661 return v + 1;
662}
663
673static inline uint64_t
675{
676 v = rte_combine64ms1b(v);
677
678 return v - (v >> 1);
679}
680
692static inline uint32_t
693rte_log2_u32(uint32_t v)
694{
695 if (v == 0)
696 return 0;
697 v = rte_align32pow2(v);
698 return rte_bsf32(v);
699}
700
712static inline uint32_t
713rte_log2_u64(uint64_t v)
714{
715 if (v == 0)
716 return 0;
717 v = rte_align64pow2(v);
718 /* we checked for v being 0 already, so no undefined behavior */
719 return rte_bsf64(v);
720}
721
722#ifdef __cplusplus
723}
724#endif
725
726#endif /* _RTE_BITOPS_H_ */
#define RTE_BIT64(nr)
Definition rte_bitops.h:32
static void rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
Definition rte_bitops.h:72
static uint32_t rte_log2_u32(uint32_t v)
Definition rte_bitops.h:693
static uint32_t rte_fls_u32(uint32_t x)
Definition rte_bitops.h:569
static void rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
Definition rte_bitops.h:188
static int rte_bsf32_safe(uint32_t v, uint32_t *pos)
Definition rte_bitops.h:507
#define RTE_BIT32(nr)
Definition rte_bitops.h:40
static uint64_t rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
Definition rte_bitops.h:230
static uint32_t rte_bsf64(uint64_t v)
Definition rte_bitops.h:528
static unsigned int rte_clz32(uint32_t v)
Definition rte_bitops.h:353
static uint32_t rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
Definition rte_bitops.h:109
static uint32_t rte_align32pow2(uint32_t x)
Definition rte_bitops.h:621
static uint32_t rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
Definition rte_bitops.h:131
static unsigned int rte_popcount32(uint32_t v)
Definition rte_bitops.h:409
static uint32_t rte_align32prevpow2(uint32_t x)
Definition rte_bitops.h:639
static uint64_t rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
Definition rte_bitops.h:208
static uint64_t rte_align64pow2(uint64_t v)
Definition rte_bitops.h:656
static unsigned int rte_ctz64(uint64_t v)
Definition rte_bitops.h:395
static uint32_t rte_bsf32(uint32_t v)
Definition rte_bitops.h:487
static int rte_bsf64_safe(uint64_t v, uint32_t *pos)
Definition rte_bitops.h:548
static uint64_t rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
Definition rte_bitops.h:154
static unsigned int rte_popcount64(uint64_t v)
Definition rte_bitops.h:423
static unsigned int rte_ctz32(uint32_t v)
Definition rte_bitops.h:381
static uint64_t rte_align64prevpow2(uint64_t v)
Definition rte_bitops.h:674
static unsigned int rte_clz64(uint64_t v)
Definition rte_bitops.h:367
static void rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
Definition rte_bitops.h:89
static uint32_t rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
Definition rte_bitops.h:55
static void rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
Definition rte_bitops.h:171
static int rte_is_power_of_2(uint32_t n)
Definition rte_bitops.h:606
static uint64_t rte_combine64ms1b(uint64_t v)
Definition rte_bitops.h:463
static uint32_t rte_combine32ms1b(uint32_t x)
Definition rte_bitops.h:441
static uint32_t rte_log2_u64(uint64_t v)
Definition rte_bitops.h:713
static uint32_t rte_fls_u64(uint64_t x)
Definition rte_bitops.h:587