@@ -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,43 @@ 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 suffixes: Vec < _ > = match index {
256
+ Some ( ix) => ix,
257
+ None => ( 0 ..de. dim ) . map ( |i| ( first + i) . to_string ( ) ) . collect ( ) ,
258
+ } ;
259
+ let last = util:: unsuffixed ( ( first + de. dim - 1 ) as u64 ) ;
260
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
261
+ let check = if first == 0 {
262
+ quote ! { debug_assert!( n <= #last) ; }
263
+ } else {
264
+ quote ! { debug_assert!( n >= #first_unsuf && n <= #last) ; }
265
+ } ;
266
+ Some ( ( first, de. dim , de. dim_increment , check, suffixes) )
267
+ } ,
268
+ Field :: Single ( _) => None
269
+ } ;
270
+
252
271
Ok ( F {
253
272
_pc_w,
254
273
_sc,
255
274
description,
256
- description_with_bits,
257
275
pc_r,
258
276
_pc_r,
259
277
pc_w,
@@ -267,6 +285,7 @@ pub fn fields(
267
285
offset : u64:: from ( offset) ,
268
286
ty : width. to_ty ( ) ?,
269
287
write_constraint : f. write_constraint . as_ref ( ) ,
288
+ dim,
270
289
} )
271
290
}
272
291
}
@@ -306,10 +325,10 @@ pub fn fields(
306
325
let _pc_r = & f. _pc_r ;
307
326
let _pc_w = & f. _pc_w ;
308
327
let description = & f. description ;
309
- let description_with_bits = & f . description_with_bits ;
328
+ let width = f . width ;
310
329
311
330
if can_read {
312
- let cast = if f . width == 1 {
331
+ let cast = if width == 1 {
313
332
quote ! { != 0 }
314
333
} else {
315
334
quote ! { as #fty }
@@ -325,21 +344,60 @@ pub fn fields(
325
344
}
326
345
} ;
327
346
328
- if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
329
- evs_r = Some ( evs. clone ( ) ) ;
330
-
331
- let sc = & f. sc ;
347
+ let sc = & f. sc ;
348
+ if let Some ( ( first, dim, increment, check, suffixes) ) = f. dim . clone ( ) {
349
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
350
+ let offset_unsuf = & util:: unsuffixed ( offset) ;
351
+ let increment_unsuf = & util:: unsuffixed ( increment as u64 ) ;
352
+ let offset_calc = quote ! { crate :: field_offset( n, #offset_unsuf, #first_unsuf, #increment_unsuf) } ;
353
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #mask) #cast } ;
354
+ let doc = & f. description ;
355
+ r_impl_items. push ( quote ! {
356
+ #[ doc = #doc]
357
+ #[ inline( always) ]
358
+ pub fn #sc( & self , n: u32 ) -> #_pc_r {
359
+ #check
360
+ #_pc_r:: new( #value )
361
+ }
362
+ } ) ;
363
+ for ( i, suffix) in ( 0 ..dim) . zip ( suffixes. iter ( ) ) {
364
+ let offset = offset + ( i as u64 ) * ( increment as u64 ) ;
365
+ let value = if offset != 0 {
366
+ let offset = & util:: unsuffixed ( offset) ;
367
+ quote ! {
368
+ ( ( self . bits >> #offset) & #mask) #cast
369
+ }
370
+ } else {
371
+ quote ! {
372
+ ( self . bits & #mask) #cast
373
+ }
374
+ } ;
375
+ let sc_n = Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) , Span :: call_site ( ) ) ;
376
+ let doc = util:: replace_suffix ( & description_with_bits ( & f. description , offset, width) , & suffix) ;
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,40 @@ 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, suffixes) ) = 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, suffix) in ( 0 ..dim) . zip ( suffixes. 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 sc_n = Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) , Span :: call_site ( ) ) ;
652
+ let doc = util:: replace_suffix ( & description_with_bits ( & f. description , offset, width) , & suffix) ;
653
+ w_impl_items. push ( quote ! {
654
+ #[ doc = #doc]
655
+ #[ inline( always) ]
656
+ pub fn #sc_n( & mut self ) -> #_pc_w {
657
+ #_pc_w { w: self , n: #n }
658
+ }
659
+ } ) ;
575
660
}
576
- } )
661
+ } else {
662
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
663
+ w_impl_items. push ( quote ! {
664
+ #[ doc = #doc]
665
+ #[ inline( always) ]
666
+ pub fn #sc( & mut self ) -> #_pc_w {
667
+ #_pc_w { w: self }
668
+ }
669
+ } ) ;
670
+ }
577
671
}
578
672
}
579
673
@@ -719,12 +813,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719
813
}
720
814
}
721
815
816
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
817
+ let mut res = if width == 1 {
818
+ format ! ( "Bit {}" , offset)
819
+ } else {
820
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
821
+ } ;
822
+ if description. len ( ) > 0 {
823
+ res. push_str ( " - " ) ;
824
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
825
+ }
826
+ res
827
+ }
828
+
722
829
struct F < ' a > {
723
830
_pc_w : Ident ,
724
831
_sc : Ident ,
725
832
access : Option < Access > ,
726
833
description : String ,
727
- description_with_bits : String ,
728
834
evs : & ' a [ EnumeratedValues ] ,
729
835
mask : u64 ,
730
836
name : & ' a str ,
@@ -737,6 +843,7 @@ struct F<'a> {
737
843
ty : Ident ,
738
844
width : u32 ,
739
845
write_constraint : Option < & ' a WriteConstraint > ,
846
+ dim : Option < ( u32 , u32 , u32 , TokenStream , Vec < String > ) > ,
740
847
}
741
848
742
849
#[ derive( Clone , Debug ) ]
0 commit comments