DPDK 26.11.0-rc1
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 * Copyright(c) 2024 Ericsson AB
6 */
7
8#ifndef _RTE_BITOPS_H_
9#define _RTE_BITOPS_H_
10
20#include <stdint.h>
21
22#include <rte_compat.h>
23#include <rte_debug.h>
24#include <rte_stdatomic.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
36#define RTE_BIT64(nr) (UINT64_C(1) << (nr))
37
44#define RTE_BIT32(nr) (UINT32_C(1) << (nr))
45
54#define RTE_SHIFT_VAL32(val, nr) ((uint32_t)(val) << (nr))
55
64#define RTE_SHIFT_VAL64(val, nr) ((uint64_t)(val) << (nr))
65
75#define RTE_GENMASK32(high, low) \
76 (((~UINT32_C(0)) << (low)) & (~UINT32_C(0) >> (31u - (high))))
77
87#define RTE_GENMASK64(high, low) \
88 (((~UINT64_C(0)) << (low)) & (~UINT64_C(0) >> (63u - (high))))
89
98#define RTE_FIELD_GET32(mask, reg) \
99 ((typeof(mask))(((reg) & (mask)) >> rte_ctz32(mask)))
100
109#define RTE_FIELD_GET64(mask, reg) \
110 ((typeof(mask))(((reg) & (mask)) >> rte_ctz64(mask)))
111
127#define rte_bit_test(addr, nr) \
128 _Generic((addr), \
129 uint32_t *: __rte_bit_test32, \
130 const uint32_t *: __rte_bit_test32, \
131 volatile uint32_t *: __rte_bit_v_test32, \
132 const volatile uint32_t *: __rte_bit_v_test32, \
133 uint64_t *: __rte_bit_test64, \
134 const uint64_t *: __rte_bit_test64, \
135 volatile uint64_t *: __rte_bit_v_test64, \
136 const volatile uint64_t *: __rte_bit_v_test64) \
137 (addr, nr)
138
154#define rte_bit_set(addr, nr) \
155 _Generic((addr), \
156 uint32_t *: __rte_bit_set32, \
157 volatile uint32_t *: __rte_bit_v_set32, \
158 uint64_t *: __rte_bit_set64, \
159 volatile uint64_t *: __rte_bit_v_set64) \
160 (addr, nr)
161
177#define rte_bit_clear(addr, nr) \
178 _Generic((addr), \
179 uint32_t *: __rte_bit_clear32, \
180 volatile uint32_t *: __rte_bit_v_clear32, \
181 uint64_t *: __rte_bit_clear64, \
182 volatile uint64_t *: __rte_bit_v_clear64) \
183 (addr, nr)
184
201#define rte_bit_assign(addr, nr, value) \
202 _Generic((addr), \
203 uint32_t *: __rte_bit_assign32, \
204 volatile uint32_t *: __rte_bit_v_assign32, \
205 uint64_t *: __rte_bit_assign64, \
206 volatile uint64_t *: __rte_bit_v_assign64) \
207 (addr, nr, value)
208
224#define rte_bit_flip(addr, nr) \
225 _Generic((addr), \
226 uint32_t *: __rte_bit_flip32, \
227 volatile uint32_t *: __rte_bit_v_flip32, \
228 uint64_t *: __rte_bit_flip64, \
229 volatile uint64_t *: __rte_bit_v_flip64) \
230 (addr, nr)
231
248#define rte_bit_atomic_test(addr, nr, memory_order) \
249 _Generic((addr), \
250 uint32_t *: __rte_bit_atomic_test32, \
251 const uint32_t *: __rte_bit_atomic_test32, \
252 volatile uint32_t *: __rte_bit_atomic_v_test32, \
253 const volatile uint32_t *: __rte_bit_atomic_v_test32, \
254 uint64_t *: __rte_bit_atomic_test64, \
255 const uint64_t *: __rte_bit_atomic_test64, \
256 volatile uint64_t *: __rte_bit_atomic_v_test64, \
257 const volatile uint64_t *: __rte_bit_atomic_v_test64) \
258 (addr, nr, memory_order)
259
274#define rte_bit_atomic_set(addr, nr, memory_order) \
275 _Generic((addr), \
276 uint32_t *: __rte_bit_atomic_set32, \
277 volatile uint32_t *: __rte_bit_atomic_v_set32, \
278 uint64_t *: __rte_bit_atomic_set64, \
279 volatile uint64_t *: __rte_bit_atomic_v_set64) \
280 (addr, nr, memory_order)
281
296#define rte_bit_atomic_clear(addr, nr, memory_order) \
297 _Generic((addr), \
298 uint32_t *: __rte_bit_atomic_clear32, \
299 volatile uint32_t *: __rte_bit_atomic_v_clear32, \
300 uint64_t *: __rte_bit_atomic_clear64, \
301 volatile uint64_t *: __rte_bit_atomic_v_clear64) \
302 (addr, nr, memory_order)
303
320#define rte_bit_atomic_assign(addr, nr, value, memory_order) \
321 _Generic((addr), \
322 uint32_t *: __rte_bit_atomic_assign32, \
323 volatile uint32_t *: __rte_bit_atomic_v_assign32, \
324 uint64_t *: __rte_bit_atomic_assign64, \
325 volatile uint64_t *: __rte_bit_atomic_v_assign64) \
326 (addr, nr, value, memory_order)
327
343#define rte_bit_atomic_flip(addr, nr, memory_order) \
344 _Generic((addr), \
345 uint32_t *: __rte_bit_atomic_flip32, \
346 volatile uint32_t *: __rte_bit_atomic_v_flip32, \
347 uint64_t *: __rte_bit_atomic_flip64, \
348 volatile uint64_t *: __rte_bit_atomic_v_flip64) \
349 (addr, nr, memory_order)
350
367#define rte_bit_atomic_test_and_set(addr, nr, memory_order) \
368 _Generic((addr), \
369 uint32_t *: __rte_bit_atomic_test_and_set32, \
370 volatile uint32_t *: __rte_bit_atomic_v_test_and_set32, \
371 uint64_t *: __rte_bit_atomic_test_and_set64, \
372 volatile uint64_t *: __rte_bit_atomic_v_test_and_set64) \
373 (addr, nr, memory_order)
374
391#define rte_bit_atomic_test_and_clear(addr, nr, memory_order) \
392 _Generic((addr), \
393 uint32_t *: __rte_bit_atomic_test_and_clear32, \
394 volatile uint32_t *: __rte_bit_atomic_v_test_and_clear32, \
395 uint64_t *: __rte_bit_atomic_test_and_clear64, \
396 volatile uint64_t *: __rte_bit_atomic_v_test_and_clear64) \
397 (addr, nr, memory_order)
398
418#define rte_bit_atomic_test_and_assign(addr, nr, value, memory_order) \
419 _Generic((addr), \
420 uint32_t *: __rte_bit_atomic_test_and_assign32, \
421 volatile uint32_t *: __rte_bit_atomic_v_test_and_assign32, \
422 uint64_t *: __rte_bit_atomic_test_and_assign64, \
423 volatile uint64_t *: __rte_bit_atomic_v_test_and_assign64) \
424 (addr, nr, value, memory_order)
425
426#define __RTE_GEN_BIT_TEST(variant, qualifier, size) \
427static inline bool \
428__rte_bit_ ## variant ## test ## size(const qualifier uint ## size ## _t *addr, unsigned int nr) \
429{ \
430 RTE_ASSERT(nr < size); \
431 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
432 return *addr & mask; \
433}
434
435#define __RTE_GEN_BIT_SET(variant, qualifier, size) \
436static inline void \
437__rte_bit_ ## variant ## set ## size(qualifier uint ## size ## _t *addr, unsigned int nr) \
438{ \
439 RTE_ASSERT(nr < size); \
440 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
441 *addr |= mask; \
442}
443
444#define __RTE_GEN_BIT_CLEAR(variant, qualifier, size) \
445static inline void \
446__rte_bit_ ## variant ## clear ## size(qualifier uint ## size ## _t *addr, unsigned int nr) \
447{ \
448 RTE_ASSERT(nr < size); \
449 uint ## size ## _t mask = ~((uint ## size ## _t)1 << nr); \
450 (*addr) &= mask; \
451}
452
453#define __RTE_GEN_BIT_ASSIGN(variant, qualifier, size) \
454static inline void \
455__rte_bit_ ## variant ## assign ## size(qualifier uint ## size ## _t *addr, unsigned int nr, \
456 bool value) \
457{ \
458 if (value) \
459 __rte_bit_ ## variant ## set ## size(addr, nr); \
460 else \
461 __rte_bit_ ## variant ## clear ## size(addr, nr); \
462}
463
464#define __RTE_GEN_BIT_FLIP(variant, qualifier, size) \
465static inline void \
466__rte_bit_ ## variant ## flip ## size(qualifier uint ## size ## _t *addr, unsigned int nr) \
467{ \
468 bool value; \
469 value = __rte_bit_ ## variant ## test ## size(addr, nr); \
470 __rte_bit_ ## variant ## assign ## size(addr, nr, !value); \
471}
472
473#define __RTE_GEN_BIT_OPS(v, qualifier, size) \
474 __RTE_GEN_BIT_TEST(v, qualifier, size) \
475 __RTE_GEN_BIT_SET(v, qualifier, size) \
476 __RTE_GEN_BIT_CLEAR(v, qualifier, size) \
477 __RTE_GEN_BIT_ASSIGN(v, qualifier, size) \
478 __RTE_GEN_BIT_FLIP(v, qualifier, size)
479
480#define __RTE_GEN_BIT_OPS_SIZE(size) \
481 __RTE_GEN_BIT_OPS(,, size) \
482 __RTE_GEN_BIT_OPS(v_, volatile, size)
483
484__RTE_GEN_BIT_OPS_SIZE(32)
485__RTE_GEN_BIT_OPS_SIZE(64)
486
487#define __RTE_GEN_BIT_ATOMIC_TEST(variant, qualifier, size) \
488static inline bool \
489__rte_bit_atomic_ ## variant ## test ## size(const qualifier uint ## size ## _t *addr, \
490 unsigned int nr, int memory_order) \
491{ \
492 RTE_ASSERT(nr < size); \
493 const qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
494 (const qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
495 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
496 return rte_atomic_load_explicit(a_addr, memory_order) & mask; \
497}
498
499#define __RTE_GEN_BIT_ATOMIC_SET(variant, qualifier, size) \
500static inline void \
501__rte_bit_atomic_ ## variant ## set ## size(qualifier uint ## size ## _t *addr, \
502 unsigned int nr, int memory_order) \
503{ \
504 RTE_ASSERT(nr < size); \
505 qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
506 (qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
507 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
508 rte_atomic_fetch_or_explicit(a_addr, mask, memory_order); \
509}
510
511#define __RTE_GEN_BIT_ATOMIC_CLEAR(variant, qualifier, size) \
512static inline void \
513__rte_bit_atomic_ ## variant ## clear ## size(qualifier uint ## size ## _t *addr, \
514 unsigned int nr, int memory_order) \
515{ \
516 RTE_ASSERT(nr < size); \
517 qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
518 (qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
519 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
520 rte_atomic_fetch_and_explicit(a_addr, ~mask, memory_order); \
521}
522
523#define __RTE_GEN_BIT_ATOMIC_FLIP(variant, qualifier, size) \
524static inline void \
525__rte_bit_atomic_ ## variant ## flip ## size(qualifier uint ## size ## _t *addr, \
526 unsigned int nr, int memory_order) \
527{ \
528 RTE_ASSERT(nr < size); \
529 qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
530 (qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
531 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
532 rte_atomic_fetch_xor_explicit(a_addr, mask, memory_order); \
533}
534
535#define __RTE_GEN_BIT_ATOMIC_ASSIGN(variant, qualifier, size) \
536static inline void \
537__rte_bit_atomic_## variant ## assign ## size(qualifier uint ## size ## _t *addr, \
538 unsigned int nr, bool value, int memory_order) \
539{ \
540 if (value) \
541 __rte_bit_atomic_ ## variant ## set ## size(addr, nr, memory_order); \
542 else \
543 __rte_bit_atomic_ ## variant ## clear ## size(addr, nr, memory_order); \
544}
545
546#define __RTE_GEN_BIT_ATOMIC_TEST_AND_SET(variant, qualifier, size) \
547static inline bool \
548__rte_bit_atomic_ ## variant ## test_and_set ## size(qualifier uint ## size ## _t *addr, \
549 unsigned int nr, int memory_order) \
550{ \
551 RTE_ASSERT(nr < size); \
552 qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
553 (qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
554 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
555 uint ## size ## _t prev; \
556 prev = rte_atomic_fetch_or_explicit(a_addr, mask, memory_order); \
557 return prev & mask; \
558}
559
560#define __RTE_GEN_BIT_ATOMIC_TEST_AND_CLEAR(variant, qualifier, size) \
561static inline bool \
562__rte_bit_atomic_ ## variant ## test_and_clear ## size(qualifier uint ## size ## _t *addr, \
563 unsigned int nr, int memory_order) \
564{ \
565 RTE_ASSERT(nr < size); \
566 qualifier RTE_ATOMIC(uint ## size ## _t) *a_addr = \
567 (qualifier RTE_ATOMIC(uint ## size ## _t) *)addr; \
568 uint ## size ## _t mask = (uint ## size ## _t)1 << nr; \
569 uint ## size ## _t prev; \
570 prev = rte_atomic_fetch_and_explicit(a_addr, ~mask, memory_order); \
571 return prev & mask; \
572}
573
574#define __RTE_GEN_BIT_ATOMIC_TEST_AND_ASSIGN(variant, qualifier, size) \
575static inline bool \
576__rte_bit_atomic_ ## variant ## test_and_assign ## size( \
577 qualifier uint ## size ## _t *addr, unsigned int nr, bool value, \
578 int memory_order) \
579{ \
580 if (value) \
581 return __rte_bit_atomic_ ## variant ## test_and_set ## size(addr, nr, \
582 memory_order); \
583 else \
584 return __rte_bit_atomic_ ## variant ## test_and_clear ## size(addr, nr, \
585 memory_order); \
586}
587
588#define __RTE_GEN_BIT_ATOMIC_OPS(variant, qualifier, size) \
589 __RTE_GEN_BIT_ATOMIC_TEST(variant, qualifier, size) \
590 __RTE_GEN_BIT_ATOMIC_SET(variant, qualifier, size) \
591 __RTE_GEN_BIT_ATOMIC_CLEAR(variant, qualifier, size) \
592 __RTE_GEN_BIT_ATOMIC_ASSIGN(variant, qualifier, size) \
593 __RTE_GEN_BIT_ATOMIC_TEST_AND_SET(variant, qualifier, size) \
594 __RTE_GEN_BIT_ATOMIC_TEST_AND_CLEAR(variant, qualifier, size) \
595 __RTE_GEN_BIT_ATOMIC_TEST_AND_ASSIGN(variant, qualifier, size) \
596 __RTE_GEN_BIT_ATOMIC_FLIP(variant, qualifier, size)
597
598#define __RTE_GEN_BIT_ATOMIC_OPS_SIZE(size) \
599 __RTE_GEN_BIT_ATOMIC_OPS(,, size) \
600 __RTE_GEN_BIT_ATOMIC_OPS(v_, volatile, size)
601
602__RTE_GEN_BIT_ATOMIC_OPS_SIZE(32)
603__RTE_GEN_BIT_ATOMIC_OPS_SIZE(64)
604
605/*------------------------ 32-bit relaxed operations ------------------------*/
606
617static inline uint32_t
618rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
619{
620 RTE_ASSERT(nr < 32);
621
622 uint32_t mask = UINT32_C(1) << nr;
623 return (*addr) & mask;
624}
625
634static inline void
635rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
636{
637 RTE_ASSERT(nr < 32);
638
639 uint32_t mask = RTE_BIT32(nr);
640 *addr = (*addr) | mask;
641}
642
651static inline void
652rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
653{
654 RTE_ASSERT(nr < 32);
655
656 uint32_t mask = RTE_BIT32(nr);
657 *addr = (*addr) & (~mask);
658}
659
671static inline uint32_t
672rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
673{
674 RTE_ASSERT(nr < 32);
675
676 uint32_t mask = RTE_BIT32(nr);
677 uint32_t val = *addr;
678 *addr = val | mask;
679 return val & mask;
680}
681
693static inline uint32_t
694rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
695{
696 RTE_ASSERT(nr < 32);
697
698 uint32_t mask = RTE_BIT32(nr);
699 uint32_t val = *addr;
700 *addr = val & (~mask);
701 return val & mask;
702}
703
704/*------------------------ 64-bit relaxed operations ------------------------*/
705
716static inline uint64_t
717rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
718{
719 RTE_ASSERT(nr < 64);
720
721 uint64_t mask = RTE_BIT64(nr);
722 return (*addr) & mask;
723}
724
733static inline void
734rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
735{
736 RTE_ASSERT(nr < 64);
737
738 uint64_t mask = RTE_BIT64(nr);
739 (*addr) = (*addr) | mask;
740}
741
750static inline void
751rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
752{
753 RTE_ASSERT(nr < 64);
754
755 uint64_t mask = RTE_BIT64(nr);
756 *addr = (*addr) & (~mask);
757}
758
770static inline uint64_t
771rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
772{
773 RTE_ASSERT(nr < 64);
774
775 uint64_t mask = RTE_BIT64(nr);
776 uint64_t val = *addr;
777 *addr = val | mask;
778 return val;
779}
780
792static inline uint64_t
793rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
794{
795 RTE_ASSERT(nr < 64);
796
797 uint64_t mask = RTE_BIT64(nr);
798 uint64_t val = *addr;
799 *addr = val & (~mask);
800 return val & mask;
801}
802
803#ifdef RTE_TOOLCHAIN_MSVC
804
813static inline unsigned int
814rte_clz32(uint32_t v)
815{
816 unsigned long rv;
817
818 (void)_BitScanReverse(&rv, v);
819
820 return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv);
821}
822
831static inline unsigned int
832rte_clz64(uint64_t v)
833{
834 unsigned long rv;
835
836 (void)_BitScanReverse64(&rv, v);
837
838 return (unsigned int)(sizeof(v) * CHAR_BIT - 1 - rv);
839}
840
849static inline unsigned int
850rte_ctz32(uint32_t v)
851{
852 unsigned long rv;
853
854 (void)_BitScanForward(&rv, v);
855
856 return (unsigned int)rv;
857}
858
867static inline unsigned int
868rte_ctz64(uint64_t v)
869{
870 unsigned long rv;
871
872 (void)_BitScanForward64(&rv, v);
873
874 return (unsigned int)rv;
875}
876
885static inline unsigned int
886rte_popcount32(uint32_t v)
887{
888 return (unsigned int)__popcnt(v);
889}
890
899static inline unsigned int
900rte_popcount64(uint64_t v)
901{
902 return (unsigned int)__popcnt64(v);
903}
904
917__rte_experimental
918static inline unsigned int
919rte_ffs32(uint32_t v)
920{
921 unsigned long rv;
922
923 if (_BitScanForward(&rv, v) == 0)
924 return 0;
925
926 return (unsigned int)rv + 1;
927}
928
941__rte_experimental
942static inline unsigned int
943rte_ffs64(uint64_t v)
944{
945 unsigned long rv;
946
947 if (_BitScanForward64(&rv, v) == 0)
948 return 0;
949
950 return (unsigned int)rv + 1;
951}
952
953#else
954
963static inline unsigned int
964rte_clz32(uint32_t v)
965{
966 return (unsigned int)__builtin_clz(v);
967}
968
977static inline unsigned int
978rte_clz64(uint64_t v)
979{
980 return (unsigned int)__builtin_clzll(v);
981}
982
991static inline unsigned int
992rte_ctz32(uint32_t v)
993{
994 return (unsigned int)__builtin_ctz(v);
995}
996
1005static inline unsigned int
1006rte_ctz64(uint64_t v)
1007{
1008 return (unsigned int)__builtin_ctzll(v);
1009}
1010
1019static inline unsigned int
1021{
1022 return (unsigned int)__builtin_popcount(v);
1023}
1024
1033static inline unsigned int
1035{
1036 return (unsigned int)__builtin_popcountll(v);
1037}
1038
1051__rte_experimental
1052static inline unsigned int
1053rte_ffs32(uint32_t v)
1054{
1055 return (unsigned int)__builtin_ffs(v);
1056}
1057
1070__rte_experimental
1071static inline unsigned int
1072rte_ffs64(uint64_t v)
1073{
1074 return (unsigned int)__builtin_ffsll(v);
1075}
1076
1077#endif
1078
1089static inline uint32_t
1091{
1092 x |= x >> 1;
1093 x |= x >> 2;
1094 x |= x >> 4;
1095 x |= x >> 8;
1096 x |= x >> 16;
1097
1098 return x;
1099}
1100
1111static inline uint64_t
1113{
1114 v |= v >> 1;
1115 v |= v >> 2;
1116 v |= v >> 4;
1117 v |= v >> 8;
1118 v |= v >> 16;
1119 v |= v >> 32;
1120
1121 return v;
1122}
1123
1135static inline uint32_t
1136rte_bsf32(uint32_t v)
1137{
1138 return (uint32_t)rte_ctz32(v);
1139}
1140
1155static inline int
1156rte_bsf32_safe(uint32_t v, uint32_t *pos)
1157{
1158 if (v == 0)
1159 return 0;
1160
1161 *pos = rte_bsf32(v);
1162 return 1;
1163}
1164
1176static inline uint32_t
1177rte_bsf64(uint64_t v)
1178{
1179 return (uint32_t)rte_ctz64(v);
1180}
1181
1196static inline int
1197rte_bsf64_safe(uint64_t v, uint32_t *pos)
1198{
1199 if (v == 0)
1200 return 0;
1201
1202 *pos = rte_bsf64(v);
1203 return 1;
1204}
1205
1217static inline uint32_t
1218rte_fls_u32(uint32_t x)
1219{
1220 return (x == 0) ? 0 : 32 - rte_clz32(x);
1221}
1222
1235static inline uint32_t
1236rte_fls_u64(uint64_t x)
1237{
1238 return (x == 0) ? 0 : 64 - rte_clz64(x);
1239}
1240
1241/*********** Macros to work with powers of 2 ********/
1242
1246#define RTE_IS_POWER_OF_2(n) ((n) != 0 && (((n) - 1) & (n)) == 0)
1247
1254static inline int
1256{
1257 return n && !(n & (n - 1));
1258}
1259
1269static inline uint32_t
1271{
1272 x--;
1273 x = rte_combine32ms1b(x);
1274
1275 return x + 1;
1276}
1277
1287static inline uint32_t
1289{
1290 x = rte_combine32ms1b(x);
1291
1292 return x - (x >> 1);
1293}
1294
1304static inline uint64_t
1306{
1307 v--;
1308 v = rte_combine64ms1b(v);
1309
1310 return v + 1;
1311}
1312
1322static inline uint64_t
1324{
1325 v = rte_combine64ms1b(v);
1326
1327 return v - (v >> 1);
1328}
1329
1341static inline uint32_t
1342rte_log2_u32(uint32_t v)
1343{
1344 if (v == 0)
1345 return 0;
1346 v = rte_align32pow2(v);
1347 return rte_bsf32(v);
1348}
1349
1361static inline uint32_t
1362rte_log2_u64(uint64_t v)
1363{
1364 if (v == 0)
1365 return 0;
1366 v = rte_align64pow2(v);
1367 /* we checked for v being 0 already, so no undefined behavior */
1368 return rte_bsf64(v);
1369}
1370
1371#ifdef __cplusplus
1372}
1373
1374/*
1375 * Since C++ doesn't support generic selection (i.e., _Generic),
1376 * function overloading is used instead. Such functions must be
1377 * defined outside 'extern "C"' to be accepted by the compiler.
1378 */
1379
1380#undef rte_bit_test
1381#undef rte_bit_set
1382#undef rte_bit_clear
1383#undef rte_bit_assign
1384#undef rte_bit_flip
1385
1386#undef rte_bit_atomic_test
1387#undef rte_bit_atomic_set
1388#undef rte_bit_atomic_clear
1389#undef rte_bit_atomic_assign
1390#undef rte_bit_atomic_flip
1391#undef rte_bit_atomic_test_and_set
1392#undef rte_bit_atomic_test_and_clear
1393#undef rte_bit_atomic_test_and_assign
1394
1395#define __RTE_BIT_OVERLOAD_V_2(family, v, fun, qualifier, size, arg1_type, arg1_name) \
1396static inline void \
1397rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name) \
1398{ \
1399 __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name); \
1400}
1401
1402#define __RTE_BIT_OVERLOAD_SZ_2(family, fun, qualifier, size, arg1_type, arg1_name) \
1403 __RTE_BIT_OVERLOAD_V_2(family,, fun, qualifier, size, arg1_type, arg1_name) \
1404 __RTE_BIT_OVERLOAD_V_2(family, v_, fun, qualifier volatile, size, arg1_type, arg1_name)
1405
1406#define __RTE_BIT_OVERLOAD_2(family, fun, qualifier, arg1_type, arg1_name) \
1407 __RTE_BIT_OVERLOAD_SZ_2(family, fun, qualifier, 32, arg1_type, arg1_name) \
1408 __RTE_BIT_OVERLOAD_SZ_2(family, fun, qualifier, 64, arg1_type, arg1_name)
1409
1410#define __RTE_BIT_OVERLOAD_V_2R(family, v, fun, qualifier, size, ret_type, arg1_type, arg1_name) \
1411static inline ret_type \
1412rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name) \
1413{ \
1414 return __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name); \
1415}
1416
1417#define __RTE_BIT_OVERLOAD_SZ_2R(family, fun, qualifier, size, ret_type, arg1_type, arg1_name) \
1418 __RTE_BIT_OVERLOAD_V_2R(family,, fun, qualifier, size, ret_type, arg1_type, arg1_name) \
1419 __RTE_BIT_OVERLOAD_V_2R(family, v_, fun, qualifier volatile, size, ret_type, arg1_type, \
1420 arg1_name)
1421
1422#define __RTE_BIT_OVERLOAD_2R(family, fun, qualifier, ret_type, arg1_type, arg1_name) \
1423 __RTE_BIT_OVERLOAD_SZ_2R(family, fun, qualifier, 32, ret_type, arg1_type, arg1_name) \
1424 __RTE_BIT_OVERLOAD_SZ_2R(family, fun, qualifier, 64, ret_type, arg1_type, arg1_name)
1425
1426#define __RTE_BIT_OVERLOAD_V_3(family, v, fun, qualifier, size, arg1_type, arg1_name, \
1427 arg2_type, arg2_name) \
1428static inline void \
1429rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name, \
1430 arg2_type arg2_name) \
1431{ \
1432 __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name, arg2_name); \
1433}
1434
1435#define __RTE_BIT_OVERLOAD_SZ_3(family, fun, qualifier, size, arg1_type, arg1_name, \
1436 arg2_type, arg2_name) \
1437 __RTE_BIT_OVERLOAD_V_3(family,, fun, qualifier, size, arg1_type, arg1_name, \
1438 arg2_type, arg2_name) \
1439 __RTE_BIT_OVERLOAD_V_3(family, v_, fun, qualifier volatile, size, arg1_type, arg1_name, \
1440 arg2_type, arg2_name)
1441
1442#define __RTE_BIT_OVERLOAD_3(family, fun, qualifier, arg1_type, arg1_name, arg2_type, arg2_name) \
1443 __RTE_BIT_OVERLOAD_SZ_3(family, fun, qualifier, 32, arg1_type, arg1_name, \
1444 arg2_type, arg2_name) \
1445 __RTE_BIT_OVERLOAD_SZ_3(family, fun, qualifier, 64, arg1_type, arg1_name, \
1446 arg2_type, arg2_name)
1447
1448#define __RTE_BIT_OVERLOAD_V_3R(family, v, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1449 arg2_type, arg2_name) \
1450static inline ret_type \
1451rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name, \
1452 arg2_type arg2_name) \
1453{ \
1454 return __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name, arg2_name); \
1455}
1456
1457#define __RTE_BIT_OVERLOAD_SZ_3R(family, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1458 arg2_type, arg2_name) \
1459 __RTE_BIT_OVERLOAD_V_3R(family,, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1460 arg2_type, arg2_name) \
1461 __RTE_BIT_OVERLOAD_V_3R(family, v_, fun, qualifier volatile, size, ret_type, \
1462 arg1_type, arg1_name, arg2_type, arg2_name)
1463
1464#define __RTE_BIT_OVERLOAD_3R(family, fun, qualifier, ret_type, arg1_type, arg1_name, \
1465 arg2_type, arg2_name) \
1466 __RTE_BIT_OVERLOAD_SZ_3R(family, fun, qualifier, 32, ret_type, arg1_type, arg1_name, \
1467 arg2_type, arg2_name) \
1468 __RTE_BIT_OVERLOAD_SZ_3R(family, fun, qualifier, 64, ret_type, arg1_type, arg1_name, \
1469 arg2_type, arg2_name)
1470
1471#define __RTE_BIT_OVERLOAD_V_4(family, v, fun, qualifier, size, arg1_type, arg1_name, \
1472 arg2_type, arg2_name, arg3_type, arg3_name) \
1473static inline void \
1474rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name, \
1475 arg2_type arg2_name, arg3_type arg3_name) \
1476{ \
1477 __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name, arg2_name, arg3_name); \
1478}
1479
1480#define __RTE_BIT_OVERLOAD_SZ_4(family, fun, qualifier, size, arg1_type, arg1_name, \
1481 arg2_type, arg2_name, arg3_type, arg3_name) \
1482 __RTE_BIT_OVERLOAD_V_4(family,, fun, qualifier, size, arg1_type, arg1_name, \
1483 arg2_type, arg2_name, arg3_type, arg3_name) \
1484 __RTE_BIT_OVERLOAD_V_4(family, v_, fun, qualifier volatile, size, arg1_type, arg1_name, \
1485 arg2_type, arg2_name, arg3_type, arg3_name)
1486
1487#define __RTE_BIT_OVERLOAD_4(family, fun, qualifier, arg1_type, arg1_name, arg2_type, arg2_name, \
1488 arg3_type, arg3_name) \
1489 __RTE_BIT_OVERLOAD_SZ_4(family, fun, qualifier, 32, arg1_type, arg1_name, \
1490 arg2_type, arg2_name, arg3_type, arg3_name) \
1491 __RTE_BIT_OVERLOAD_SZ_4(family, fun, qualifier, 64, arg1_type, arg1_name, \
1492 arg2_type, arg2_name, arg3_type, arg3_name)
1493
1494#define __RTE_BIT_OVERLOAD_V_4R(family, v, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1495 arg2_type, arg2_name, arg3_type, arg3_name) \
1496static inline ret_type \
1497rte_bit_ ## family ## fun(qualifier uint ## size ## _t *addr, arg1_type arg1_name, \
1498 arg2_type arg2_name, arg3_type arg3_name) \
1499{ \
1500 return __rte_bit_ ## family ## v ## fun ## size(addr, arg1_name, arg2_name, \
1501 arg3_name); \
1502}
1503
1504#define __RTE_BIT_OVERLOAD_SZ_4R(family, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1505 arg2_type, arg2_name, arg3_type, arg3_name) \
1506 __RTE_BIT_OVERLOAD_V_4R(family,, fun, qualifier, size, ret_type, arg1_type, arg1_name, \
1507 arg2_type, arg2_name, arg3_type, arg3_name) \
1508 __RTE_BIT_OVERLOAD_V_4R(family, v_, fun, qualifier volatile, size, ret_type, \
1509 arg1_type, arg1_name, arg2_type, arg2_name, arg3_type, arg3_name)
1510
1511#define __RTE_BIT_OVERLOAD_4R(family, fun, qualifier, ret_type, arg1_type, arg1_name, \
1512 arg2_type, arg2_name, arg3_type, arg3_name) \
1513 __RTE_BIT_OVERLOAD_SZ_4R(family, fun, qualifier, 32, ret_type, arg1_type, arg1_name, \
1514 arg2_type, arg2_name, arg3_type, arg3_name) \
1515 __RTE_BIT_OVERLOAD_SZ_4R(family, fun, qualifier, 64, ret_type, arg1_type, arg1_name, \
1516 arg2_type, arg2_name, arg3_type, arg3_name)
1517
1518__RTE_BIT_OVERLOAD_2R(, test, const, bool, unsigned int, nr)
1519__RTE_BIT_OVERLOAD_2(, set,, unsigned int, nr)
1520__RTE_BIT_OVERLOAD_2(, clear,, unsigned int, nr)
1521__RTE_BIT_OVERLOAD_3(, assign,, unsigned int, nr, bool, value)
1522__RTE_BIT_OVERLOAD_2(, flip,, unsigned int, nr)
1523
1524__RTE_BIT_OVERLOAD_3R(atomic_, test, const, bool, unsigned int, nr, int, memory_order)
1525__RTE_BIT_OVERLOAD_3(atomic_, set,, unsigned int, nr, int, memory_order)
1526__RTE_BIT_OVERLOAD_3(atomic_, clear,, unsigned int, nr, int, memory_order)
1527__RTE_BIT_OVERLOAD_4(atomic_, assign,, unsigned int, nr, bool, value, int, memory_order)
1528__RTE_BIT_OVERLOAD_3(atomic_, flip,, unsigned int, nr, int, memory_order)
1529__RTE_BIT_OVERLOAD_3R(atomic_, test_and_set,, bool, unsigned int, nr, int, memory_order)
1530__RTE_BIT_OVERLOAD_3R(atomic_, test_and_clear,, bool, unsigned int, nr, int, memory_order)
1531__RTE_BIT_OVERLOAD_4R(atomic_, test_and_assign,, bool, unsigned int, nr, bool, value,
1532 int, memory_order)
1533
1534#endif
1535
1536#endif /* _RTE_BITOPS_H_ */
#define RTE_BIT64(nr)
Definition: rte_bitops.h:36
static void rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
Definition: rte_bitops.h:635
static __rte_experimental unsigned int rte_ffs64(uint64_t v)
Definition: rte_bitops.h:1072
static uint32_t rte_log2_u32(uint32_t v)
Definition: rte_bitops.h:1342
static uint32_t rte_fls_u32(uint32_t x)
Definition: rte_bitops.h:1218
static void rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
Definition: rte_bitops.h:751
static int rte_bsf32_safe(uint32_t v, uint32_t *pos)
Definition: rte_bitops.h:1156
#define RTE_BIT32(nr)
Definition: rte_bitops.h:44
static uint64_t rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
Definition: rte_bitops.h:793
static uint32_t rte_bsf64(uint64_t v)
Definition: rte_bitops.h:1177
static unsigned int rte_clz32(uint32_t v)
Definition: rte_bitops.h:964
static uint32_t rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
Definition: rte_bitops.h:672
static uint32_t rte_align32pow2(uint32_t x)
Definition: rte_bitops.h:1270
static uint32_t rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
Definition: rte_bitops.h:694
static unsigned int rte_popcount32(uint32_t v)
Definition: rte_bitops.h:1020
static uint32_t rte_align32prevpow2(uint32_t x)
Definition: rte_bitops.h:1288
static uint64_t rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
Definition: rte_bitops.h:771
static uint64_t rte_align64pow2(uint64_t v)
Definition: rte_bitops.h:1305
static unsigned int rte_ctz64(uint64_t v)
Definition: rte_bitops.h:1006
static uint32_t rte_bsf32(uint32_t v)
Definition: rte_bitops.h:1136
static int rte_bsf64_safe(uint64_t v, uint32_t *pos)
Definition: rte_bitops.h:1197
static uint64_t rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
Definition: rte_bitops.h:717
static unsigned int rte_popcount64(uint64_t v)
Definition: rte_bitops.h:1034
static unsigned int rte_ctz32(uint32_t v)
Definition: rte_bitops.h:992
static uint64_t rte_align64prevpow2(uint64_t v)
Definition: rte_bitops.h:1323
static unsigned int rte_clz64(uint64_t v)
Definition: rte_bitops.h:978
static void rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
Definition: rte_bitops.h:652
static uint32_t rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
Definition: rte_bitops.h:618
static void rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
Definition: rte_bitops.h:734
static int rte_is_power_of_2(uint32_t n)
Definition: rte_bitops.h:1255
static uint64_t rte_combine64ms1b(uint64_t v)
Definition: rte_bitops.h:1112
static uint32_t rte_combine32ms1b(uint32_t x)
Definition: rte_bitops.h:1090
static __rte_experimental unsigned int rte_ffs32(uint32_t v)
Definition: rte_bitops.h:1053
static uint32_t rte_log2_u64(uint64_t v)
Definition: rte_bitops.h:1362
static uint32_t rte_fls_u64(uint64_t x)
Definition: rte_bitops.h:1236