Software APIs
bitfield.h
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
6#define OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_
7
8#include <stdbool.h>
9#include <stdint.h>
10
12
13#ifdef __cplusplus
14extern "C" {
15#endif // __cplusplus
16
17/**
18 * @file
19 * @brief Bitfield Manipulation Functions
20 */
21
22/**
23 * A field of a 32-bit bitfield.
24 *
25 * The following field definition: `{ .mask = 0b11, .index = 12 }`
26 *
27 * Denotes the X-marked bits in the following 32-bit bitfield:
28 *
29 * field: 0b--------'--------'--XX----'--------
30 * index: 31 0
31 *
32 * Restrictions: The index plus the width of the mask must not be greater than
33 * 31.
34 */
35typedef struct bitfield_field32 {
36 /** The field mask. Usually all ones. */
37 uint32_t mask;
38 /** The field position in the bitfield, counting from the zero-bit. */
39 uint32_t index;
41
42/**
43 * Reads a value from `field` in `bitfield`.
44 *
45 * This function uses the `field` parameter to read the value from `bitfield`.
46 * The resulting value will be shifted right and zero-extended so the field's
47 * zero-bit is the return value's zero-bit.
48 *
49 * @param bitfield Bitfield to get the field from.
50 * @param field Field to read out from.
51 * @return Zero-extended `field` from `bitfield`.
52 */
54inline uint32_t bitfield_field32_read(uint32_t bitfield,
55 bitfield_field32_t field) {
56 return (bitfield >> field.index) & field.mask;
57}
58
59/**
60 * Writes `value` to `field` in `bitfield`.
61 *
62 * This function uses the `field` parameter to set specific bits in `bitfield`.
63 * The relevant portion of `bitfield` is zeroed before the bits are set to
64 * `value`.
65 *
66 * @param bitfield Bitfield to set the field in.
67 * @param field Field within bitfield to be set.
68 * @param value Value for the new field.
69 * @return `bitfield` with `field` set to `value`.
70 */
72inline uint32_t bitfield_field32_write(uint32_t bitfield,
74 uint32_t value) {
75 bitfield &= ~(field.mask << field.index);
76 bitfield |= (value & field.mask) << field.index;
77 return bitfield;
78}
79
80/**
81 * A single bit in a 32-bit bitfield.
82 *
83 * This denotes the position of a single bit, counting from the zero-bit.
84 *
85 * For instance, `(bitfield_bit_index_t)4` denotes the X-marked bit in the
86 * following 32-bit bitfield:
87 *
88 * field: 0b--------'--------'--------'---X----
89 * index: 31 0
90 *
91 * Restrictions: The value must not be greater than 31.
92 */
93typedef uint32_t bitfield_bit32_index_t;
94
95/**
96 * Turns a `bitfield_bit32_index_t` into a `bitfield_field32_t` (which is more
97 * general).
98 *
99 * @param bit_index The corresponding single bit to turn into a field.
100 * @return A 1-bit field that corresponds to `bit_index`.
101 */
104 bitfield_bit32_index_t bit_index) {
105 return (bitfield_field32_t){
106 .mask = 0x1,
107 .index = bit_index,
108 };
109}
110
111/**
112 * Reads the `bit_index`th bit in `bitfield`.
113 *
114 * @param bitfield Bitfield to get the bit from.
115 * @param bit_index Bit to read.
116 * @return `true` if the bit was one, `false` otherwise.
117 */
119inline bool bitfield_bit32_read(uint32_t bitfield,
120 bitfield_bit32_index_t bit_index) {
121 return bitfield_field32_read(bitfield,
122 bitfield_bit32_to_field32(bit_index)) == 0x1u;
123}
124
125/**
126 * Writes `value` to the `bit_index`th bit in `bitfield`.
127 *
128 * @param bitfield Bitfield to update the bit in.
129 * @param bit_index Bit to update.
130 * @param value Bit value to write to `bitfield`.
131 * @return `bitfield` with the `bit_index`th bit set to `value`.
132 */
134inline uint32_t bitfield_bit32_write(uint32_t bitfield,
135 bitfield_bit32_index_t bit_index,
136 bool value) {
137 return bitfield_field32_write(bitfield, bitfield_bit32_to_field32(bit_index),
138 value ? 0x1u : 0x0u);
139}
140
141/**
142 * Copies a bit from one bit set to the other.
143 *
144 * @param dest Bitfield to write to.
145 * @param dest_bit Bit to write to.
146 * @param src Bitfield to read from.
147 * @param src_bit Bit to read from.
148 * @return `dest` with the copied bit applied.
149 */
151inline uint32_t bitfield_bit32_copy(uint32_t dest,
152 bitfield_bit32_index_t dest_bit,
153 uint32_t src,
154 bitfield_bit32_index_t src_bit) {
155 return bitfield_bit32_write(dest, dest_bit,
156 bitfield_bit32_read(src, src_bit));
157}
158
159/**
160 * Find First Set Bit
161 *
162 * Returns one plus the index of the least-significant 1-bit of a 32-bit word.
163 *
164 * For instance, `bitfield_find_first_set32(field)` of the below 32-bit value
165 * returns `5`.
166 *
167 * field: 0b00000000'00000000'11111111'00010000
168 * index: 31 0
169 *
170 * This is the canonical definition for the GCC/Clang builtin `__builtin_ffs`,
171 * and hence takes and returns a signed integer.
172 *
173 * @param bitfield Bitfield to find the first set bit in.
174 * @return One plus the index of the least-significant 1-bit of `bitfield`.
175 */
177inline int32_t bitfield_find_first_set32(int32_t bitfield) {
178 return __builtin_ffs(bitfield);
179}
180
181/**
182 * Count Leading Zeroes
183 *
184 * Returns the number of leading 0-bits in `bitfield`, starting at the most
185 * significant bit position. If `bitfield` is 0, the result is 32, to match the
186 * RISC-V B Extension.
187 *
188 * For instance, `bitfield_count_leading_zeroes32(field)` of the below 32-bit
189 * value returns `16`.
190 *
191 * field: 0b00000000'00000000'11111111'00010000
192 * index: 31 0
193 *
194 * This is the canonical definition for the GCC/Clang builtin `__builtin_clz`,
195 * and hence returns a signed integer.
196 *
197 * @param bitfield Bitfield to count leading 0-bits from.
198 * @return The number of leading 0-bits in `bitfield`.
199 */
201inline int32_t bitfield_count_leading_zeroes32(uint32_t bitfield) {
202 return (bitfield != 0) ? __builtin_clz(bitfield) : 32;
203}
204
205/**
206 * Count Trailing Zeroes
207 *
208 * Returns the number of trailing 0-bits in `bitfield`, starting at the least
209 * significant bit position. If `bitfield` is 0, the result is 32, to match the
210 * RISC-V B Extension.
211 *
212 * For instance, `bitfield_count_trailing_zeroes32(field)` of the below 32-bit
213 * value returns `4`.
214 *
215 * field: 0b00000000'00000000'11111111'00010000
216 * index: 31 0
217 *
218 * This is the canonical definition for the GCC/Clang builtin `__builtin_ctz`,
219 * and hence returns a signed integer.
220 *
221 * @param bitfield Bitfield to count trailing 0-bits from.
222 * @return The number of trailing 0-bits in `bitfield`.
223 */
225inline int32_t bitfield_count_trailing_zeroes32(uint32_t bitfield) {
226 return (bitfield != 0) ? __builtin_ctz(bitfield) : 32;
227}
228
229/**
230 * Count Set Bits
231 *
232 * Returns the number of 1-bits in `bitfield`.
233 *
234 * For instance, `bitfield_popcount32(field)` of the below 32-bit value returns
235 * `9`.
236 *
237 * field: 0b00000000'00000000'11111111'00010000
238 * index: 31 0
239 *
240 * This is the canonical definition for the GCC/Clang builtin
241 * `__builtin_popcount`, and hence returns a signed integer.
242 *
243 * @param bitfield Bitfield to count 1-bits from.
244 * @return The number of 1-bits in `bitfield`.
245 */
247inline int32_t bitfield_popcount32(uint32_t bitfield) {
248 return __builtin_popcount(bitfield);
249}
250
251/**
252 * Parity
253 *
254 * Returns the number of 1-bits in `bitfield`, modulo 2.
255 *
256 * For instance, `bitfield_parity32(field)` of the below 32-bit value returns
257 * `1`.
258 *
259 * field: 0b00000000'00000000'11111111'00010000
260 * index: 31 0
261 *
262 * This is the canonical definition for the GCC/Clang builtin
263 * `__builtin_parity`, and hence returns a signed integer.
264 *
265 * @param bitfield Bitfield to count 1-bits from.
266 * @return The number of 1-bits in `bitfield`, modulo 2.
267 */
269inline int32_t bitfield_parity32(uint32_t bitfield) {
270 return __builtin_parity(bitfield);
271}
272
273/**
274 * Byte Swap
275 *
276 * Returns `field` with the order of the bytes reversed. Bytes here always means
277 * exactly 8 bits.
278 *
279 * For instance, `byteswap(field)` of the below 32-bit value returns `1`.
280 *
281 * field: 0bAAAAAAAA'BBBBBBBB'CCCCCCCC'DDDDDDDD
282 * index: 31 0
283 * returns: 0bDDDDDDDD'CCCCCCCC'BBBBBBBB'AAAAAAAA
284 *
285 * This is the canonical definition for the GCC/Clang builtin
286 * `__builtin_bswap32`.
287 *
288 * @param bitfield Bitfield to reverse bytes of.
289 * @return `bitfield` with the order of bytes reversed.
290 */
292inline uint32_t bitfield_byteswap32(uint32_t bitfield) {
293 return __builtin_bswap32(bitfield);
294}
295
296/**
297 * Check whether the bitfield value is power of two aligned.
298 *
299 * Zero will also return false.
300 *
301 * @param bitfield Value to be verified.
302 * @return True if bitfield is power of two, otherwise false.
303 */
305inline bool bitfield_is_power_of_two32(uint32_t bitfield) {
306 return bitfield != 0 && (bitfield & (bitfield - 1)) == 0;
307}
308
309#ifdef __cplusplus
310} // extern "C"
311#endif // __cplusplus
312
313#endif // OPENTITAN_SW_DEVICE_LIB_BASE_BITFIELD_H_