@@ -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:: name_of_field ( & f) ;
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,46 @@ 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
+ if de. dim_increment != 1 {
247
+ return Err ( format ! ( "Unsupported field array {}, increment = {}" , f. name, de. dim_increment) ) ?;
248
+ }
249
+ let ( first, index) = if let Some ( dim_index) = & de. dim_index {
250
+ if let Ok ( first) = dim_index[ 0 ] . parse :: < u32 > ( ) {
251
+ ( first, None )
252
+ } else {
253
+ ( 0 , de. dim_index . clone ( ) )
254
+ }
255
+ } else {
256
+ ( 0 , None )
257
+ } ;
258
+ let names_with_index: Vec < _ > = match index {
259
+ Some ( ix) => ix. iter ( ) . map ( |i| util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & i) ) . collect ( ) ,
260
+ None => ( 0 ..de. dim ) . map ( |i| util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & ( first + i) . to_string ( ) ) ) . collect ( ) ,
261
+ } ;
262
+ let last = util:: unsuffixed ( ( first + de. dim + 1 ) as u64 ) ;
263
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
264
+ let check = if first == 0 {
265
+ quote ! { debug_assert!( n <= #last) ; }
266
+ } else {
267
+ quote ! { debug_assert!( n >= #first_unsuf && n <= #last) ; }
268
+ } ;
269
+ Some ( ( first, de. dim , check, names_with_index) )
270
+ } ,
271
+ Field :: Single ( _) => None
272
+ } ;
273
+
252
274
Ok ( F {
253
275
_pc_w,
254
276
_sc,
255
277
description,
256
- description_with_bits,
257
278
pc_r,
258
279
_pc_r,
259
280
pc_w,
@@ -267,6 +288,7 @@ pub fn fields(
267
288
offset : u64:: from ( offset) ,
268
289
ty : width. to_ty ( ) ?,
269
290
write_constraint : f. write_constraint . as_ref ( ) ,
291
+ dim,
270
292
} )
271
293
}
272
294
}
@@ -306,10 +328,10 @@ pub fn fields(
306
328
let _pc_r = & f. _pc_r ;
307
329
let _pc_w = & f. _pc_w ;
308
330
let description = & f. description ;
309
- let description_with_bits = & f . description_with_bits ;
331
+ let width = f . width ;
310
332
311
333
if can_read {
312
- let cast = if f . width == 1 {
334
+ let cast = if width == 1 {
313
335
quote ! { != 0 }
314
336
} else {
315
337
quote ! { as #fty }
@@ -325,17 +347,56 @@ pub fn fields(
325
347
}
326
348
} ;
327
349
328
- if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
329
- evs_r = Some ( evs. clone ( ) ) ;
330
-
331
- let sc = & f. sc ;
350
+ let sc = & f. sc ;
351
+ if let Some ( ( first, dim, check, names) ) = f. dim . clone ( ) {
352
+ let first_unsuf = util:: unsuffixed ( first as u64 ) ;
353
+ let offset_unsuf = & util:: unsuffixed ( offset) ;
354
+ let width_unsuf = & util:: unsuffixed ( width as u64 ) ;
355
+ let offset_calc = quote ! { crate :: field_offset( n, #offset_unsuf, #first_unsuf, #width_unsuf) } ;
356
+ let value = quote ! { ( ( self . bits >> #offset_calc) & #mask) #cast } ;
357
+ let doc = & f. description ;
332
358
r_impl_items. push ( quote ! {
333
- #[ doc = #description_with_bits]
359
+ #[ doc = #doc]
360
+ #[ inline( always) ]
361
+ pub fn #sc( & self , n: u32 ) -> #_pc_r {
362
+ #check
363
+ #_pc_r:: new( #value )
364
+ }
365
+ } ) ;
366
+ for ( i, sc_n) in ( 0 ..dim) . zip ( names. iter ( ) ) {
367
+ let offset = offset + ( i as u64 ) * ( width as u64 ) ;
368
+ let value = if offset != 0 {
369
+ let offset = & util:: unsuffixed ( offset) ;
370
+ quote ! {
371
+ ( ( self . bits >> #offset) & #mask) #cast
372
+ }
373
+ } else {
374
+ quote ! {
375
+ ( self . bits & #mask) #cast
376
+ }
377
+ } ;
378
+ let doc = description_with_bits ( & f. description , offset, width) ;
379
+ r_impl_items. push ( quote ! {
380
+ #[ doc = #doc]
381
+ #[ inline( always) ]
382
+ pub fn #sc_n( & self ) -> #_pc_r {
383
+ #_pc_r:: new( #value )
384
+ }
385
+ } ) ;
386
+ }
387
+ } else {
388
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
389
+ r_impl_items. push ( quote ! {
390
+ #[ doc = #doc]
334
391
#[ inline( always) ]
335
392
pub fn #sc( & self ) -> #_pc_r {
336
393
#_pc_r:: new( #value )
337
394
}
338
395
} ) ;
396
+ }
397
+
398
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
399
+ evs_r = Some ( evs. clone ( ) ) ;
339
400
340
401
base_pc_w = base. as_ref ( ) . map ( |base| {
341
402
let pc = base. field . to_sanitized_upper_case ( ) ;
@@ -352,7 +413,7 @@ pub fn fields(
352
413
} ) ;
353
414
354
415
if base. is_none ( ) {
355
- let has_reserved_variant = evs. values . len ( ) != ( 1 << f . width ) ;
416
+ let has_reserved_variant = evs. values . len ( ) != ( 1 << width) ;
356
417
let variants = Variant :: from_enumerated_values ( evs) ?;
357
418
358
419
add_from_variants ( mod_items, & variants, pc_r, & f, description, rv) ;
@@ -362,7 +423,7 @@ pub fn fields(
362
423
let mut arms = variants
363
424
. iter ( )
364
425
. map ( |v| {
365
- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
426
+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
366
427
let pc = & v. pc ;
367
428
368
429
if has_reserved_variant {
@@ -377,7 +438,7 @@ pub fn fields(
377
438
arms. push ( quote ! {
378
439
i => Res ( i)
379
440
} ) ;
380
- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
441
+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
381
442
arms. push ( quote ! {
382
443
_ => unreachable!( )
383
444
} ) ;
@@ -437,15 +498,6 @@ pub fn fields(
437
498
}
438
499
439
500
} 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
501
let doc = format ! ( "Reader of field `{}`" , f. name) ;
450
502
mod_items. push ( quote ! {
451
503
#[ doc = #doc]
@@ -458,13 +510,12 @@ pub fn fields(
458
510
if can_write {
459
511
let mut proxy_items = vec ! [ ] ;
460
512
461
- let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
462
- let width = f. width ;
513
+ let mut unsafety = unsafety ( f. write_constraint , width) ;
463
514
464
515
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
465
516
let variants = Variant :: from_enumerated_values ( evs) ?;
466
517
467
- if variants. len ( ) == 1 << f . width {
518
+ if variants. len ( ) == 1 << width {
468
519
unsafety = None ;
469
520
}
470
521
@@ -533,7 +584,19 @@ pub fn fields(
533
584
} ) ;
534
585
}
535
586
536
- proxy_items. push ( if offset != 0 {
587
+ proxy_items. push ( if let Some ( ( first, _, _, _) ) = f. dim {
588
+ let offset = & util:: unsuffixed ( offset) ;
589
+ let first = util:: unsuffixed ( first as u64 ) ;
590
+ let offset_calc = quote ! { crate :: field_offset( self . n, #offset, #first, #width) } ;
591
+ quote ! {
592
+ ///Writes raw bits to the field
593
+ #[ inline( always) ]
594
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
595
+ self . w. bits = ( self . w. bits & !( #mask << #offset_calc) ) | ( ( ( value as #rty) & #mask) << #offset_calc) ;
596
+ self . w
597
+ }
598
+ }
599
+ } else if offset != 0 {
537
600
let offset = & util:: unsuffixed ( offset) ;
538
601
quote ! {
539
602
///Writes raw bits to the field
@@ -554,11 +617,18 @@ pub fn fields(
554
617
}
555
618
} ) ;
556
619
620
+ let n_entry = if f. dim . is_some ( ) {
621
+ quote ! { n: u32 , }
622
+ } else {
623
+ quote ! { }
624
+ } ;
625
+
557
626
let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
558
627
mod_items. push ( quote ! {
559
628
#[ doc = #doc]
560
629
pub struct #_pc_w<' a> {
561
630
w: & ' a mut W ,
631
+ #n_entry
562
632
}
563
633
564
634
impl <' a> #_pc_w<' a> {
@@ -567,13 +637,39 @@ pub fn fields(
567
637
} ) ;
568
638
569
639
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 }
640
+ if let Some ( ( first, dim, check, names) ) = f. dim . clone ( ) {
641
+ let doc = & f. description ;
642
+ w_impl_items. push ( quote ! {
643
+ #[ doc = #doc]
644
+ #[ inline( always) ]
645
+ pub fn #sc( & mut self , n: u32 ) -> #_pc_w {
646
+ #check
647
+ #_pc_w { w: self , n }
648
+ }
649
+ } ) ;
650
+ for ( i, sc_n) in ( 0 ..dim) . zip ( names. iter ( ) ) {
651
+ let n = first + i;
652
+ let n = util:: unsuffixed ( n as u64 ) ;
653
+ let offset = offset + ( i as u64 ) * ( width as u64 ) ;
654
+ let doc = description_with_bits ( & f. description , offset, width) ;
655
+ w_impl_items. push ( quote ! {
656
+ #[ doc = #doc]
657
+ #[ inline( always) ]
658
+ pub fn #sc_n( & mut self ) -> #_pc_w {
659
+ #_pc_w { w: self , n: #n }
660
+ }
661
+ } ) ;
575
662
}
576
- } )
663
+ } else {
664
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
665
+ w_impl_items. push ( quote ! {
666
+ #[ doc = #doc]
667
+ #[ inline( always) ]
668
+ pub fn #sc( & mut self ) -> #_pc_w {
669
+ #_pc_w { w: self }
670
+ }
671
+ } ) ;
672
+ }
577
673
}
578
674
}
579
675
@@ -719,12 +815,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719
815
}
720
816
}
721
817
818
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
819
+ let mut res = if width == 1 {
820
+ format ! ( "Bit {}" , offset)
821
+ } else {
822
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
823
+ } ;
824
+ if description. len ( ) > 0 {
825
+ res. push_str ( " - " ) ;
826
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
827
+ }
828
+ res
829
+ }
830
+
722
831
struct F < ' a > {
723
832
_pc_w : Ident ,
724
833
_sc : Ident ,
725
834
access : Option < Access > ,
726
835
description : String ,
727
- description_with_bits : String ,
728
836
evs : & ' a [ EnumeratedValues ] ,
729
837
mask : u64 ,
730
838
name : & ' a str ,
@@ -737,6 +845,7 @@ struct F<'a> {
737
845
ty : Ident ,
738
846
width : u32 ,
739
847
write_constraint : Option < & ' a WriteConstraint > ,
848
+ dim : Option < ( u32 , u32 , TokenStream , Vec < Ident > ) > ,
740
849
}
741
850
742
851
#[ derive( Clone , Debug ) ]
0 commit comments