@@ -228,23 +228,15 @@ pub fn fields(
228
228
// TODO(AJM) - do we need to do anything with this range type?
229
229
let BitRange { offset, width, .. } = f. bit_range ;
230
230
let span = Span :: call_site ( ) ;
231
- let sc = Ident :: new ( & f. name . to_sanitized_snake_case ( ) , span) ;
232
- let pc = f. name . to_sanitized_upper_case ( ) ;
231
+ let name = util:: replace_suffix ( & f. name , "" ) ;
232
+ let sc = Ident :: new ( & name. to_sanitized_snake_case ( ) , span) ;
233
+ let pc = name. to_sanitized_upper_case ( ) ;
233
234
let bits = Ident :: new ( if width == 1 { "bit" } else { "bits" } , span) ;
234
- let mut description_with_bits = if width == 1 {
235
- format ! ( "Bit {}" , offset)
236
- } else {
237
- format ! ( "Bits {}:{}" , offset, offset + width - 1 )
238
- } ;
239
235
let description = if let Some ( d) = & f. description {
240
236
util:: respace ( & util:: escape_brackets ( d) )
241
237
} else {
242
238
"" . to_owned ( )
243
239
} ;
244
- if !description. is_empty ( ) {
245
- description_with_bits. push_str ( " - " ) ;
246
- description_with_bits. push_str ( & description) ;
247
- }
248
240
249
241
let can_read = [ Access :: ReadOnly , Access :: ReadWriteOnce , Access :: ReadWrite ]
250
242
. contains ( & access)
@@ -275,6 +267,34 @@ pub fn fields(
275
267
276
268
let mut evs_r = None ;
277
269
270
+ let field_dim = match f {
271
+ Field :: Array ( _, de) => {
272
+ let ( first, index) = if let Some ( dim_index) = & de. dim_index {
273
+ if let Ok ( first) = dim_index[ 0 ] . parse :: < u32 > ( ) {
274
+ let sequential_indexes = dim_index
275
+ . iter ( )
276
+ . map ( |element| element. parse :: < u32 > ( ) )
277
+ . eq ( ( first..de. dim + first) . map ( Ok ) ) ;
278
+ if !sequential_indexes {
279
+ return Err ( format ! ( "unsupported array indexes in {}" , f. name) ) ?;
280
+ }
281
+ ( first, None )
282
+ } else {
283
+ ( 0 , de. dim_index . clone ( ) )
284
+ }
285
+ } else {
286
+ ( 0 , None )
287
+ } ;
288
+ let suffixes: Vec < _ > = match index {
289
+ Some ( ix) => ix,
290
+ None => ( 0 ..de. dim ) . map ( |i| ( first + i) . to_string ( ) ) . collect ( ) ,
291
+ } ;
292
+ let suffixes_str = format ! ( "{}-{}" , first, first + de. dim - 1 ) ;
293
+ Some ( ( first, de. dim , de. dim_increment , suffixes, suffixes_str) )
294
+ }
295
+ Field :: Single ( _) => None ,
296
+ } ;
297
+
278
298
if can_read {
279
299
let _pc_r = Ident :: new ( & ( pc. clone ( ) + "_R" ) , span) ;
280
300
@@ -294,23 +314,71 @@ pub fn fields(
294
314
}
295
315
} ;
296
316
297
- if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
298
- evs_r = Some ( evs. clone ( ) ) ;
299
-
317
+ if let Some ( ( first, dim, increment, suffixes, _) ) = & field_dim {
318
+ let offset_calc = calculate_offset ( * first, * increment, offset) ;
319
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #hexmask) #cast } ;
320
+ let doc = & description;
300
321
r_impl_items. push ( quote ! {
301
- #[ doc = #description_with_bits]
322
+ #[ doc = #doc]
323
+ #[ inline( always) ]
324
+ pub unsafe fn #sc( & self , n: usize ) -> #_pc_r {
325
+ #_pc_r:: new( #value )
326
+ }
327
+ } ) ;
328
+ for ( i, suffix) in ( 0 ..* dim) . zip ( suffixes. iter ( ) ) {
329
+ let sub_offset = offset + ( i as u64 ) * ( * increment as u64 ) ;
330
+ let value = if sub_offset != 0 {
331
+ let sub_offset = & util:: unsuffixed ( sub_offset) ;
332
+ quote ! {
333
+ ( ( self . bits >> #sub_offset) & #hexmask) #cast
334
+ }
335
+ } else {
336
+ quote ! {
337
+ ( self . bits & #hexmask) #cast
338
+ }
339
+ } ;
340
+ let sc_n = Ident :: new (
341
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
342
+ Span :: call_site ( ) ,
343
+ ) ;
344
+ let doc = util:: replace_suffix (
345
+ & description_with_bits ( & description, sub_offset, width) ,
346
+ & suffix,
347
+ ) ;
348
+ r_impl_items. push ( quote ! {
349
+ #[ doc = #doc]
350
+ #[ inline( always) ]
351
+ pub fn #sc_n( & self ) -> #_pc_r {
352
+ #_pc_r:: new( #value )
353
+ }
354
+ } ) ;
355
+ }
356
+ } else {
357
+ let doc = description_with_bits ( & description, offset, width) ;
358
+ r_impl_items. push ( quote ! {
359
+ #[ doc = #doc]
302
360
#[ inline( always) ]
303
361
pub fn #sc( & self ) -> #_pc_r {
304
362
#_pc_r:: new( #value )
305
363
}
306
364
} ) ;
365
+ }
366
+
367
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
368
+ evs_r = Some ( evs. clone ( ) ) ;
307
369
308
370
if let Some ( base) = base {
309
- let pc = base. field . to_sanitized_upper_case ( ) ;
310
- let base_pc_r = Ident :: new ( & ( pc. clone ( ) + "_A" ) , span) ;
371
+ let base_pc_r = Ident :: new (
372
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( ) + "_A" ) ,
373
+ span,
374
+ ) ;
311
375
derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, & description) ;
312
376
313
- let doc = format ! ( "Reader of field `{}`" , f. name) ;
377
+ let doc = if let Some ( ( _, _, _, _, suffixes_str) ) = & field_dim {
378
+ format ! ( "Reader of fields `{}({})`" , & name, & suffixes_str)
379
+ } else {
380
+ format ! ( "Reader of field `{}`" , f. name)
381
+ } ;
314
382
mod_items. push ( quote ! {
315
383
#[ doc = #doc]
316
384
pub type #_pc_r = crate :: R <#fty, #pc_r>;
@@ -403,14 +471,6 @@ pub fn fields(
403
471
} ) ;
404
472
}
405
473
} else {
406
- r_impl_items. push ( quote ! {
407
- #[ doc = #description_with_bits]
408
- #[ inline( always) ]
409
- pub fn #sc( & self ) -> #_pc_r {
410
- #_pc_r:: new ( #value )
411
- }
412
- } ) ;
413
-
414
474
let doc = format ! ( "Reader of field `{}`" , f. name) ;
415
475
mod_items. push ( quote ! {
416
476
#[ doc = #doc]
@@ -436,8 +496,11 @@ pub fn fields(
436
496
if Some ( evs) != evs_r. as_ref ( ) {
437
497
pc_w = & new_pc_w;
438
498
if let Some ( base) = base {
439
- let pc = base. field . to_sanitized_upper_case ( ) ;
440
- let base_pc_w = Ident :: new ( & ( pc + "_AW" ) , span) ;
499
+ let base_pc_w = Ident :: new (
500
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( )
501
+ + "_AW" ) ,
502
+ span,
503
+ ) ;
441
504
derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, & description)
442
505
} else {
443
506
add_from_variants ( mod_items, & variants, pc_w, & fty, & description, rv) ;
@@ -485,7 +548,16 @@ pub fn fields(
485
548
} ) ;
486
549
}
487
550
488
- proxy_items. push ( if offset != 0 {
551
+ proxy_items. push ( if field_dim. is_some ( ) {
552
+ quote ! {
553
+ ///Writes raw bits to the field
554
+ #[ inline( always) ]
555
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
556
+ self . w. bits = ( self . w. bits & !( #hexmask << self . offset) ) | ( ( ( value as #rty) & #hexmask) << self . offset) ;
557
+ self . w
558
+ }
559
+ }
560
+ } else if offset != 0 {
489
561
let offset = & util:: unsuffixed ( offset) ;
490
562
quote ! {
491
563
///Writes raw bits to the field
@@ -506,25 +578,66 @@ pub fn fields(
506
578
}
507
579
} ) ;
508
580
509
- let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
581
+ let ( doc, offset_entry) = if let Some ( ( _, _, _, _, suffixes_str) ) = & field_dim {
582
+ (
583
+ format ! ( "Write proxy for fields `{}({})`" , & name, & suffixes_str) ,
584
+ quote ! { offset: usize , } ,
585
+ )
586
+ } else {
587
+ ( format ! ( "Write proxy for field `{}`" , f. name) , quote ! { } )
588
+ } ;
589
+
510
590
mod_items. push ( quote ! {
511
591
#[ doc = #doc]
512
592
pub struct #_pc_w<' a> {
513
593
w: & ' a mut W ,
594
+ #offset_entry
514
595
}
515
596
516
597
impl <' a> #_pc_w<' a> {
517
598
#( #proxy_items) *
518
599
}
519
600
} ) ;
520
601
521
- w_impl_items. push ( quote ! {
522
- #[ doc = #description_with_bits]
523
- #[ inline( always) ]
524
- pub fn #sc( & mut self ) -> #_pc_w {
525
- #_pc_w { w: self }
602
+ if let Some ( ( first, dim, increment, suffixes, _) ) = & field_dim {
603
+ let offset_calc = calculate_offset ( * first, * increment, offset) ;
604
+ let doc = & description;
605
+ w_impl_items. push ( quote ! {
606
+ #[ doc = #doc]
607
+ #[ inline( always) ]
608
+ pub unsafe fn #sc( & mut self , n: usize ) -> #_pc_w {
609
+ #_pc_w { w: self , offset: #offset_calc }
610
+ }
611
+ } ) ;
612
+ for ( i, suffix) in ( 0 ..* dim) . zip ( suffixes. iter ( ) ) {
613
+ let sub_offset = offset + ( i as u64 ) * ( * increment as u64 ) ;
614
+ let sc_n = Ident :: new (
615
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
616
+ Span :: call_site ( ) ,
617
+ ) ;
618
+ let doc = util:: replace_suffix (
619
+ & description_with_bits ( & description, sub_offset, width) ,
620
+ & suffix,
621
+ ) ;
622
+ let sub_offset = util:: unsuffixed ( sub_offset as u64 ) ;
623
+ w_impl_items. push ( quote ! {
624
+ #[ doc = #doc]
625
+ #[ inline( always) ]
626
+ pub fn #sc_n( & mut self ) -> #_pc_w {
627
+ #_pc_w { w: self , offset: #sub_offset }
628
+ }
629
+ } ) ;
526
630
}
527
- } )
631
+ } else {
632
+ let doc = description_with_bits ( & description, offset, width) ;
633
+ w_impl_items. push ( quote ! {
634
+ #[ doc = #doc]
635
+ #[ inline( always) ]
636
+ pub fn #sc( & mut self ) -> #_pc_w {
637
+ #_pc_w { w: self }
638
+ }
639
+ } ) ;
640
+ }
528
641
}
529
642
}
530
643
@@ -634,6 +747,41 @@ fn add_from_variants(
634
747
} ) ;
635
748
}
636
749
750
+ fn calculate_offset ( first : u32 , increment : u32 , offset : u64 ) -> TokenStream {
751
+ let mut res = if first != 0 {
752
+ let first = util:: unsuffixed ( first as u64 ) ;
753
+ quote ! { n - #first }
754
+ } else {
755
+ quote ! { n }
756
+ } ;
757
+ if increment != 1 {
758
+ let increment = util:: unsuffixed ( increment as u64 ) ;
759
+ res = if first != 0 {
760
+ quote ! { ( #res) * #increment }
761
+ } else {
762
+ quote ! { #res * #increment }
763
+ } ;
764
+ }
765
+ if offset != 0 {
766
+ let offset = & util:: unsuffixed ( offset) ;
767
+ res = quote ! { #res + #offset } ;
768
+ }
769
+ res
770
+ }
771
+
772
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
773
+ let mut res = if width == 1 {
774
+ format ! ( "Bit {}" , offset)
775
+ } else {
776
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
777
+ } ;
778
+ if description. len ( ) > 0 {
779
+ res. push_str ( " - " ) ;
780
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
781
+ }
782
+ res
783
+ }
784
+
637
785
fn derive_from_base (
638
786
mod_items : & mut Vec < TokenStream > ,
639
787
base : & Base ,
0 commit comments