@@ -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
+ let sequential_indexes = dim_index
249
+ . iter ( )
250
+ . map ( |element| element. parse :: < u32 > ( ) )
251
+ . eq ( ( first..de. dim +first) . map ( Ok ) ) ;
252
+ if !sequential_indexes {
253
+ return Err ( format ! ( "unsupported array indexes in {}" , f. name) ) ?;
254
+ }
255
+ ( first, None )
256
+ } else {
257
+ ( 0 , de. dim_index . clone ( ) )
258
+ }
259
+ } else {
260
+ ( 0 , None )
261
+ } ;
262
+ let suffixes: Vec < _ > = match index {
263
+ Some ( ix) => ix,
264
+ None => ( 0 ..de. dim ) . map ( |i| ( first + i) . to_string ( ) ) . collect ( ) ,
265
+ } ;
266
+ Some ( ( first, de. dim , de. dim_increment , 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,72 @@ 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, suffixes) ) = f. dim . clone ( ) {
349
+ let mut offset_calc = if first != 0 {
350
+ let first = util:: unsuffixed ( first as u64 ) ;
351
+ quote ! { ( n - #first) }
352
+ } else {
353
+ quote ! { n }
354
+ } ;
355
+ if increment != 1 {
356
+ let increment = util:: unsuffixed ( increment as u64 ) ;
357
+ offset_calc = quote ! { #offset_calc * #increment } ;
358
+ }
359
+ offset_calc = if offset !=0 {
360
+ let offset = & util:: unsuffixed ( offset) ;
361
+ quote ! { let o = #offset_calc + #offset; }
362
+ } else {
363
+ quote ! { let o = #offset_calc; }
364
+ } ;
365
+ let value = quote ! { ( ( self . bits >> o) & #mask) #cast } ;
366
+ let doc = & f. description ;
332
367
r_impl_items. push ( quote ! {
333
- #[ doc = #description_with_bits]
368
+ #[ doc = #doc]
369
+ #[ inline( always) ]
370
+ pub unsafe fn #sc( & self , n: u32 ) -> #_pc_r {
371
+ #offset_calc
372
+ #_pc_r:: new( #value )
373
+ }
374
+ } ) ;
375
+ for ( i, suffix) in ( 0 ..dim) . zip ( suffixes. iter ( ) ) {
376
+ let offset = offset + ( i as u64 ) * ( increment as u64 ) ;
377
+ let value = if offset != 0 {
378
+ let offset = & util:: unsuffixed ( offset) ;
379
+ quote ! {
380
+ ( ( self . bits >> #offset) & #mask) #cast
381
+ }
382
+ } else {
383
+ quote ! {
384
+ ( self . bits & #mask) #cast
385
+ }
386
+ } ;
387
+ let sc_n = Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) , Span :: call_site ( ) ) ;
388
+ let doc = util:: replace_suffix ( & description_with_bits ( & f. description , offset, width) , & suffix) ;
389
+ r_impl_items. push ( quote ! {
390
+ #[ doc = #doc]
391
+ #[ inline( always) ]
392
+ pub fn #sc_n( & self ) -> #_pc_r {
393
+ #_pc_r:: new( #value )
394
+ }
395
+ } ) ;
396
+ }
397
+ } else {
398
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
399
+ r_impl_items. push ( quote ! {
400
+ #[ doc = #doc]
334
401
#[ inline( always) ]
335
402
pub fn #sc( & self ) -> #_pc_r {
336
403
#_pc_r:: new( #value )
337
404
}
338
405
} ) ;
406
+ }
407
+
408
+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
409
+ evs_r = Some ( evs. clone ( ) ) ;
339
410
340
411
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 ( ) ) ;
412
+ let base_pc_r = Ident :: new ( & format ! ( "{}_A" , util:: replace_suffix( base. field, "" ) . to_sanitized_upper_case( ) ) , Span :: call_site ( ) ) ;
343
413
let base_pc_r = derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, description) ;
344
414
345
415
let doc = format ! ( "Reader of field `{}`" , f. name) ;
@@ -352,7 +422,7 @@ pub fn fields(
352
422
} ) ;
353
423
354
424
if base. is_none ( ) {
355
- let has_reserved_variant = evs. values . len ( ) != ( 1 << f . width ) ;
425
+ let has_reserved_variant = evs. values . len ( ) != ( 1 << width) ;
356
426
let variants = Variant :: from_enumerated_values ( evs) ?;
357
427
358
428
add_from_variants ( mod_items, & variants, pc_r, & f, description, rv) ;
@@ -362,7 +432,7 @@ pub fn fields(
362
432
let mut arms = variants
363
433
. iter ( )
364
434
. map ( |v| {
365
- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
435
+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
366
436
let pc = & v. pc ;
367
437
368
438
if has_reserved_variant {
@@ -377,7 +447,7 @@ pub fn fields(
377
447
arms. push ( quote ! {
378
448
i => Res ( i)
379
449
} ) ;
380
- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
450
+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
381
451
arms. push ( quote ! {
382
452
_ => unreachable!( )
383
453
} ) ;
@@ -437,15 +507,6 @@ pub fn fields(
437
507
}
438
508
439
509
} 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
510
let doc = format ! ( "Reader of field `{}`" , f. name) ;
450
511
mod_items. push ( quote ! {
451
512
#[ doc = #doc]
@@ -458,22 +519,20 @@ pub fn fields(
458
519
if can_write {
459
520
let mut proxy_items = vec ! [ ] ;
460
521
461
- let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
462
- let width = f. width ;
522
+ let mut unsafety = unsafety ( f. write_constraint , width) ;
463
523
464
524
if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
465
525
let variants = Variant :: from_enumerated_values ( evs) ?;
466
526
467
- if variants. len ( ) == 1 << f . width {
527
+ if variants. len ( ) == 1 << width {
468
528
unsafety = None ;
469
529
}
470
530
471
531
if Some ( evs) != evs_r. as_ref ( ) {
472
532
pc_w = & f. pc_w ;
473
533
474
534
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 ( ) ) ;
535
+ let base_pc_w = Ident :: new ( & format ! ( "{}_AW" , util:: replace_suffix( base. field, "" ) . to_sanitized_upper_case( ) ) , Span :: call_site ( ) ) ;
477
536
derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, description)
478
537
} ) ;
479
538
@@ -533,7 +592,33 @@ pub fn fields(
533
592
} ) ;
534
593
}
535
594
536
- proxy_items. push ( if offset != 0 {
595
+ proxy_items. push ( if let Some ( ( first, _, increment, _) ) = f. dim {
596
+ let mut offset_calc = if first != 0 {
597
+ let first = util:: unsuffixed ( first as u64 ) ;
598
+ quote ! { ( self . n - #first) }
599
+ } else {
600
+ quote ! { self . n }
601
+ } ;
602
+ if increment != 1 {
603
+ let increment = util:: unsuffixed ( increment as u64 ) ;
604
+ offset_calc = quote ! { #offset_calc * #increment } ;
605
+ }
606
+ offset_calc = if offset !=0 {
607
+ let offset = & util:: unsuffixed ( offset) ;
608
+ quote ! { let o = #offset_calc + #offset; }
609
+ } else {
610
+ quote ! { let o = #offset_calc; }
611
+ } ;
612
+ quote ! {
613
+ ///Writes raw bits to the field
614
+ #[ inline( always) ]
615
+ pub #unsafety fn #bits( self , value: #fty) -> & ' a mut W {
616
+ #offset_calc
617
+ self . w. bits = ( self . w. bits & !( #mask << o) ) | ( ( ( value as #rty) & #mask) << o) ;
618
+ self . w
619
+ }
620
+ }
621
+ } else if offset != 0 {
537
622
let offset = & util:: unsuffixed ( offset) ;
538
623
quote ! {
539
624
///Writes raw bits to the field
@@ -554,11 +639,18 @@ pub fn fields(
554
639
}
555
640
} ) ;
556
641
642
+ let n_entry = if f. dim . is_some ( ) {
643
+ quote ! { n: u32 , }
644
+ } else {
645
+ quote ! { }
646
+ } ;
647
+
557
648
let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
558
649
mod_items. push ( quote ! {
559
650
#[ doc = #doc]
560
651
pub struct #_pc_w<' a> {
561
652
w: & ' a mut W ,
653
+ #n_entry
562
654
}
563
655
564
656
impl <' a> #_pc_w<' a> {
@@ -567,13 +659,39 @@ pub fn fields(
567
659
} ) ;
568
660
569
661
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 }
662
+ if let Some ( ( first, dim, increment, suffixes) ) = f. dim . clone ( ) {
663
+ let doc = & f. description ;
664
+ w_impl_items. push ( quote ! {
665
+ #[ doc = #doc]
666
+ #[ inline( always) ]
667
+ pub unsafe fn #sc( & mut self , n: u32 ) -> #_pc_w {
668
+ #_pc_w { w: self , n }
669
+ }
670
+ } ) ;
671
+ for ( i, suffix) in ( 0 ..dim) . zip ( suffixes. iter ( ) ) {
672
+ let n = first + i;
673
+ let n = util:: unsuffixed ( n as u64 ) ;
674
+ let offset = offset + ( i as u64 ) * ( increment as u64 ) ;
675
+ let sc_n = Ident :: new ( & util:: replace_suffix ( & f. name . to_sanitized_snake_case ( ) , & suffix) , Span :: call_site ( ) ) ;
676
+ let doc = util:: replace_suffix ( & description_with_bits ( & f. description , offset, width) , & suffix) ;
677
+ w_impl_items. push ( quote ! {
678
+ #[ doc = #doc]
679
+ #[ inline( always) ]
680
+ pub fn #sc_n( & mut self ) -> #_pc_w {
681
+ #_pc_w { w: self , n: #n }
682
+ }
683
+ } ) ;
575
684
}
576
- } )
685
+ } else {
686
+ let doc = description_with_bits ( & f. description , f. offset , width) ;
687
+ w_impl_items. push ( quote ! {
688
+ #[ doc = #doc]
689
+ #[ inline( always) ]
690
+ pub fn #sc( & mut self ) -> #_pc_w {
691
+ #_pc_w { w: self }
692
+ }
693
+ } ) ;
694
+ }
577
695
}
578
696
}
579
697
@@ -719,12 +837,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719
837
}
720
838
}
721
839
840
+ fn description_with_bits ( description : & str , offset : u64 , width : u32 ) -> String {
841
+ let mut res = if width == 1 {
842
+ format ! ( "Bit {}" , offset)
843
+ } else {
844
+ format ! ( "Bits {}:{}" , offset, offset + width as u64 - 1 )
845
+ } ;
846
+ if description. len ( ) > 0 {
847
+ res. push_str ( " - " ) ;
848
+ res. push_str ( & util:: respace ( & util:: escape_brackets ( description) ) ) ;
849
+ }
850
+ res
851
+ }
852
+
722
853
struct F < ' a > {
723
854
_pc_w : Ident ,
724
855
_sc : Ident ,
725
856
access : Option < Access > ,
726
857
description : String ,
727
- description_with_bits : String ,
728
858
evs : & ' a [ EnumeratedValues ] ,
729
859
mask : u64 ,
730
860
name : & ' a str ,
@@ -737,6 +867,7 @@ struct F<'a> {
737
867
ty : Ident ,
738
868
width : u32 ,
739
869
write_constraint : Option < & ' a WriteConstraint > ,
870
+ dim : Option < ( u32 , u32 , u32 , Vec < String > ) > ,
740
871
}
741
872
742
873
#[ derive( Clone , Debug ) ]
0 commit comments