1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
8 #include <linux/types.h>
12 #define BITS_IN_SIZE_T (sizeof(size_t) * 8)
15 * fill_mask[i] - first i bits are '1' , i = 0,1,2,3,4,5,6,7,8
16 * fill_mask[i] = 0xFF >> (8-i)
18 static const u8 fill_mask
[] = { 0x00, 0x01, 0x03, 0x07, 0x0F,
19 0x1F, 0x3F, 0x7F, 0xFF };
22 * zero_mask[i] - first i bits are '0' , i = 0,1,2,3,4,5,6,7,8
23 * zero_mask[i] = 0xFF << i
25 static const u8 zero_mask
[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
26 0xE0, 0xC0, 0x80, 0x00 };
31 * Return: True if all bits [bit, bit+nbits) are zeros "0".
33 bool are_bits_clear(const void *lmap
, size_t bit
, size_t nbits
)
36 const u8
*map
= (u8
*)lmap
+ (bit
>> 3);
40 return !nbits
|| !(*map
& fill_mask
[pos
+ nbits
] &
43 if (*map
++ & zero_mask
[pos
])
48 pos
= ((size_t)map
) & (sizeof(size_t) - 1);
50 pos
= sizeof(size_t) - pos
;
51 if (nbits
>= pos
* 8) {
52 for (nbits
-= pos
* 8; pos
; pos
--, map
++) {
59 for (pos
= nbits
/ BITS_IN_SIZE_T
; pos
; pos
--, map
+= sizeof(size_t)) {
64 for (pos
= (nbits
% BITS_IN_SIZE_T
) >> 3; pos
; pos
--, map
++) {
70 if (pos
&& (*map
& fill_mask
[pos
]))
79 * Return: True if all bits [bit, bit+nbits) are ones "1".
81 bool are_bits_set(const void *lmap
, size_t bit
, size_t nbits
)
85 const u8
*map
= (u8
*)lmap
+ (bit
>> 3);
88 if (8 - pos
>= nbits
) {
89 mask
= fill_mask
[pos
+ nbits
] & zero_mask
[pos
];
90 return !nbits
|| (*map
& mask
) == mask
;
93 mask
= zero_mask
[pos
];
94 if ((*map
++ & mask
) != mask
)
99 pos
= ((size_t)map
) & (sizeof(size_t) - 1);
101 pos
= sizeof(size_t) - pos
;
102 if (nbits
>= pos
* 8) {
103 for (nbits
-= pos
* 8; pos
; pos
--, map
++) {
110 for (pos
= nbits
/ BITS_IN_SIZE_T
; pos
; pos
--, map
+= sizeof(size_t)) {
111 if (*((size_t *)map
) != MINUS_ONE_T
)
115 for (pos
= (nbits
% BITS_IN_SIZE_T
) >> 3; pos
; pos
--, map
++) {
122 mask
= fill_mask
[pos
];
123 if ((*map
& mask
) != mask
)