1- use super :: onescomplement :: unsigned :: Unsigned36Bit ;
1+ use std :: fmt :: { Display , Write } ;
22
3- #[ repr( u8 ) ]
4- #[ derive( PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy , Debug ) ]
5- pub enum Quarter {
6- Q1 = 0 ,
7- Q2 = 1 ,
8- Q3 = 2 ,
9- Q4 = 3 ,
10- }
3+ use super :: onescomplement:: unsigned:: Unsigned36Bit ;
4+ use super :: quarters:: Quarter ;
115
126#[ repr( u8 ) ]
13- #[ derive( PartialEq , Eq , PartialOrd , Ord , Hash , Clone , Copy , Debug ) ]
14- pub enum QuarterBit {
7+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
8+ pub enum BitPos {
159 B1 = 0 ,
1610 B2 = 1 ,
1711 B3 = 2 ,
@@ -23,55 +17,100 @@ pub enum QuarterBit {
2317 B9 = 8 ,
2418}
2519
26- const fn bit_select_mask ( quarter : Quarter , bit : QuarterBit ) -> u64 {
27- let shift = ( quarter as u32 ) * 9 + ( bit as u32 ) ;
28- 1_u64 << shift
20+ impl Display for BitPos {
21+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
22+ f. write_char ( match self {
23+ BitPos :: B1 => '1' ,
24+ BitPos :: B2 => '2' ,
25+ BitPos :: B3 => '3' ,
26+ BitPos :: B4 => '4' ,
27+ BitPos :: B5 => '5' ,
28+ BitPos :: B6 => '6' ,
29+ BitPos :: B7 => '7' ,
30+ BitPos :: B8 => '8' ,
31+ BitPos :: B9 => '9' ,
32+ } )
33+ }
34+ }
35+
36+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
37+ pub struct BitSelector {
38+ pub quarter : Quarter ,
39+ /// `bitpos` values 1 to 9 inclusive are normal bit positions in a
40+ /// quarter. 0 is a valid value but not a valid bit (so a default
41+ /// will be used when SKM tests bit 0). 10 is the meta bit. 11
42+ /// is the parity bit stored in memory. 12 is the parity value
43+ /// computed from the bits stored in memory.
44+ pub bitpos : BitPos ,
45+ }
46+
47+ impl BitSelector {
48+ pub const fn raw_mask ( & self ) -> u64 {
49+ let shift = ( self . quarter as u32 ) * 9 + ( self . bitpos as u32 ) ;
50+ 1_u64 << shift
51+ }
52+
53+ pub fn mask ( & self ) -> Unsigned36Bit {
54+ Unsigned36Bit :: try_from ( self . raw_mask ( ) )
55+ . expect ( "bit selector mask values cannot be outside the range of Unsigned36Bit" )
56+ }
57+ }
58+
59+ impl Display for BitSelector {
60+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
61+ write ! ( f, "{}.{}" , & self . quarter, & self . bitpos)
62+ }
63+ }
64+
65+ #[ cfg( test) ]
66+ const fn bit_select_mask ( quarter : Quarter , bitpos : BitPos ) -> u64 {
67+ BitSelector { quarter, bitpos } . raw_mask ( )
2968}
3069
3170#[ test]
3271fn test_bit_select_mask_q1 ( ) {
3372 assert_eq ! (
34- bit_select_mask( Quarter :: Q1 , QuarterBit :: B1 ) ,
73+ bit_select_mask( Quarter :: Q1 , BitPos :: B1 ) ,
3574 0o001_u64 ,
3675 "failed for bit 1.1"
3776 ) ;
3877 assert_eq ! (
39- bit_select_mask( Quarter :: Q1 , QuarterBit :: B2 ) ,
78+ bit_select_mask( Quarter :: Q1 , BitPos :: B2 ) ,
4079 0o002_u64 ,
4180 "failed for bit 1.2"
4281 ) ;
4382 assert_eq ! (
44- bit_select_mask( Quarter :: Q1 , QuarterBit :: B3 ) ,
83+ bit_select_mask( Quarter :: Q1 , BitPos :: B3 ) ,
4584 0o004_u64 ,
4685 "failed for bit 1.3"
4786 ) ;
4887 assert_eq ! (
49- bit_select_mask( Quarter :: Q1 , QuarterBit :: B4 ) ,
88+ bit_select_mask( Quarter :: Q1 , BitPos :: B4 ) ,
5089 0o010_u64 ,
5190 "failed for bit 1.4"
5291 ) ;
5392 assert_eq ! (
54- bit_select_mask( Quarter :: Q1 , QuarterBit :: B5 ) ,
93+ bit_select_mask( Quarter :: Q1 , BitPos :: B5 ) ,
5594 0o020_u64 ,
5695 "failed for bit 1.5"
5796 ) ;
5897 assert_eq ! (
59- bit_select_mask( Quarter :: Q1 , QuarterBit :: B6 ) ,
98+ bit_select_mask( Quarter :: Q1 , BitPos :: B6 ) ,
6099 0o040_u64 ,
61100 "failed for bit 1.6"
62101 ) ;
63102 assert_eq ! (
64- bit_select_mask( Quarter :: Q1 , QuarterBit :: B7 ) ,
103+ bit_select_mask( Quarter :: Q1 , BitPos :: B7 ) ,
65104 0o100_u64 ,
66105 "failed for bit 1.7"
67106 ) ;
68107 assert_eq ! (
69- bit_select_mask( Quarter :: Q1 , QuarterBit :: B8 ) ,
108+ bit_select_mask( Quarter :: Q1 , BitPos :: B8 ) ,
70109 0o200_u64 ,
71110 "failed for bit 1.8"
72111 ) ;
73112 assert_eq ! (
74- bit_select_mask( Quarter :: Q1 , QuarterBit :: B9 ) ,
113+ bit_select_mask( Quarter :: Q1 , BitPos :: B9 ) ,
75114 0o400_u64 ,
76115 "failed for bit 1.9"
77116 ) ;
@@ -80,47 +119,47 @@ fn test_bit_select_mask_q1() {
80119#[ test]
81120fn test_bit_select_mask_q2 ( ) {
82121 assert_eq ! (
83- bit_select_mask( Quarter :: Q2 , QuarterBit :: B1 ) ,
122+ bit_select_mask( Quarter :: Q2 , BitPos :: B1 ) ,
84123 0o001_000_u64 ,
85124 "failed for bit 2.1"
86125 ) ;
87126 assert_eq ! (
88- bit_select_mask( Quarter :: Q2 , QuarterBit :: B2 ) ,
127+ bit_select_mask( Quarter :: Q2 , BitPos :: B2 ) ,
89128 0o002_000_u64 ,
90129 "failed for bit 2.2"
91130 ) ;
92131 assert_eq ! (
93- bit_select_mask( Quarter :: Q2 , QuarterBit :: B3 ) ,
132+ bit_select_mask( Quarter :: Q2 , BitPos :: B3 ) ,
94133 0o004_000_u64 ,
95134 "failed for bit 2.3"
96135 ) ;
97136 assert_eq ! (
98- bit_select_mask( Quarter :: Q2 , QuarterBit :: B4 ) ,
137+ bit_select_mask( Quarter :: Q2 , BitPos :: B4 ) ,
99138 0o010_000_u64 ,
100139 "failed for bit 2.4"
101140 ) ;
102141 assert_eq ! (
103- bit_select_mask( Quarter :: Q2 , QuarterBit :: B5 ) ,
142+ bit_select_mask( Quarter :: Q2 , BitPos :: B5 ) ,
104143 0o020_000_u64 ,
105144 "failed for bit 2.5"
106145 ) ;
107146 assert_eq ! (
108- bit_select_mask( Quarter :: Q2 , QuarterBit :: B6 ) ,
147+ bit_select_mask( Quarter :: Q2 , BitPos :: B6 ) ,
109148 0o040_000_u64 ,
110149 "failed for bit 2.6"
111150 ) ;
112151 assert_eq ! (
113- bit_select_mask( Quarter :: Q2 , QuarterBit :: B7 ) ,
152+ bit_select_mask( Quarter :: Q2 , BitPos :: B7 ) ,
114153 0o100_000_u64 ,
115154 "failed for bit 2.7"
116155 ) ;
117156 assert_eq ! (
118- bit_select_mask( Quarter :: Q2 , QuarterBit :: B8 ) ,
157+ bit_select_mask( Quarter :: Q2 , BitPos :: B8 ) ,
119158 0o200_000_u64 ,
120159 "failed for bit 2.8"
121160 ) ;
122161 assert_eq ! (
123- bit_select_mask( Quarter :: Q2 , QuarterBit :: B9 ) ,
162+ bit_select_mask( Quarter :: Q2 , BitPos :: B9 ) ,
124163 0o400_000_u64 ,
125164 "failed for bit 2.9"
126165 ) ;
@@ -129,47 +168,47 @@ fn test_bit_select_mask_q2() {
129168#[ test]
130169fn test_bit_select_mask_q3 ( ) {
131170 assert_eq ! (
132- bit_select_mask( Quarter :: Q3 , QuarterBit :: B1 ) ,
171+ bit_select_mask( Quarter :: Q3 , BitPos :: B1 ) ,
133172 0o001_000_000_u64 ,
134173 "failed for bit 3.1"
135174 ) ;
136175 assert_eq ! (
137- bit_select_mask( Quarter :: Q3 , QuarterBit :: B2 ) ,
176+ bit_select_mask( Quarter :: Q3 , BitPos :: B2 ) ,
138177 0o002_000_000_u64 ,
139178 "failed for bit 3.2"
140179 ) ;
141180 assert_eq ! (
142- bit_select_mask( Quarter :: Q3 , QuarterBit :: B3 ) ,
181+ bit_select_mask( Quarter :: Q3 , BitPos :: B3 ) ,
143182 0o004_000_000_u64 ,
144183 "failed for bit 3.3"
145184 ) ;
146185 assert_eq ! (
147- bit_select_mask( Quarter :: Q3 , QuarterBit :: B4 ) ,
186+ bit_select_mask( Quarter :: Q3 , BitPos :: B4 ) ,
148187 0o010_000_000_u64 ,
149188 "failed for bit 3.4"
150189 ) ;
151190 assert_eq ! (
152- bit_select_mask( Quarter :: Q3 , QuarterBit :: B5 ) ,
191+ bit_select_mask( Quarter :: Q3 , BitPos :: B5 ) ,
153192 0o020_000_000_u64 ,
154193 "failed for bit 3.5"
155194 ) ;
156195 assert_eq ! (
157- bit_select_mask( Quarter :: Q3 , QuarterBit :: B6 ) ,
196+ bit_select_mask( Quarter :: Q3 , BitPos :: B6 ) ,
158197 0o040_000_000_u64 ,
159198 "failed for bit 3.6"
160199 ) ;
161200 assert_eq ! (
162- bit_select_mask( Quarter :: Q3 , QuarterBit :: B7 ) ,
201+ bit_select_mask( Quarter :: Q3 , BitPos :: B7 ) ,
163202 0o100_000_000_u64 ,
164203 "failed for bit 3.7"
165204 ) ;
166205 assert_eq ! (
167- bit_select_mask( Quarter :: Q3 , QuarterBit :: B8 ) ,
206+ bit_select_mask( Quarter :: Q3 , BitPos :: B8 ) ,
168207 0o200_000_000_u64 ,
169208 "failed for bit 3.8"
170209 ) ;
171210 assert_eq ! (
172- bit_select_mask( Quarter :: Q3 , QuarterBit :: B9 ) ,
211+ bit_select_mask( Quarter :: Q3 , BitPos :: B9 ) ,
173212 0o400_000_000_u64 ,
174213 "failed for bit 3.9"
175214 ) ;
@@ -178,95 +217,94 @@ fn test_bit_select_mask_q3() {
178217#[ test]
179218fn test_bit_select_mask_q4 ( ) {
180219 assert_eq ! (
181- bit_select_mask( Quarter :: Q4 , QuarterBit :: B1 ) ,
220+ bit_select_mask( Quarter :: Q4 , BitPos :: B1 ) ,
182221 0o001_000_000_000_u64 ,
183222 "failed for bit 4.1"
184223 ) ;
185224 assert_eq ! (
186- bit_select_mask( Quarter :: Q4 , QuarterBit :: B2 ) ,
225+ bit_select_mask( Quarter :: Q4 , BitPos :: B2 ) ,
187226 0o002_000_000_000_u64 ,
188227 "failed for bit 4.2"
189228 ) ;
190229 assert_eq ! (
191- bit_select_mask( Quarter :: Q4 , QuarterBit :: B3 ) ,
230+ bit_select_mask( Quarter :: Q4 , BitPos :: B3 ) ,
192231 0o004_000_000_000_u64 ,
193232 "failed for bit 4.3"
194233 ) ;
195234 assert_eq ! (
196- bit_select_mask( Quarter :: Q4 , QuarterBit :: B4 ) ,
235+ bit_select_mask( Quarter :: Q4 , BitPos :: B4 ) ,
197236 0o010_000_000_000_u64 ,
198237 "failed for bit 4.4"
199238 ) ;
200239 assert_eq ! (
201- bit_select_mask( Quarter :: Q4 , QuarterBit :: B5 ) ,
240+ bit_select_mask( Quarter :: Q4 , BitPos :: B5 ) ,
202241 0o020_000_000_000_u64 ,
203242 "failed for bit 4.5"
204243 ) ;
205244 assert_eq ! (
206- bit_select_mask( Quarter :: Q4 , QuarterBit :: B6 ) ,
245+ bit_select_mask( Quarter :: Q4 , BitPos :: B6 ) ,
207246 0o040_000_000_000_u64 ,
208247 "failed for bit 4.6"
209248 ) ;
210249 assert_eq ! (
211- bit_select_mask( Quarter :: Q4 , QuarterBit :: B7 ) ,
250+ bit_select_mask( Quarter :: Q4 , BitPos :: B7 ) ,
212251 0o100_000_000_000_u64 ,
213252 "failed for bit 4.7"
214253 ) ;
215254 assert_eq ! (
216- bit_select_mask( Quarter :: Q4 , QuarterBit :: B8 ) ,
255+ bit_select_mask( Quarter :: Q4 , BitPos :: B8 ) ,
217256 0o200_000_000_000_u64 ,
218257 "failed for bit 4.8"
219258 ) ;
220259 assert_eq ! (
221- bit_select_mask( Quarter :: Q4 , QuarterBit :: B9 ) ,
260+ bit_select_mask( Quarter :: Q4 , BitPos :: B9 ) ,
222261 0o400_000_000_000_u64 ,
223262 "failed for bit 4.9"
224263 ) ;
225264}
226265
227- pub const fn bit_select ( value : Unsigned36Bit , quarter : Quarter , bit : QuarterBit ) -> bool {
228- let mask = bit_select_mask ( quarter, bit) ;
229- value. bits & mask != 0
230- }
231-
232266#[ cfg( test) ]
233- fn all_bit_selectors ( ) -> Vec < ( Quarter , QuarterBit ) > {
267+ fn all_bit_selectors ( ) -> Vec < BitSelector > {
234268 let mut result = Vec :: with_capacity ( 36 ) ;
235- for q in [ Quarter :: Q1 , Quarter :: Q2 , Quarter :: Q3 , Quarter :: Q4 ] {
236- for b in [
237- QuarterBit :: B1 ,
238- QuarterBit :: B2 ,
239- QuarterBit :: B3 ,
240- QuarterBit :: B4 ,
241- QuarterBit :: B5 ,
242- QuarterBit :: B6 ,
243- QuarterBit :: B7 ,
244- QuarterBit :: B8 ,
245- QuarterBit :: B9 ,
269+ for quarter in [ Quarter :: Q1 , Quarter :: Q2 , Quarter :: Q3 , Quarter :: Q4 ] {
270+ for bitpos in [
271+ BitPos :: B1 ,
272+ BitPos :: B2 ,
273+ BitPos :: B3 ,
274+ BitPos :: B4 ,
275+ BitPos :: B5 ,
276+ BitPos :: B6 ,
277+ BitPos :: B7 ,
278+ BitPos :: B8 ,
279+ BitPos :: B9 ,
246280 ] {
247- result. push ( ( q , b ) ) ;
281+ result. push ( BitSelector { quarter , bitpos } )
248282 }
249283 }
250284 result
251285}
252286
287+ pub const fn bit_select ( value : Unsigned36Bit , selector : BitSelector ) -> bool {
288+ value. bits & selector. raw_mask ( ) != 0
289+ }
290+
253291#[ test]
254292fn test_bit_select ( ) {
255- for ( bitpos, ( quarter_of_bit_to_set, bit_to_set) ) in all_bit_selectors ( ) . into_iter ( ) . enumerate ( )
256- {
293+ for ( bitpos, selector) in all_bit_selectors ( ) . into_iter ( ) . enumerate ( ) {
257294 let just_that_bit: Unsigned36Bit =
258295 Unsigned36Bit :: try_from ( 1_u64 << bitpos) . expect ( "test bit should not be out of range" ) ;
259- for ( quarter_to_test, bit_to_test) in all_bit_selectors ( ) {
260- if ( quarter_to_test, bit_to_test) == ( quarter_of_bit_to_set, bit_to_set) {
296+ for selector_to_test in all_bit_selectors ( ) {
297+ let found_value: bool = bit_select ( just_that_bit, selector_to_test) ;
298+ if selector_to_test == selector {
261299 // The quarter and bit number is the one we had set, so the value should be 1.
262300 assert ! (
263- bit_select ( just_that_bit , quarter_to_test , bit_to_test ) ,
264- "bit {quarter_to_test:?}.{bit_to_test:? } should be set in {just_that_bit:012o}"
301+ found_value ,
302+ "bit {selector_to_test } should be set in {just_that_bit:012o}"
265303 ) ;
266304 } else {
267305 assert ! (
268- !bit_select ( just_that_bit , quarter_to_test , bit_to_test ) ,
269- "bit {quarter_to_test:?}.{bit_to_test:? } should be unset in {just_that_bit:012o}"
306+ !found_value ,
307+ "bit {selector_to_test } should be unset in {just_that_bit:012o}"
270308 ) ;
271309 }
272310 }
0 commit comments