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
14 extern "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  */
35 typedef 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  */
54 inline 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  */
72 inline uint32_t bitfield_field32_write(uint32_t bitfield,
73  bitfield_field32_t field,
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  */
93 typedef 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  */
119 inline 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  */
134 inline 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  */
151 inline 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  */
177 inline 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  */
201 inline 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  */
225 inline 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  */
247 inline 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  */
269 inline 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  */
292 inline 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  */
305 inline 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_