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