@@ -216,23 +216,15 @@ pub fn fields(
216
216
for f in fields. iter ( ) {
217
217
// TODO(AJM) - do we need to do anything with this range type?
218
218
let BitRange { offset, width, .. } = f. bit_range ;
219
- let sc = Ident :: new ( & f. name . to_sanitized_snake_case ( ) , span) ;
220
- let pc = f. name . to_sanitized_upper_case ( ) ;
219
+ let name = util:: replace_suffix ( & f. name , "" ) ;
220
+ let sc = Ident :: new ( & name. to_sanitized_snake_case ( ) , span) ;
221
+ let pc = name. to_sanitized_upper_case ( ) ;
221
222
let bits = Ident :: new ( if width == 1 { "bit" } else { "bits" } , span) ;
222
- let mut description_with_bits = if width == 1 {
223
- format ! ( "Bit {}" , offset)
224
- } else {
225
- format ! ( "Bits {}:{}" , offset, offset + width - 1 )
226
- } ;
227
223
let description = if let Some ( d) = & f. description {
228
224
util:: respace ( & util:: escape_brackets ( d) )
229
225
} else {
230
226
"" . to_owned ( )
231
227
} ;
232
- if !description. is_empty ( ) {
233
- description_with_bits. push_str ( " - " ) ;
234
- description_with_bits. push_str ( & description) ;
235
- }
236
228
237
229
let can_read = can_read
238
230
&& ( f. access != Some ( Access :: WriteOnly ) )
@@ -246,7 +238,6 @@ pub fn fields(
246
238
let fty = width. to_ty ( ) ?;
247
239
let evs = & f. enumerated_values ;
248
240
let quotedfield = String :: from ( "`" ) + & f. name + "`" ;
249
- let readerdoc = String :: from ( "Reader of field " ) + & quotedfield;
250
241
251
242
let lookup_results = lookup (
252
243
evs,
@@ -264,7 +255,41 @@ pub fn fields(
264
255
265
256
let mut evs_r = None ;
266
257
258
+ let field_dim = match f {
259
+ Field :: Array ( _, de) => {
260
+ let ( first, index) = if let Some ( dim_index) = & de. dim_index {
261
+ if let Ok ( first) = dim_index[ 0 ] . parse :: < u32 > ( ) {
262
+ let sequential_indexes = dim_index
263
+ . iter ( )
264
+ . map ( |element| element. parse :: < u32 > ( ) )
265
+ . eq ( ( first..de. dim + first) . map ( Ok ) ) ;
266
+ if !sequential_indexes {
267
+ return Err ( format ! ( "unsupported array indexes in {}" , f. name) ) ?;
268
+ }
269
+ ( first, None )
270
+ } else {
271
+ ( 0 , de. dim_index . clone ( ) )
272
+ }
273
+ } else {
274
+ ( 0 , None )
275
+ } ;
276
+ let suffixes: Vec < _ > = match index {
277
+ Some ( ix) => ix,
278
+ None => ( 0 ..de. dim ) . map ( |i| ( first + i) . to_string ( ) ) . collect ( ) ,
279
+ } ;
280
+ let suffixes_str = format ! ( "({}-{})" , first, first + de. dim - 1 ) ;
281
+ Some ( ( first, de. dim , de. dim_increment , suffixes, suffixes_str) )
282
+ }
283
+ Field :: Single ( _) => None ,
284
+ } ;
285
+
267
286
if can_read {
287
+ let readerdoc = if let Some ( ( _, _, _, _, suffixes_str) ) = & field_dim {
288
+ format ! ( "Reader of fields `{}{}`" , & name, & suffixes_str)
289
+ } else {
290
+ String :: from ( "Reader of field " ) + & quotedfield
291
+ } ;
292
+
268
293
let _pc_r = Ident :: new ( & ( pc. clone ( ) + "_R" ) , span) ;
269
294
270
295
let cast = if width == 1 {
@@ -283,20 +308,64 @@ pub fn fields(
283
308
}
284
309
} ;
285
310
286
- r_impl_items. extend ( quote ! {
287
- #[ doc = #description_with_bits]
288
- #[ inline( always) ]
289
- pub fn #sc( & self ) -> #_pc_r {
290
- #_pc_r:: new ( #value )
311
+ if let Some ( ( first, dim, increment, suffixes, suffixes_str) ) = & field_dim {
312
+ let offset_calc = calculate_offset ( * first, * increment, offset) ;
313
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #hexmask) #cast } ;
314
+ let doc = & util:: replace_suffix ( & description, suffixes_str) ;
315
+ r_impl_items. extend ( quote ! {
316
+ #[ doc = #doc]
317
+ #[ inline( always) ]
318
+ pub unsafe fn #sc( & self , n: usize ) -> #_pc_r {
319
+ #_pc_r:: new ( #value )
320
+ }
321
+ } ) ;
322
+ for ( i, suffix) in ( 0 ..* dim) . zip ( suffixes. iter ( ) ) {
323
+ let sub_offset = offset + ( i as u64 ) * ( * increment as u64 ) ;
324
+ let value = if sub_offset != 0 {
325
+ let sub_offset = & util:: unsuffixed ( sub_offset) ;
326
+ quote ! {
327
+ ( ( self . bits >> #sub_offset) & #hexmask) #cast
328
+ }
329
+ } else {
330
+ quote ! {
331
+ ( self . bits & #hexmask) #cast
332
+ }
333
+ } ;
334
+ let sc_n = Ident :: new (
335
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
336
+ Span :: call_site ( ) ,
337
+ ) ;
338
+ let doc = util:: replace_suffix (
339
+ & description_with_bits ( & description, sub_offset, width) ,
340
+ & suffix,
341
+ ) ;
342
+ r_impl_items. extend ( quote ! {
343
+ #[ doc = #doc]
344
+ #[ inline( always) ]
345
+ pub fn #sc_n( & self ) -> #_pc_r {
346
+ #_pc_r:: new ( #value )
347
+ }
348
+ } ) ;
291
349
}
292
- } ) ;
350
+ } else {
351
+ let doc = description_with_bits ( & description, offset, width) ;
352
+ r_impl_items. extend ( quote ! {
353
+ #[ doc = #doc]
354
+ #[ inline( always) ]
355
+ pub fn #sc( & self ) -> #_pc_r {
356
+ #_pc_r:: new ( #value )
357
+ }
358
+ } ) ;
359
+ }
293
360
294
361
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
295
362
evs_r = Some ( evs. clone ( ) ) ;
296
363
297
364
if let Some ( base) = base {
298
- let pc = base. field . to_sanitized_upper_case ( ) ;
299
- let base_pc_r = Ident :: new ( & ( pc. clone ( ) + "_A" ) , span) ;
365
+ let base_pc_r = Ident :: new (
366
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( ) + "_A" ) ,
367
+ span,
368
+ ) ;
300
369
derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, & description) ;
301
370
302
371
mod_items. extend ( quote ! {
@@ -414,8 +483,11 @@ pub fn fields(
414
483
if Some ( evs) != evs_r. as_ref ( ) {
415
484
pc_w = & new_pc_w;
416
485
if let Some ( base) = base {
417
- let pc = base. field . to_sanitized_upper_case ( ) ;
418
- let base_pc_w = Ident :: new ( & ( pc + "_AW" ) , span) ;
486
+ let base_pc_w = Ident :: new (
487
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( )
488
+ + "_AW" ) ,
489
+ span,
490
+ ) ;
419
491
derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, & description)
420
492
} else {
421
493
add_from_variants ( mod_items, & variants, pc_w, & fty, & description, rv) ;
@@ -463,7 +535,16 @@ pub fn fields(
463
535
} ) ;
464
536
}
465
537
466
- proxy_items. extend ( if offset != 0 {
538
+ proxy_items. extend ( if field_dim. is_some ( ) {
539
+ quote ! {
540
+ ///Writes raw bits to the field
541
+ #[ inline( always) ]
542
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
543
+ self . w. bits = ( self . w. bits & !( #hexmask << self . offset) ) | ( ( ( value as #rty) & #hexmask) << self . offset) ;
544
+ self . w
545
+ }
546
+ }
547
+ } else if offset != 0 {
467
548
let offset = & util:: unsuffixed ( offset) ;
468
549
quote ! {
469
550
///Writes raw bits to the field
@@ -484,25 +565,66 @@ pub fn fields(
484
565
}
485
566
} ) ;
486
567
487
- let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
568
+ let ( doc, offset_entry) = if let Some ( ( _, _, _, _, suffixes_str) ) = & field_dim {
569
+ (
570
+ format ! ( "Write proxy for fields `{}{}`" , & name, & suffixes_str) ,
571
+ quote ! { offset: usize , } ,
572
+ )
573
+ } else {
574
+ ( format ! ( "Write proxy for field `{}`" , f. name) , quote ! { } )
575
+ } ;
576
+
488
577
mod_items. extend ( quote ! {
489
578
#[ doc = #doc]
490
579
pub struct #_pc_w<' a> {
491
580
w: & ' a mut W ,
581
+ #offset_entry
492
582
}
493
583
494
584
impl <' a> #_pc_w<' a> {
495
585
#proxy_items
496
586
}
497
587
} ) ;
498
588
499
- w_impl_items. extend ( quote ! {
500
- #[ doc = #description_with_bits]
501
- #[ inline( always) ]
502
- pub fn #sc( & mut self ) -> #_pc_w {
503
- #_pc_w { w: self }
589
+ if let Some ( ( first, dim, increment, suffixes, suffixes_str) ) = & field_dim {
590
+ let offset_calc = calculate_offset ( * first, * increment, offset) ;
591
+ let doc = & util:: replace_suffix ( & description, suffixes_str) ;
592
+ w_impl_items. extend ( quote ! {
593
+ #[ doc = #doc]
594
+ #[ inline( always) ]
595
+ pub unsafe fn #sc( & mut self , n: usize ) -> #_pc_w {
596
+ #_pc_w { w: self , offset: #offset_calc }
597
+ }
598
+ } ) ;
599
+ for ( i, suffix) in ( 0 ..* dim) . zip ( suffixes. iter ( ) ) {
600
+ let sub_offset = offset + ( i as u64 ) * ( * increment as u64 ) ;
601
+ let sc_n = Ident :: new (
602
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
603
+ Span :: call_site ( ) ,
604
+ ) ;
605
+ let doc = util:: replace_suffix (
606
+ & description_with_bits ( & description, sub_offset, width) ,
607
+ & suffix,
608
+ ) ;
609
+ let sub_offset = util:: unsuffixed ( sub_offset as u64 ) ;
610
+ w_impl_items. extend ( quote ! {
611
+ #[ doc = #doc]
612
+ #[ inline( always) ]
613
+ pub fn #sc_n( & mut self ) -> #_pc_w {
614
+ #_pc_w { w: self , offset: #sub_offset }
615
+ }
616
+ } ) ;
504
617
}
505
- } )
618
+ } else {
619
+ let doc = description_with_bits ( & description, offset, width) ;
620
+ w_impl_items. extend ( quote ! {
621
+ #[ doc = #doc]
622
+ #[ inline( always) ]
623
+ pub fn #sc( & mut self ) -> #_pc_w {
624
+ #_pc_w { w: self }
625
+ }
626
+ } ) ;
627
+ }
506
628
}
507
629
}
508
630
@@ -612,6 +734,41 @@ fn add_from_variants(
612
734
} ) ;
613
735
}
614
736
737
+ fn calculate_offset ( first : u32 , increment : u32 , offset : u64 ) -> TokenStream {
738
+ let mut res = if first != 0 {
739
+ let first = util:: unsuffixed ( first as u64 ) ;
740
+ quote ! { n - #first }
741
+ } else {
742
+ quote ! { n }
743
+ } ;
744
+ if increment != 1 {
745
+ let increment = util:: unsuffixed ( increment as u64 ) ;
746
+ res = if first != 0 {
747
+ quote ! { ( #res) * #increment }
748
+ } else {
749
+ quote ! { #res * #increment }
750
+ } ;
751
+ }
752
+ if offset != 0 {
753
+ let offset = & util:: unsuffixed ( offset) ;
754
+ res = quote ! { #res + #offset } ;
755
+ }
756
+ res
757
+ }
758
+
759
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
760
+ let mut res = if width == 1 {
761
+ format ! ( "Bit {}" , offset)
762
+ } else {
763
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
764
+ } ;
765
+ if description. len ( ) > 0 {
766
+ res. push_str ( " - " ) ;
767
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
768
+ }
769
+ res
770
+ }
771
+
615
772
fn derive_from_base (
616
773
mod_items : & mut TokenStream ,
617
774
base : & Base ,
0 commit comments