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
11
#include "
sw/device/lib/base/macros.h
"
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
;
40
}
bitfield_field32_t
;
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
*/
53
OT_WARN_UNUSED_RESULT
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
*/
71
OT_WARN_UNUSED_RESULT
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
*/
102
OT_WARN_UNUSED_RESULT
103
inline
bitfield_field32_t
bitfield_bit32_to_field32
(
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
*/
118
OT_WARN_UNUSED_RESULT
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
*/
133
OT_WARN_UNUSED_RESULT
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
*/
150
OT_WARN_UNUSED_RESULT
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
*/
176
OT_WARN_UNUSED_RESULT
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
*/
200
OT_WARN_UNUSED_RESULT
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
*/
224
OT_WARN_UNUSED_RESULT
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
*/
246
OT_WARN_UNUSED_RESULT
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
*/
268
OT_WARN_UNUSED_RESULT
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
*/
291
OT_WARN_UNUSED_RESULT
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
*/
304
OT_WARN_UNUSED_RESULT
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_
sw
device
lib
base
bitfield.h
Return to
OpenTitan Documentation