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