1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Arm Limited
12 * This file defines a family of APIs for bit operations
13 * without enforcing memory ordering.
17 #include <rte_debug.h>
18 #include <rte_compat.h>
20 /*------------------------ 32-bit relaxed operations ------------------------*/
24 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
26 * Get the target bit from a 32-bit value without memory ordering.
29 * The target bit to get.
31 * The address holding the bit.
36 static inline uint32_t
37 rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
41 uint32_t mask = UINT32_C(1) << nr;
42 return (*addr) & mask;
47 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
49 * Set the target bit in a 32-bit value to 1 without memory ordering.
52 * The target bit to set.
54 * The address holding the bit.
58 rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
62 uint32_t mask = UINT32_C(1) << nr;
63 *addr = (*addr) | mask;
68 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
70 * Clear the target bit in a 32-bit value to 0 without memory ordering.
73 * The target bit to clear.
75 * The address holding the bit.
79 rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
83 uint32_t mask = UINT32_C(1) << nr;
84 *addr = (*addr) & (~mask);
89 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
91 * Return the original bit from a 32-bit value, then set it to 1 without
95 * The target bit to get and set.
97 * The address holding the bit.
102 static inline uint32_t
103 rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
107 uint32_t mask = UINT32_C(1) << nr;
108 uint32_t val = *addr;
115 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
117 * Return the original bit from a 32-bit value, then clear it to 0 without
121 * The target bit to get and clear.
123 * The address holding the bit.
128 static inline uint32_t
129 rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
133 uint32_t mask = UINT32_C(1) << nr;
134 uint32_t val = *addr;
135 *addr = val & (~mask);
139 /*------------------------ 64-bit relaxed operations ------------------------*/
143 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
145 * Get the target bit from a 64-bit value without memory ordering.
148 * The target bit to get.
150 * The address holding the bit.
155 static inline uint64_t
156 rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
160 uint64_t mask = UINT64_C(1) << nr;
161 return (*addr) & mask;
166 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
168 * Set the target bit in a 64-bit value to 1 without memory ordering.
171 * The target bit to set.
173 * The address holding the bit.
177 rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
181 uint64_t mask = UINT64_C(1) << nr;
182 (*addr) = (*addr) | mask;
187 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
189 * Clear the target bit in a 64-bit value to 0 without memory ordering.
192 * The target bit to clear.
194 * The address holding the bit.
198 rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
202 uint64_t mask = UINT64_C(1) << nr;
203 *addr = (*addr) & (~mask);
208 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
210 * Return the original bit from a 64-bit value, then set it to 1 without
214 * The target bit to get and set.
216 * The address holding the bit.
221 static inline uint64_t
222 rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
226 uint64_t mask = UINT64_C(1) << nr;
227 uint64_t val = *addr;
234 * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
236 * Return the original bit from a 64-bit value, then clear it to 0 without
240 * The target bit to get and clear.
242 * The address holding the bit.
247 static inline uint64_t
248 rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
252 uint64_t mask = UINT64_C(1) << nr;
253 uint64_t val = *addr;
254 *addr = val & (~mask);
258 #endif /* _RTE_BITOPS_H_ */