@@ -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,33 @@ 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
+ Some ( ( first, de. dim , de. dim_increment , suffixes) )
293
+ }
294
+ Field :: Single ( _) => None ,
295
+ } ;
296
+
278
297
if can_read {
279
298
let _pc_r = Ident :: new ( & ( pc. clone ( ) + "_R" ) , span) ;
280
299
@@ -294,20 +313,64 @@ pub fn fields(
294
313
}
295
314
} ;
296
315
297
- if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
298
- evs_r = Some ( evs. clone ( ) ) ;
299
-
316
+ if let Some ( ( first, dim, increment, suffixes) ) = field_dim. clone ( ) {
317
+ let offset_calc = calculate_offset ( first, increment, offset) ;
318
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #hexmask) #cast } ;
319
+ let doc = & description;
320
+ r_impl_items. push ( quote ! {
321
+ #[ doc = #doc]
322
+ #[ inline( always) ]
323
+ pub unsafe fn #sc( & self , n: usize ) -> #_pc_r {
324
+ #_pc_r:: new( #value )
325
+ }
326
+ } ) ;
327
+ for ( i, suffix) in ( 0 ..dim) . zip ( suffixes. iter ( ) ) {
328
+ let sub_offset = offset + ( i as u64 ) * ( increment as u64 ) ;
329
+ let value = if sub_offset != 0 {
330
+ let sub_offset = & util:: unsuffixed ( sub_offset) ;
331
+ quote ! {
332
+ ( ( self . bits >> #sub_offset) & #hexmask) #cast
333
+ }
334
+ } else {
335
+ quote ! {
336
+ ( self . bits & #hexmask) #cast
337
+ }
338
+ } ;
339
+ let sc_n = Ident :: new (
340
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
341
+ Span :: call_site ( ) ,
342
+ ) ;
343
+ let doc = util:: replace_suffix (
344
+ & description_with_bits ( & description, sub_offset, width) ,
345
+ & suffix,
346
+ ) ;
347
+ r_impl_items. push ( quote ! {
348
+ #[ doc = #doc]
349
+ #[ inline( always) ]
350
+ pub fn #sc_n( & self ) -> #_pc_r {
351
+ #_pc_r:: new( #value )
352
+ }
353
+ } ) ;
354
+ }
355
+ } else {
356
+ let doc = description_with_bits ( & description, offset, width) ;
300
357
r_impl_items. push ( quote ! {
301
- #[ doc = #description_with_bits ]
358
+ #[ doc = #doc ]
302
359
#[ inline( always) ]
303
360
pub fn #sc( & self ) -> #_pc_r {
304
361
#_pc_r:: new( #value )
305
362
}
306
363
} ) ;
364
+ }
365
+
366
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
367
+ evs_r = Some ( evs. clone ( ) ) ;
307
368
308
369
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) ;
370
+ let base_pc_r = Ident :: new (
371
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( ) + "_A" ) ,
372
+ span,
373
+ ) ;
311
374
derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, & description) ;
312
375
313
376
let doc = format ! ( "Reader of field `{}`" , f. name) ;
@@ -403,14 +466,6 @@ pub fn fields(
403
466
} ) ;
404
467
}
405
468
} 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
469
let doc = format ! ( "Reader of field `{}`" , f. name) ;
415
470
mod_items. push ( quote ! {
416
471
#[ doc = #doc]
@@ -436,8 +491,11 @@ pub fn fields(
436
491
if Some ( evs) != evs_r. as_ref ( ) {
437
492
pc_w = & new_pc_w;
438
493
if let Some ( base) = base {
439
- let pc = base. field . to_sanitized_upper_case ( ) ;
440
- let base_pc_w = Ident :: new ( & ( pc + "_AW" ) , span) ;
494
+ let base_pc_w = Ident :: new (
495
+ & ( util:: replace_suffix ( base. field , "" ) . to_sanitized_upper_case ( )
496
+ + "_AW" ) ,
497
+ span,
498
+ ) ;
441
499
derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, & description)
442
500
} else {
443
501
add_from_variants ( mod_items, & variants, pc_w, & fty, & description, rv) ;
@@ -485,7 +543,16 @@ pub fn fields(
485
543
} ) ;
486
544
}
487
545
488
- proxy_items. push ( if offset != 0 {
546
+ proxy_items. push ( if field_dim. is_some ( ) {
547
+ quote ! {
548
+ ///Writes raw bits to the field
549
+ #[ inline( always) ]
550
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
551
+ self . w. bits = ( self . w. bits & !( #hexmask << self . offset) ) | ( ( ( value as #rty) & #hexmask) << self . offset) ;
552
+ self . w
553
+ }
554
+ }
555
+ } else if offset != 0 {
489
556
let offset = & util:: unsuffixed ( offset) ;
490
557
quote ! {
491
558
///Writes raw bits to the field
@@ -506,25 +573,64 @@ pub fn fields(
506
573
}
507
574
} ) ;
508
575
576
+ let offset_entry = if field_dim. is_some ( ) {
577
+ quote ! { offset: usize , }
578
+ } else {
579
+ quote ! { }
580
+ } ;
581
+
509
582
let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
510
583
mod_items. push ( quote ! {
511
584
#[ doc = #doc]
512
585
pub struct #_pc_w<' a> {
513
586
w: & ' a mut W ,
587
+ #offset_entry
514
588
}
515
589
516
590
impl <' a> #_pc_w<' a> {
517
591
#( #proxy_items) *
518
592
}
519
593
} ) ;
520
594
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 }
595
+ if let Some ( ( first, dim, increment, suffixes) ) = field_dim. clone ( ) {
596
+ let offset_calc = calculate_offset ( first, increment, offset) ;
597
+ let doc = & f. description ;
598
+ w_impl_items. push ( quote ! {
599
+ #[ doc = #doc]
600
+ #[ inline( always) ]
601
+ pub unsafe fn #sc( & mut self , n: usize ) -> #_pc_w {
602
+ #_pc_w { w: self , offset: #offset_calc }
603
+ }
604
+ } ) ;
605
+ for ( i, suffix) in ( 0 ..dim) . zip ( suffixes. iter ( ) ) {
606
+ let sub_offset = offset + ( i as u64 ) * ( increment as u64 ) ;
607
+ let sc_n = Ident :: new (
608
+ & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) ,
609
+ Span :: call_site ( ) ,
610
+ ) ;
611
+ let doc = util:: replace_suffix (
612
+ & description_with_bits ( & description, sub_offset, width) ,
613
+ & suffix,
614
+ ) ;
615
+ let sub_offset = util:: unsuffixed ( sub_offset as u64 ) ;
616
+ w_impl_items. push ( quote ! {
617
+ #[ doc = #doc]
618
+ #[ inline( always) ]
619
+ pub fn #sc_n( & mut self ) -> #_pc_w {
620
+ #_pc_w { w: self , offset: #sub_offset }
621
+ }
622
+ } ) ;
526
623
}
527
- } )
624
+ } else {
625
+ let doc = description_with_bits ( & description, offset, width) ;
626
+ w_impl_items. push ( quote ! {
627
+ #[ doc = #doc]
628
+ #[ inline( always) ]
629
+ pub fn #sc( & mut self ) -> #_pc_w {
630
+ #_pc_w { w: self }
631
+ }
632
+ } ) ;
633
+ }
528
634
}
529
635
}
530
636
@@ -634,6 +740,41 @@ fn add_from_variants(
634
740
} ) ;
635
741
}
636
742
743
+ fn calculate_offset ( first : u32 , increment : u32 , offset : u64 ) -> TokenStream {
744
+ let mut res = if first != 0 {
745
+ let first = util:: unsuffixed ( first as u64 ) ;
746
+ quote ! { n - #first }
747
+ } else {
748
+ quote ! { n }
749
+ } ;
750
+ if increment != 1 {
751
+ let increment = util:: unsuffixed ( increment as u64 ) ;
752
+ res = if first != 0 {
753
+ quote ! { ( #res) * #increment }
754
+ } else {
755
+ quote ! { #res * #increment }
756
+ } ;
757
+ }
758
+ if offset != 0 {
759
+ let offset = & util:: unsuffixed ( offset) ;
760
+ res = quote ! { #res + #offset } ;
761
+ }
762
+ res
763
+ }
764
+
765
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
766
+ let mut res = if width == 1 {
767
+ format ! ( "Bit {}" , offset)
768
+ } else {
769
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
770
+ } ;
771
+ if description. len ( ) > 0 {
772
+ res. push_str ( " - " ) ;
773
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
774
+ }
775
+ res
776
+ }
777
+
637
778
fn derive_from_base (
638
779
mod_items : & mut Vec < TokenStream > ,
639
780
base : & Base ,
0 commit comments