My Kernel v0.1.0
bits.h
1
12#ifndef UTILS_BITS_H
13#define UTILS_BITS_H
14
15#include <stdint.h>
16
17#include "compiler.h"
18
20#define BIT(_n) (1 << (_n))
21#define BIT64(_n) (1ULL << (_n))
22
24#define BIT_CLEAR(_var, _n) (_var &= ~BIT((_n)))
25
27#define BIT_SET(_var, _n) (_var |= BIT((_n)))
28
30#define BIT_READ(_x, _n) ((_x) & BIT((_n)))
31
32static inline uint64_t BIT_ENABLE(uint64_t bit, unsigned int off, int enable)
33{
34 if (enable)
35 return BIT_SET(bit, off);
36 return BIT_CLEAR(bit, off);
37}
38
39// clang-format off
40
41static inline uint16_t __bswap_16(uint16_t x)
42{
43 return (x << 8) | (x >> 8);
44}
45
46static inline uint32_t __bswap_32(uint32_t x)
47{
48 return ((x) << 24) |
49 ((x & 0x0000FF00) << 8) |
50 ((x & 0x00FF0000) >> 8) |
51 ((x) >> 24);
52}
53
54static inline uint64_t __bswap_64(uint64_t x)
55{
56 return ((x) >> 56) |
57 ((x & 0x00FF000000000000ULL) >> 40) |
58 ((x & 0x0000FF0000000000ULL) >> 24) |
59 ((x & 0x000000FF00000000ULL) >> 8) |
60 ((x & 0x00000000FF000000ULL) << 8) |
61 ((x & 0x0000000000FF0000ULL) << 24) |
62 ((x & 0x000000000000FF00ULL) << 40) |
63 ((x) << 56);
64}
65
66// clang-format on
67
68#ifdef ARCH_LITTLE_ENDIAN
69
70#define htobe16(x) __bswap_16(x)
71#define htole16(x) (uint16_t)(x)
72#define be16toh(x) __bswap_16(x)
73#define le16toh(x) (uint16_t)(x)
74
75#define htobe32(x) __bswap_32(x)
76#define htole32(x) (uint32_t)(x)
77#define be32toh(x) __bswap_32(x)
78#define le32toh(x) (uint32_t)(x)
79
80#define htobe64(x) __bswap_64(x)
81#define htole64(x) (uint64_t)(x)
82#define be64toh(x) __bswap_64(x)
83#define le64toh(x) (uint64_t)(x)
84
85#else
86
87#define htobe16(x) (uint16_t)(x)
88#define htole16(x) __bswap_16(x)
89#define be16toh(x) (uint16_t)(x)
90#define le16toh(x) __bswap_16(x)
91
92#define htobe32(x) (uint32_t)(x)
93#define htole32(x) __bswap_32(x)
94#define be32toh(x) (uint32_t)(x)
95#define le32toh(x) __bswap_32(x)
96
97#define htobe64(x) (uint64_t)(x)
98#define htole64(x) __bswap_64(x)
99#define be64toh(x) (uint64_t)(x)
100#define le64toh(x) __bswap_64(x)
101
102#endif
103
105static ALWAYS_INLINE unsigned long bit_first_one(unsigned long word)
106{
107 return __builtin_ctzl(word);
108}
109
111static ALWAYS_INLINE unsigned long bit_last_one(unsigned long word)
112{
113 return (8 * sizeof(word)) - __builtin_clzl(word) - 1;
114}
115
117static ALWAYS_INLINE unsigned long bit_first_zero(unsigned long word)
118{
119 return __builtin_ctzl(~word);
120}
121
123static ALWAYS_INLINE unsigned long bit_last_zero(unsigned long word)
124{
125 return (8 * sizeof(word)) - __builtin_clzl(~word) - 1;
126}
127
131static ALWAYS_INLINE uint32_t bit_next_pow32(uint32_t val)
132{
133 --val;
134
135 val |= val >> 1;
136 val |= val >> 2;
137 val |= val >> 4;
138 val |= val >> 8;
139 val |= val >> 16;
140
141 return val + 1;
142}
143
144#endif /* UTILS_BITS_H */
#define BIT_SET(_var, _n)
Set the nth bit.
Definition: bits.h:27
static ALWAYS_INLINE unsigned long bit_first_one(unsigned long word)
Find the index of the first set bit inside word.
Definition: bits.h:105
static ALWAYS_INLINE unsigned long bit_first_zero(unsigned long word)
Find the index of the first unset bit inside word.
Definition: bits.h:117
static ALWAYS_INLINE unsigned long bit_last_one(unsigned long word)
Find the index of the last set bit inside word.
Definition: bits.h:111
#define BIT_CLEAR(_var, _n)
Clear the nth bit.
Definition: bits.h:24
static ALWAYS_INLINE uint32_t bit_next_pow32(uint32_t val)
Compute the nex highest power of 2 for a 32bit integer.
Definition: bits.h:131
static ALWAYS_INLINE unsigned long bit_last_zero(unsigned long word)
Find the index of the last unset bit inside word.
Definition: bits.h:123