@@ -221,8 +221,9 @@ pub fn fields(
221
221
width,
222
222
range_type : _,
223
223
} = f. bit_range ;
224
- let sc = f. name . to_sanitized_snake_case ( ) ;
225
- let pc = f. name . to_sanitized_upper_case ( ) ;
224
+ let name = util:: replace_suffix ( & f. name , "" ) ;
225
+ let sc = name. to_sanitized_snake_case ( ) ;
226
+ let pc = name. to_sanitized_upper_case ( ) ;
226
227
let span = Span :: call_site ( ) ;
227
228
let pc_r = Ident :: new ( & format ! ( "{}_A" , pc) , span) ;
228
229
let _pc_r = Ident :: new ( & format ! ( "{}_R" , pc) , span) ;
@@ -234,26 +235,44 @@ pub fn fields(
234
235
} else {
235
236
"bits"
236
237
} , Span :: call_site ( ) ) ;
237
- let mut description_with_bits = if width == 1 {
238
- format ! ( "Bit {}" , offset)
239
- } else {
240
- format ! ( "Bits {}:{}" , offset, offset + width - 1 )
241
- } ;
242
- if let Some ( d) = & f. description {
243
- description_with_bits. push_str ( " - " ) ;
244
- description_with_bits. push_str ( & util:: respace ( & util:: escape_brackets ( d) ) ) ;
245
- }
246
238
let description = if let Some ( d) = & f. description {
247
239
util:: respace ( & util:: escape_brackets ( d) )
248
240
} else {
249
241
"" . to_owned ( )
250
242
} ;
251
243
244
+ let dim = match f {
245
+ Field :: Array ( _, de) => {
246
+ let ( first, index) = if let Some ( dim_index) = & de. dim_index {
247
+ if let Ok ( first) = dim_index[ 0 ] . parse :: < u32 > ( ) {
248
+ ( first, None )
249
+ } else {
250
+ ( 0 , de. dim_index . clone ( ) )
251
+ }
252
+ } else {
253
+ ( 0 , None )
254
+ } ;
255
+ let span = Span :: call_site ( ) ;
256
+ let names_with_index: Vec < _ > = match index {
257
+ Some ( ix) => ix. iter ( ) . map ( |i| Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & i) , span) ) . collect ( ) ,
258
+ None => ( 0 ..de. dim ) . map ( |i| Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & ( first + i) . to_string ( ) ) , span) ) . collect ( ) ,
259
+ } ;
260
+ let last = util:: unsuffixed ( ( first + de. dim - 1 ) as u64 ) ;
261
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
262
+ let check = if first == 0 {
263
+ quote ! { debug_assert!( n <= #last) ; }
264
+ } else {
265
+ quote ! { debug_assert!( n >= #first_unsuf && n <= #last) ; }
266
+ } ;
267
+ Some ( ( first, de. dim , de. dim_increment , check, names_with_index) )
268
+ } ,
269
+ Field :: Single ( _) => None
270
+ } ;
271
+
252
272
Ok ( F {
253
273
_pc_w,
254
274
_sc,
255
275
description,
256
- description_with_bits,
257
276
pc_r,
258
277
_pc_r,
259
278
pc_w,
@@ -267,6 +286,7 @@ pub fn fields(
267
286
offset : u64:: from ( offset) ,
268
287
ty : width. to_ty ( ) ?,
269
288
write_constraint : f. write_constraint . as_ref ( ) ,
289
+ dim,
270
290
} )
271
291
}
272
292
}
@@ -306,10 +326,10 @@ pub fn fields(
306
326
let _pc_r = & f. _pc_r ;
307
327
let _pc_w = & f. _pc_w ;
308
328
let description = & f. description ;
309
- let description_with_bits = & f . description_with_bits ;
329
+ let width = f . width ;
310
330
311
331
if can_read {
312
- let cast = if f . width == 1 {
332
+ let cast = if width == 1 {
313
333
quote ! { != 0 }
314
334
} else {
315
335
quote ! { as #fty }
@@ -325,21 +345,59 @@ pub fn fields(
325
345
}
326
346
} ;
327
347
328
- if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
329
- evs_r = Some ( evs. clone ( ) ) ;
330
-
331
- let sc = & f. sc ;
348
+ let sc = & f. sc ;
349
+ if let Some ( ( first, dim, increment, check, names) ) = f. dim . clone ( ) {
350
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
351
+ let offset_unsuf = & util:: unsuffixed ( offset) ;
352
+ let increment_unsuf = & util:: unsuffixed ( increment as u64 ) ;
353
+ let offset_calc = quote ! { crate :: field_offset( n, #offset_unsuf, #first_unsuf, #increment_unsuf) } ;
354
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #mask) #cast } ;
355
+ let doc = & f. description ;
356
+ r_impl_items. push ( quote ! {
357
+ #[ doc = #doc]
358
+ #[ inline( always) ]
359
+ pub fn #sc( & self , n: u32 ) -> #_pc_r {
360
+ #check
361
+ #_pc_r:: new( #value )
362
+ }
363
+ } ) ;
364
+ for ( i, sc_n) in ( 0 ..dim) . zip ( names. iter ( ) ) {
365
+ let offset = offset + ( i as u64 ) * ( increment as u64 ) ;
366
+ let value = if offset != 0 {
367
+ let offset = & util:: unsuffixed ( offset) ;
368
+ quote ! {
369
+ ( ( self . bits >> #offset) & #mask) #cast
370
+ }
371
+ } else {
372
+ quote ! {
373
+ ( self . bits & #mask) #cast
374
+ }
375
+ } ;
376
+ let doc = description_with_bits ( & f. description , offset, width) ;
377
+ r_impl_items. push ( quote ! {
378
+ #[ doc = #doc]
379
+ #[ inline( always) ]
380
+ pub fn #sc_n( & self ) -> #_pc_r {
381
+ #_pc_r:: new( #value )
382
+ }
383
+ } ) ;
384
+ }
385
+ } else {
386
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
332
387
r_impl_items. push ( quote ! {
333
- #[ doc = #description_with_bits ]
388
+ #[ doc = #doc ]
334
389
#[ inline( always) ]
335
390
pub fn #sc( & self ) -> #_pc_r {
336
391
#_pc_r:: new( #value )
337
392
}
338
393
} ) ;
394
+ }
395
+
396
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
397
+ evs_r = Some ( evs. clone ( ) ) ;
339
398
340
399
base_pc_w = base. as_ref ( ) . map ( |base| {
341
- let pc = base. field . to_sanitized_upper_case ( ) ;
342
- let base_pc_r = Ident :: new ( & format ! ( "{}_A" , pc) , Span :: call_site ( ) ) ;
400
+ let base_pc_r = Ident :: new ( & format ! ( "{}_A" , util:: replace_suffix( base. field, "" ) . to_sanitized_upper_case( ) ) , Span :: call_site ( ) ) ;
343
401
let base_pc_r = derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, description) ;
344
402
345
403
let doc = format ! ( "Reader of field `{}`" , f. name) ;
@@ -352,7 +410,7 @@ pub fn fields(
352
410
} ) ;
353
411
354
412
if base. is_none ( ) {
355
- let has_reserved_variant = evs. values . len ( ) != ( 1 << f . width ) ;
413
+ let has_reserved_variant = evs. values . len ( ) != ( 1 << width) ;
356
414
let variants = Variant :: from_enumerated_values ( evs) ?;
357
415
358
416
add_from_variants ( mod_items, & variants, pc_r, & f, description, rv) ;
@@ -362,7 +420,7 @@ pub fn fields(
362
420
let mut arms = variants
363
421
. iter ( )
364
422
. map ( |v| {
365
- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
423
+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
366
424
let pc = & v. pc ;
367
425
368
426
if has_reserved_variant {
@@ -377,7 +435,7 @@ pub fn fields(
377
435
arms. push ( quote ! {
378
436
i => Res ( i)
379
437
} ) ;
380
- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
438
+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
381
439
arms. push ( quote ! {
382
440
_ => unreachable!( )
383
441
} ) ;
@@ -437,15 +495,6 @@ pub fn fields(
437
495
}
438
496
439
497
} else {
440
- let sc = & f. sc ;
441
- r_impl_items. push ( quote ! {
442
- #[ doc = #description_with_bits]
443
- #[ inline( always) ]
444
- pub fn #sc( & self ) -> #_pc_r {
445
- #_pc_r:: new ( #value )
446
- }
447
- } ) ;
448
-
449
498
let doc = format ! ( "Reader of field `{}`" , f. name) ;
450
499
mod_items. push ( quote ! {
451
500
#[ doc = #doc]
@@ -458,22 +507,20 @@ pub fn fields(
458
507
if can_write {
459
508
let mut proxy_items = vec ! [ ] ;
460
509
461
- let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
462
- let width = f. width ;
510
+ let mut unsafety = unsafety ( f. write_constraint , width) ;
463
511
464
512
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
465
513
let variants = Variant :: from_enumerated_values ( evs) ?;
466
514
467
- if variants. len ( ) == 1 << f . width {
515
+ if variants. len ( ) == 1 << width {
468
516
unsafety = None ;
469
517
}
470
518
471
519
if Some ( evs) != evs_r. as_ref ( ) {
472
520
pc_w = & f. pc_w ;
473
521
474
522
base_pc_w = base. as_ref ( ) . map ( |base| {
475
- let pc = base. field . to_sanitized_upper_case ( ) ;
476
- let base_pc_w = Ident :: new ( & format ! ( "{}_AW" , pc) , Span :: call_site ( ) ) ;
523
+ let base_pc_w = Ident :: new ( & format ! ( "{}_AW" , util:: replace_suffix( base. field, "" ) . to_sanitized_upper_case( ) ) , Span :: call_site ( ) ) ;
477
524
derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, description)
478
525
} ) ;
479
526
@@ -533,7 +580,20 @@ pub fn fields(
533
580
} ) ;
534
581
}
535
582
536
- proxy_items. push ( if offset != 0 {
583
+ proxy_items. push ( if let Some ( ( first, _, increment, _, _) ) = f. dim {
584
+ let offset = & util:: unsuffixed ( offset) ;
585
+ let first = util:: unsuffixed ( first as u64 ) ;
586
+ let increment_unsuf = util:: unsuffixed ( increment as u64 ) ;
587
+ let offset_calc = quote ! { crate :: field_offset( self . n, #offset, #first, #increment_unsuf) } ;
588
+ quote ! {
589
+ ///Writes raw bits to the field
590
+ #[ inline( always) ]
591
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
592
+ self . w. bits = ( self . w. bits & !( #mask << #offset_calc) ) | ( ( ( value as #rty) & #mask) << #offset_calc) ;
593
+ self . w
594
+ }
595
+ }
596
+ } else if offset != 0 {
537
597
let offset = & util:: unsuffixed ( offset) ;
538
598
quote ! {
539
599
///Writes raw bits to the field
@@ -554,11 +614,18 @@ pub fn fields(
554
614
}
555
615
} ) ;
556
616
617
+ let n_entry = if f. dim . is_some ( ) {
618
+ quote ! { n: u32 , }
619
+ } else {
620
+ quote ! { }
621
+ } ;
622
+
557
623
let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
558
624
mod_items. push ( quote ! {
559
625
#[ doc = #doc]
560
626
pub struct #_pc_w<' a> {
561
627
w: & ' a mut W ,
628
+ #n_entry
562
629
}
563
630
564
631
impl <' a> #_pc_w<' a> {
@@ -567,13 +634,39 @@ pub fn fields(
567
634
} ) ;
568
635
569
636
let sc = & f. sc ;
570
- w_impl_items. push ( quote ! {
571
- #[ doc = #description_with_bits]
572
- #[ inline( always) ]
573
- pub fn #sc( & mut self ) -> #_pc_w {
574
- #_pc_w { w: self }
637
+ if let Some ( ( first, dim, increment, check, names) ) = f. dim . clone ( ) {
638
+ let doc = & f. description ;
639
+ w_impl_items. push ( quote ! {
640
+ #[ doc = #doc]
641
+ #[ inline( always) ]
642
+ pub fn #sc( & mut self , n: u32 ) -> #_pc_w {
643
+ #check
644
+ #_pc_w { w: self , n }
645
+ }
646
+ } ) ;
647
+ for ( i, sc_n) in ( 0 ..dim) . zip ( names. iter ( ) ) {
648
+ let n = first + i;
649
+ let n = util:: unsuffixed ( n as u64 ) ;
650
+ let offset = offset + ( i as u64 ) * ( increment as u64 ) ;
651
+ let doc = description_with_bits ( & f. description , offset, width) ;
652
+ w_impl_items. push ( quote ! {
653
+ #[ doc = #doc]
654
+ #[ inline( always) ]
655
+ pub fn #sc_n( & mut self ) -> #_pc_w {
656
+ #_pc_w { w: self , n: #n }
657
+ }
658
+ } ) ;
575
659
}
576
- } )
660
+ } else {
661
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
662
+ w_impl_items. push ( quote ! {
663
+ #[ doc = #doc]
664
+ #[ inline( always) ]
665
+ pub fn #sc( & mut self ) -> #_pc_w {
666
+ #_pc_w { w: self }
667
+ }
668
+ } ) ;
669
+ }
577
670
}
578
671
}
579
672
@@ -719,12 +812,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719
812
}
720
813
}
721
814
815
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
816
+ let mut res = if width == 1 {
817
+ format ! ( "Bit {}" , offset)
818
+ } else {
819
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
820
+ } ;
821
+ if description. len ( ) > 0 {
822
+ res. push_str ( " - " ) ;
823
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
824
+ }
825
+ res
826
+ }
827
+
722
828
struct F < ' a > {
723
829
_pc_w : Ident ,
724
830
_sc : Ident ,
725
831
access : Option < Access > ,
726
832
description : String ,
727
- description_with_bits : String ,
728
833
evs : & ' a [ EnumeratedValues ] ,
729
834
mask : u64 ,
730
835
name : & ' a str ,
@@ -737,6 +842,7 @@ struct F<'a> {
737
842
ty : Ident ,
738
843
width : u32 ,
739
844
write_constraint : Option < & ' a WriteConstraint > ,
845
+ dim : Option < ( u32 , u32 , u32 , TokenStream , Vec < Ident > ) > ,
740
846
}
741
847
742
848
#[ derive( Clone , Debug ) ]
0 commit comments