diff options
author | Mark Rutland <mark.rutland@arm.com> | 2021-07-27 15:07:03 +0100 |
---|---|---|
committer | Mark Rutland <mark.rutland@arm.com> | 2022-01-27 16:12:11 +0000 |
commit | d3b1a15d18542b2086e72bfdc3fc43f454772a3b (patch) | |
tree | d055aaeb19e6c44f462f9cd5ce7a0d9e8d5578c7 | |
parent | 286b8ecc86393c2619fc8e5792a4684c46fa461c (diff) | |
download | boot-wrapper-aarch64-d3b1a15d18542b2086e72bfdc3fc43f454772a3b.tar.gz |
Add bit-field macros
Arm architectural documentation typically defines bit-fields as
`[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
helpful if we could define fields in the same way.
Add helpers so that we can do so, along with helper to extract/insert
bit-field values.
There should be no functional change as a result of this patch.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
-rw-r--r-- | include/bits.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/include/bits.h b/include/bits.h new file mode 100644 index 0000000..3dba897 --- /dev/null +++ b/include/bits.h @@ -0,0 +1,66 @@ +/* + * include/bits.h - helpers for bit-field definitions. + * + * Copyright (C) 2021 ARM Limited. All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE.txt file. + */ +#ifndef __BITS_H +#define __BITS_H + +#ifdef __ASSEMBLY__ +#define UL(x) x +#define ULL(x) x +#else +#define UL(x) x##UL +#define ULL(x) x##ULL +#endif + +/* + * Define a contiguous mask of bits with `msb` as the most significant bit and + * `lsb` as the least significant bit. The `msb` value must be greater than or + * equal to `lsb`. + * + * For example: + * - BITS(63, 63) is 0x8000000000000000 + * - BITS(63, 0) is 0xFFFFFFFFFFFFFFFF + * - BITS(0, 0) is 0x0000000000000001 + * - BITS(49, 17) is 0x0003FFFFFFFE0000 + */ +#define BITS(msb, lsb) \ + ((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb)) + +/* + * Define a mask of a single set bit `b`. + * + * For example: + * - BIT(63) is 0x8000000000000000 + * - BIT(0) is 0x0000000000000001 + * - BIT(32) is 0x0000000100000000 + */ +#define BIT(b) BITS(b, b) + +/* + * Find the least significant set bit in the contiguous set of bits in `mask`. + * + * For example: + * - BITS_LSB(0x0000000000000001) is 0 + * - BITS_LSB(0x000000000000ff00) is 8 + * - BITS_LSB(0x8000000000000000) is 63 + */ +#define BITS_LSB(mask) (__builtin_ffsll(mask) - 1) + +/* + * Extract a bit-field out of `val` described by the contiguous set of bits in + * `mask`. + * + * For example: + * - BITS_EXTRACT(0xABCD, BITS(15, 12)) is 0xA + * - BITS_EXTRACT(0xABCD, BITS(11, 8)) is 0xB + * - BITS_EXTRACT(0xABCD, BIT(7)) is 0x1 + */ +#define BITS_EXTRACT(val, mask) \ + (((val) & (mask)) >> BITS_LSB(mask)) + +#endif |