1 /*
2 * Copyright © 2022 Collabora, Ltd.
3 * SPDX-License-Identifier: MIT
4 */
5
6 use std::ops::Range;
7
8 pub trait BitViewable {
bits(&self) -> usize9 fn bits(&self) -> usize;
10
get_bit_range_u64(&self, range: Range<usize>) -> u6411 fn get_bit_range_u64(&self, range: Range<usize>) -> u64;
12 }
13
14 pub trait BitMutViewable: BitViewable {
set_bit_range_u64(&mut self, range: Range<usize>, val: u64)15 fn set_bit_range_u64(&mut self, range: Range<usize>, val: u64);
16 }
17
u64_mask_for_bits(bits: usize) -> u6418 fn u64_mask_for_bits(bits: usize) -> u64 {
19 assert!(bits > 0 && bits <= 64);
20 !0u64 >> (64 - bits)
21 }
22
23 macro_rules! decl_bit_set_viewable_for_uint {
24 ($ty: ty) => {
25 impl BitViewable for $ty {
26 fn bits(&self) -> usize {
27 <$ty>::BITS as usize
28 }
29
30 fn get_bit_range_u64(&self, range: Range<usize>) -> u64 {
31 assert!(!range.is_empty());
32 assert!(range.end <= self.bits());
33
34 let mask = <$ty>::MAX >> (self.bits() - range.len());
35 ((self >> range.start) & mask).into()
36 }
37 }
38
39 impl BitMutViewable for $ty {
40 fn set_bit_range_u64(&mut self, range: Range<usize>, val: u64) {
41 assert!(!range.is_empty());
42 assert!(range.end <= self.bits());
43
44 let mask = <$ty>::MAX >> (self.bits() - range.len());
45
46 assert!((val & u64::from(mask)) == val);
47 let val = val as $ty;
48
49 *self = (*self & !(mask << range.start)) | (val << range.start);
50 }
51 }
52
53 impl BitViewable for [$ty] {
54 fn bits(&self) -> usize {
55 self.len() * (<$ty>::BITS as usize)
56 }
57
58 fn get_bit_range_u64(&self, range: Range<usize>) -> u64 {
59 assert!(!range.is_empty());
60 assert!(range.end <= self.bits());
61
62 let mask = u64_mask_for_bits(range.len());
63
64 let bits = <$ty>::BITS as usize;
65 let c0_idx = range.start / bits;
66 let c0_start = range.start % bits;
67 let chunks = (c0_start + range.len()).div_ceil(bits);
68
69 let mut val = 0_u64;
70 for i in 0..chunks {
71 let chunk = u64::from(self[c0_idx + i]);
72 if i == 0 {
73 val |= chunk >> c0_start;
74 } else {
75 val |= chunk << (i * bits) - c0_start;
76 };
77 }
78 val & mask
79 }
80 }
81
82 impl BitMutViewable for [$ty] {
83 fn set_bit_range_u64(&mut self, range: Range<usize>, val: u64) {
84 assert!(!range.is_empty());
85 assert!(range.end <= self.bits());
86
87 let mask = u64_mask_for_bits(range.len());
88 assert!((val & u64::from(mask)) == val);
89
90 let bits = <$ty>::BITS as usize;
91 let c0_idx = range.start / bits;
92 let c0_start = range.start % bits;
93 let chunks = (c0_start + range.len()).div_ceil(bits);
94
95 for i in 0..chunks {
96 let chunk = &mut self[c0_idx + i];
97 if i == 0 {
98 *chunk &= !((mask << c0_start) as $ty);
99 *chunk |= (val << c0_start) as $ty;
100 } else {
101 let shift = (i * bits) - c0_start;
102 *chunk &= !((mask >> shift) as $ty);
103 *chunk |= (val >> shift) as $ty;
104 }
105 }
106 }
107 }
108
109 impl<const N: usize> BitViewable for [$ty; N] {
110 fn bits(&self) -> usize {
111 N * (<$ty>::BITS as usize)
112 }
113
114 fn get_bit_range_u64(&self, range: Range<usize>) -> u64 {
115 self[..].get_bit_range_u64(range)
116 }
117 }
118
119 impl<const N: usize> BitMutViewable for [$ty; N] {
120 fn set_bit_range_u64(&mut self, range: Range<usize>, val: u64) {
121 self[..].set_bit_range_u64(range, val);
122 }
123 }
124 };
125 }
126
127 decl_bit_set_viewable_for_uint!(u8);
128 decl_bit_set_viewable_for_uint!(u16);
129 decl_bit_set_viewable_for_uint!(u32);
130 decl_bit_set_viewable_for_uint!(u64);
131
132 pub struct BitView<'a, BS: BitViewable + ?Sized> {
133 parent: &'a BS,
134 range: Range<usize>,
135 }
136
137 impl<'a, BS: BitViewable + ?Sized> BitView<'a, BS> {
new(parent: &'a BS) -> Self138 pub fn new(parent: &'a BS) -> Self {
139 let len = parent.bits();
140 Self {
141 parent: parent,
142 range: 0..len,
143 }
144 }
145
new_subset(parent: &'a BS, range: Range<usize>) -> Self146 pub fn new_subset(parent: &'a BS, range: Range<usize>) -> Self {
147 assert!(range.end <= parent.bits());
148 Self {
149 parent: parent,
150 range: range,
151 }
152 }
153
subset( &'a self, range: Range<usize>, ) -> BitView<'a, BitView<'a, BS>>154 pub fn subset(
155 &'a self,
156 range: Range<usize>,
157 ) -> BitView<'a, BitView<'a, BS>> {
158 BitView::new_subset(self, range)
159 }
160
range_in_parent(&self, range: Range<usize>) -> Range<usize>161 fn range_in_parent(&self, range: Range<usize>) -> Range<usize> {
162 let new_start = self.range.start + range.start;
163 let new_end = self.range.start + range.end;
164 assert!(new_end <= self.range.end);
165 new_start..new_end
166 }
167
get_bit(&self, bit: usize) -> bool168 pub fn get_bit(&self, bit: usize) -> bool {
169 self.get_bit_range_u64(bit..(bit + 1)) != 0
170 }
171 }
172
173 impl<'a, BS: BitViewable + ?Sized> BitViewable for BitView<'a, BS> {
bits(&self) -> usize174 fn bits(&self) -> usize {
175 self.range.end - self.range.start
176 }
177
get_bit_range_u64(&self, range: Range<usize>) -> u64178 fn get_bit_range_u64(&self, range: Range<usize>) -> u64 {
179 self.parent.get_bit_range_u64(self.range_in_parent(range))
180 }
181 }
182
183 pub struct BitMutView<'a, BS: BitMutViewable + ?Sized> {
184 parent: &'a mut BS,
185 range: Range<usize>,
186 }
187
188 impl<'a, BS: BitMutViewable + ?Sized> BitMutView<'a, BS> {
new(parent: &'a mut BS) -> Self189 pub fn new(parent: &'a mut BS) -> Self {
190 let len = parent.bits();
191 Self {
192 parent: parent,
193 range: 0..len,
194 }
195 }
196
new_subset(parent: &'a mut BS, range: Range<usize>) -> Self197 pub fn new_subset(parent: &'a mut BS, range: Range<usize>) -> Self {
198 assert!(range.end <= parent.bits());
199 Self {
200 parent: parent,
201 range: range,
202 }
203 }
204
subset_mut<'b>( &'b mut self, range: Range<usize>, ) -> BitMutView<'b, BitMutView<'a, BS>>205 pub fn subset_mut<'b>(
206 &'b mut self,
207 range: Range<usize>,
208 ) -> BitMutView<'b, BitMutView<'a, BS>> {
209 BitMutView::new_subset(self, range)
210 }
211
range_in_parent(&self, range: Range<usize>) -> Range<usize>212 fn range_in_parent(&self, range: Range<usize>) -> Range<usize> {
213 let new_start = self.range.start + range.start;
214 let new_end = self.range.start + range.end;
215 assert!(new_end <= self.range.end);
216 new_start..new_end
217 }
218
get_bit(&self, bit: usize) -> bool219 pub fn get_bit(&self, bit: usize) -> bool {
220 self.get_bit_range_u64(bit..(bit + 1)) != 0
221 }
222
set_bit(&mut self, bit: usize, val: bool)223 pub fn set_bit(&mut self, bit: usize, val: bool) {
224 self.set_bit_range_u64(bit..(bit + 1), u64::from(val));
225 }
226 }
227
228 impl<'a, BS: BitMutViewable + ?Sized> BitViewable for BitMutView<'a, BS> {
bits(&self) -> usize229 fn bits(&self) -> usize {
230 self.range.end - self.range.start
231 }
232
get_bit_range_u64(&self, range: Range<usize>) -> u64233 fn get_bit_range_u64(&self, range: Range<usize>) -> u64 {
234 self.parent.get_bit_range_u64(self.range_in_parent(range))
235 }
236 }
237
238 impl<'a, BS: BitMutViewable + ?Sized> BitMutViewable for BitMutView<'a, BS> {
set_bit_range_u64(&mut self, range: Range<usize>, val: u64)239 fn set_bit_range_u64(&mut self, range: Range<usize>, val: u64) {
240 self.parent
241 .set_bit_range_u64(self.range_in_parent(range), val);
242 }
243 }
244
245 pub trait SetFieldU64 {
set_field_u64(&mut self, range: Range<usize>, val: u64)246 fn set_field_u64(&mut self, range: Range<usize>, val: u64);
247 }
248
249 impl<'a, BS: BitMutViewable + ?Sized> SetFieldU64 for BitMutView<'a, BS> {
set_field_u64(&mut self, range: Range<usize>, val: u64)250 fn set_field_u64(&mut self, range: Range<usize>, val: u64) {
251 let bits = range.end - range.start;
252
253 /* Check that it fits in the bitfield */
254 assert!((val & u64_mask_for_bits(bits)) == val);
255
256 self.set_bit_range_u64(range, val);
257 }
258 }
259
260 pub trait SetField<T> {
set_field(&mut self, range: Range<usize>, val: T)261 fn set_field(&mut self, range: Range<usize>, val: T);
262 }
263
264 impl<T: SetFieldU64> SetField<u64> for T {
set_field(&mut self, range: Range<usize>, val: u64)265 fn set_field(&mut self, range: Range<usize>, val: u64) {
266 self.set_field_u64(range, val);
267 }
268 }
269
270 impl<T: SetFieldU64> SetField<u32> for T {
set_field(&mut self, range: Range<usize>, val: u32)271 fn set_field(&mut self, range: Range<usize>, val: u32) {
272 self.set_field(range, u64::from(val));
273 }
274 }
275
276 impl<T: SetFieldU64> SetField<u16> for T {
set_field(&mut self, range: Range<usize>, val: u16)277 fn set_field(&mut self, range: Range<usize>, val: u16) {
278 self.set_field(range, u64::from(val));
279 }
280 }
281
282 impl<T: SetFieldU64> SetField<u8> for T {
set_field(&mut self, range: Range<usize>, val: u8)283 fn set_field(&mut self, range: Range<usize>, val: u8) {
284 self.set_field(range, u64::from(val));
285 }
286 }
287
288 impl<T: SetFieldU64> SetField<bool> for T {
set_field(&mut self, range: Range<usize>, val: bool)289 fn set_field(&mut self, range: Range<usize>, val: bool) {
290 assert!(range.len() == 1);
291 self.set_field(range, u64::from(val));
292 }
293 }
294
295 impl<T: SetFieldU64> SetField<f32> for T {
set_field(&mut self, range: Range<usize>, val: f32)296 fn set_field(&mut self, range: Range<usize>, val: f32) {
297 assert!(range.len() == 32);
298 self.set_field(range, val.to_bits());
299 }
300 }
301
302 pub trait SetBit {
set_bit(&mut self, bit: usize, val: bool)303 fn set_bit(&mut self, bit: usize, val: bool);
304 }
305
306 impl<T: SetFieldU64> SetBit for T {
set_bit(&mut self, bit: usize, val: bool)307 fn set_bit(&mut self, bit: usize, val: bool) {
308 self.set_field(bit..(bit + 1), val);
309 }
310 }
311
312 impl<T: SetFieldU64> SetField<i64> for T {
set_field(&mut self, range: Range<usize>, val: i64)313 fn set_field(&mut self, range: Range<usize>, val: i64) {
314 let bits = range.end - range.start;
315 let mask = u64_mask_for_bits(bits);
316
317 /* It's easier to work with a u64 */
318 let val = val as u64;
319
320 /* Check that it fits in the bitfield, taking sign into account */
321 let sign_mask = !(mask >> 1);
322 assert!((val & sign_mask) == 0 || (val & sign_mask) == sign_mask);
323
324 self.set_field_u64(range, val & mask);
325 }
326 }
327
328 impl<T: SetFieldU64> SetField<i32> for T {
set_field(&mut self, range: Range<usize>, val: i32)329 fn set_field(&mut self, range: Range<usize>, val: i32) {
330 self.set_field(range, i64::from(val));
331 }
332 }
333
334 impl<T: SetFieldU64> SetField<i16> for T {
set_field(&mut self, range: Range<usize>, val: i16)335 fn set_field(&mut self, range: Range<usize>, val: i16) {
336 self.set_field(range, i64::from(val));
337 }
338 }
339
340 impl<T: SetFieldU64> SetField<i8> for T {
set_field(&mut self, range: Range<usize>, val: i8)341 fn set_field(&mut self, range: Range<usize>, val: i8) {
342 self.set_field(range, i64::from(val));
343 }
344 }
345