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