| 1 | /* @title: Bit Manipulation */ |
| 2 | #pragma once |
| 3 | #include <kassert.h> |
| 4 | #include <stdint.h> |
| 5 | |
| 6 | #define BIT(n) (1ull << (n)) |
| 7 | |
| 8 | #define BIT_SET(val, n) ((val) | BIT(n)) |
| 9 | #define BIT_CLEAR(val, n) ((val) & ~BIT(n)) |
| 10 | #define BIT_TEST(val, n) (((val) >> (n)) & 1ull) |
| 11 | #define BIT_TOGGLE(val, n) ((val) ^ BIT(n)) |
| 12 | |
| 13 | #define BIT_MASK(lo, hi) ((~0ULL >> (64ULL - 1ULL - ((hi) - (lo)))) << (lo)) |
| 14 | |
| 15 | #define BIT_RANGE(val, lo, hi) \ |
| 16 | (((val) >> (lo)) & (~0ULL >> (64ULL - 1ULL - ((hi) - (lo))))) |
| 17 | |
| 18 | #define BIT_GET_FIELD(val, lo, hi) \ |
| 19 | ({ \ |
| 20 | uint64_t __v = (uint64_t) (val); \ |
| 21 | uint32_t __l = (uint32_t) (lo); \ |
| 22 | uint32_t __h = (uint32_t) (hi); \ |
| 23 | (void) kassert(__l <= __h && __h < 64); \ |
| 24 | ((__v >> __l) & (~0ULL >> (64ULL - 1ULL - (__h - __l)))); \ |
| 25 | }) |
| 26 | |
| 27 | #define BIT_SET_FIELD(val, field_val, lo, hi) \ |
| 28 | ({ \ |
| 29 | uint64_t __v = (uint64_t) (val); \ |
| 30 | uint64_t __fv = (uint64_t) (field_val); \ |
| 31 | uint32_t __l = (uint32_t) (lo); \ |
| 32 | uint32_t __h = (uint32_t) (hi); \ |
| 33 | (void) kassert(__l <= __h && __h < 64); \ |
| 34 | uint64_t __mask = (~0ULL >> (64ULL - 1ULL - (__h - __l))) << __l; \ |
| 35 | ((__v & ~__mask) | ((__fv << __l) & __mask)); \ |
| 36 | }) |
| 37 | |
| 38 | #define SET_FIELD(val, field_val, lo, hi) BIT_SET_FIELD(val, field_val, lo, hi) |
| 39 | |
| 40 | #define BIT_ANY(val, mask) (((val) & (mask)) != 0) |
| 41 | #define BIT_ALL(val, mask) (((val) & (mask)) == (mask)) |
| 42 | |
| 43 | /* Count of bits in a range */ |
| 44 | #define BIT_WIDTH(lo, hi) \ |
| 45 | ({ \ |
| 46 | uint32_t __l = (uint32_t) (lo); \ |
| 47 | uint32_t __h = (uint32_t) (hi); \ |
| 48 | (void) kassert(__l <= __h); \ |
| 49 | ((__h - __l) + 1u); \ |
| 50 | }) |
| 51 | |