@@ -223,17 +223,17 @@ struct RegisterBlockField {
223
223
224
224
#[ derive( Clone , Debug ) ]
225
225
struct Region {
226
- fields : Vec < RegisterBlockField > ,
226
+ rbfs : Vec < RegisterBlockField > ,
227
227
offset : u32 ,
228
228
end : u32 ,
229
- /// This is only used for regions with `fields .len() > 1`
229
+ /// This is only used for regions with `rbfs .len() > 1`
230
230
pub ident : Option < String > ,
231
231
}
232
232
233
233
impl Region {
234
234
fn shortest_ident ( & self ) -> Option < String > {
235
235
let mut idents: Vec < _ > = self
236
- . fields
236
+ . rbfs
237
237
. iter ( )
238
238
. filter_map ( |f| match & f. field . ident {
239
239
None => None ,
@@ -274,7 +274,7 @@ impl Region {
274
274
}
275
275
276
276
let idents: Vec < _ > = self
277
- . fields
277
+ . rbfs
278
278
. iter ( )
279
279
. filter_map ( |f| match & f. field . ident {
280
280
None => None ,
@@ -304,10 +304,13 @@ impl Region {
304
304
}
305
305
if index <= 1 {
306
306
None
307
- } else if first. get ( index) . is_some ( ) && first[ index] . chars ( ) . all ( |c| c. is_numeric ( ) ) {
308
- Some ( first. iter ( ) . take ( index) . cloned ( ) . collect ( ) )
309
307
} else {
310
- Some ( first. iter ( ) . take ( index - 1 ) . cloned ( ) . collect ( ) )
308
+ Some ( match first. get ( index) {
309
+ Some ( elem) if elem. chars ( ) . all ( |c| c. is_numeric ( ) ) => {
310
+ first. iter ( ) . take ( index) . cloned ( ) . collect ( )
311
+ }
312
+ _ => first. iter ( ) . take ( index - 1 ) . cloned ( ) . collect ( ) ,
313
+ } )
311
314
}
312
315
}
313
316
@@ -320,12 +323,12 @@ impl Region {
320
323
}
321
324
322
325
fn is_union ( & self ) -> bool {
323
- self . fields . len ( ) > 1
326
+ self . rbfs . len ( ) > 1
324
327
}
325
328
}
326
329
327
330
/// FieldRegions keeps track of overlapping field regions,
328
- /// merging fields into appropriate regions as we process them.
331
+ /// merging rbfs into appropriate regions as we process them.
329
332
/// This allows us to reason about when to create a union
330
333
/// rather than a struct.
331
334
#[ derive( Default , Debug ) ]
@@ -338,19 +341,19 @@ struct FieldRegions {
338
341
impl FieldRegions {
339
342
/// Track a field. If the field overlaps with 1 or more existing
340
343
/// entries, they will be merged together.
341
- fn add ( & mut self , field : & RegisterBlockField ) -> Result < ( ) > {
344
+ fn add ( & mut self , rbf : & RegisterBlockField ) -> Result < ( ) > {
342
345
// When merging, this holds the indices in self.regions
343
- // that the input `field ` will be merging with.
346
+ // that the input `rbf ` will be merging with.
344
347
let mut indices = Vec :: new ( ) ;
345
348
346
- let field_start = field . offset ;
347
- let field_end = field_start + ( field . size + BITS_PER_BYTE - 1 ) / BITS_PER_BYTE ;
349
+ let rbf_start = rbf . offset ;
350
+ let rbf_end = rbf_start + ( rbf . size + BITS_PER_BYTE - 1 ) / BITS_PER_BYTE ;
348
351
349
352
// The region that we're going to insert
350
353
let mut new_region = Region {
351
- fields : vec ! [ field . clone( ) ] ,
352
- offset : field . offset ,
353
- end : field_end ,
354
+ rbfs : vec ! [ rbf . clone( ) ] ,
355
+ offset : rbf . offset ,
356
+ end : rbf_end ,
354
357
ident : None ,
355
358
} ;
356
359
@@ -363,8 +366,8 @@ impl FieldRegions {
363
366
let f_end = f. end ;
364
367
365
368
// Compute intersection range
366
- let begin = f_start. max ( field_start ) ;
367
- let end = f_end. min ( field_end ) ;
369
+ let begin = f_start. max ( rbf_start ) ;
370
+ let end = f_end. min ( rbf_end ) ;
368
371
369
372
if end > begin {
370
373
// We're going to remove this element and fold it
@@ -375,8 +378,8 @@ impl FieldRegions {
375
378
new_region. offset = new_region. offset . min ( f_start) ;
376
379
new_region. end = new_region. end . max ( f_end) ;
377
380
378
- // And merge in the fields
379
- new_region. fields . append ( & mut f. fields ) ;
381
+ // And merge in the rbfs
382
+ new_region. rbfs . append ( & mut f. rbfs ) ;
380
383
}
381
384
}
382
385
@@ -387,7 +390,7 @@ impl FieldRegions {
387
390
self . regions . remove ( * idx) ;
388
391
}
389
392
390
- new_region. fields . sort_by_key ( |f| f. offset ) ;
393
+ new_region. rbfs . sort_by_key ( |f| f. offset ) ;
391
394
392
395
// maintain the regions ordered by starting offset
393
396
let idx = self
@@ -413,7 +416,7 @@ impl FieldRegions {
413
416
let idents: Vec < _ > = {
414
417
self . regions
415
418
. iter_mut ( )
416
- . filter ( |r| r. fields . len ( ) > 1 )
419
+ . filter ( |r| r. rbfs . len ( ) > 1 )
417
420
. map ( |r| {
418
421
r. ident = r. compute_ident ( ) ;
419
422
r. ident . clone ( )
@@ -424,15 +427,15 @@ impl FieldRegions {
424
427
. iter_mut ( )
425
428
. filter ( |r| r. ident . is_some ( ) )
426
429
. filter ( |r| {
427
- r. fields . len ( ) > 1 && ( idents. iter ( ) . filter ( |ident| * * ident == r. ident ) . count ( ) > 1 )
430
+ r. rbfs . len ( ) > 1 && ( idents. iter ( ) . filter ( |& ident| ident == & r. ident ) . count ( ) > 1 )
428
431
} )
429
432
. for_each ( |r| {
433
+ let new_ident = r. shortest_ident ( ) ;
430
434
warn ! (
431
435
"Found type name conflict with region {:?}, renamed to {:?}" ,
432
- r. ident,
433
- r. shortest_ident( )
436
+ r. ident, new_ident
434
437
) ;
435
- r. ident = r . shortest_ident ( ) ;
438
+ r. ident = new_ident ;
436
439
} ) ;
437
440
Ok ( ( ) )
438
441
}
@@ -444,7 +447,7 @@ fn register_or_cluster_block(
444
447
name : Option < & str > ,
445
448
_nightly : bool ,
446
449
) -> Result < TokenStream > {
447
- let mut fields = TokenStream :: new ( ) ;
450
+ let mut rbfs = TokenStream :: new ( ) ;
448
451
let mut accessors = TokenStream :: new ( ) ;
449
452
let mut have_accessors = false ;
450
453
@@ -459,7 +462,7 @@ fn register_or_cluster_block(
459
462
460
463
// We need to compute the idents of each register/union block first to make sure no conflicts exists.
461
464
regions. resolve_idents ( ) ?;
462
- // The end of the region for which we previously emitted a field into `fields `
465
+ // The end of the region for which we previously emitted a rbf into `rbfs `
463
466
let mut last_end = 0 ;
464
467
465
468
let span = Span :: call_site ( ) ;
@@ -469,15 +472,15 @@ fn register_or_cluster_block(
469
472
if pad != 0 {
470
473
let name = Ident :: new ( & format ! ( "_reserved{}" , i) , span) ;
471
474
let pad = pad as usize ;
472
- fields . extend ( quote ! {
475
+ rbfs . extend ( quote ! {
473
476
#name : [ u8 ; #pad] ,
474
477
} ) ;
475
478
}
476
479
477
- let mut region_fields = TokenStream :: new ( ) ;
480
+ let mut region_rbfs = TokenStream :: new ( ) ;
478
481
let is_region_a_union = region. is_union ( ) ;
479
482
480
- for reg_block_field in & region. fields {
483
+ for reg_block_field in & region. rbfs {
481
484
let comment = & format ! (
482
485
"0x{:02x} - {}" ,
483
486
reg_block_field. offset,
@@ -499,20 +502,20 @@ fn register_or_cluster_block(
499
502
}
500
503
} ) ;
501
504
} else {
502
- region_fields . extend ( quote ! {
505
+ region_rbfs . extend ( quote ! {
503
506
#[ doc = #comment]
504
507
} ) ;
505
508
506
- reg_block_field. field . to_tokens ( & mut region_fields ) ;
507
- Punct :: new ( ',' , Spacing :: Alone ) . to_tokens ( & mut region_fields ) ;
509
+ reg_block_field. field . to_tokens ( & mut region_rbfs ) ;
510
+ Punct :: new ( ',' , Spacing :: Alone ) . to_tokens ( & mut region_rbfs ) ;
508
511
}
509
512
}
510
513
511
514
if !is_region_a_union {
512
- fields . extend ( region_fields ) ;
515
+ rbfs . extend ( region_rbfs ) ;
513
516
} else {
514
517
// Emit padding for the items that we're not emitting
515
- // as fields so that subsequent fields have the correct
518
+ // as rbfs so that subsequent rbfs have the correct
516
519
// alignment in the struct. We could omit this and just
517
520
// not updated `last_end`, so that the padding check in
518
521
// the outer loop kicks in, but it is nice to be able to
@@ -534,7 +537,7 @@ fn register_or_cluster_block(
534
537
span,
535
538
) ;
536
539
let pad = ( region. end - region. offset ) as usize ;
537
- fields . extend ( quote ! {
540
+ rbfs . extend ( quote ! {
538
541
#name: [ u8 ; #pad] ,
539
542
} )
540
543
}
@@ -563,7 +566,7 @@ fn register_or_cluster_block(
563
566
///Register block
564
567
#[ repr( C ) ]
565
568
pub struct #name {
566
- #fields
569
+ #rbfs
567
570
}
568
571
569
572
#accessors
@@ -809,10 +812,18 @@ fn expand_svd_register(
809
812
)
810
813
} ) ;
811
814
812
- let ty_name = util:: replace_suffix ( & info. name , "" ) ;
815
+ let ty_name = if let Some ( group) = & info. alternate_group {
816
+ format ! ( "{}_{}" , group, util:: replace_suffix( & info. name, "" ) )
817
+ } else {
818
+ util:: replace_suffix ( & info. name , "" )
819
+ } ;
813
820
814
821
for ( idx, _i) in indices. iter ( ) . zip ( 0 ..) {
815
- let nb_name = util:: replace_suffix ( & info. name , idx) ;
822
+ let nb_name = if let Some ( group) = & info. alternate_group {
823
+ format ! ( "{}_{}" , group, util:: replace_suffix( & info. name, idx) )
824
+ } else {
825
+ util:: replace_suffix ( & info. name , idx)
826
+ } ;
816
827
817
828
let ty = name_to_wrapped_ty ( & ty_name, name) ?;
818
829
@@ -826,20 +837,50 @@ fn expand_svd_register(
826
837
/// Convert a parsed `Register` into its `Field` equivalent
827
838
fn convert_svd_register ( register : & Register , name : Option < & str > ) -> Result < syn:: Field , syn:: Error > {
828
839
Ok ( match register {
829
- Register :: Single ( info) => new_syn_field (
830
- & info. name . to_sanitized_snake_case ( ) ,
831
- name_to_wrapped_ty ( & info. name , name) ?,
832
- ) ,
840
+ Register :: Single ( info) => {
841
+ if let Some ( group) = & info. alternate_group {
842
+ new_syn_field (
843
+ & format ! (
844
+ "{}_{}" ,
845
+ & group. to_sanitized_snake_case( ) ,
846
+ & info. name. to_sanitized_snake_case( )
847
+ ) ,
848
+ name_to_wrapped_ty ( & format ! ( "{}_{}" , group, & info. name) , name) ?,
849
+ )
850
+ } else {
851
+ new_syn_field (
852
+ & info. name . to_sanitized_snake_case ( ) ,
853
+ name_to_wrapped_ty ( & info. name , name) ?,
854
+ )
855
+ }
856
+ }
833
857
Register :: Array ( info, array_info) => {
834
858
let nb_name = util:: replace_suffix ( & info. name , "" ) ;
835
859
836
- let ty = syn:: Type :: Array ( parse_str :: < syn:: TypeArray > ( & format ! (
837
- "[{};{}]" ,
838
- name_to_wrapped_ty_str( & nb_name, name) ,
839
- u64 :: from( array_info. dim)
840
- ) ) ?) ;
860
+ if let Some ( group) = & info. alternate_group {
861
+ let ty = syn:: Type :: Array ( parse_str :: < syn:: TypeArray > ( & format ! (
862
+ "[{};{}]" ,
863
+ name_to_wrapped_ty_str( & format!( "{}_{}" , group, & nb_name) , name) ,
864
+ u64 :: from( array_info. dim)
865
+ ) ) ?) ;
866
+
867
+ new_syn_field (
868
+ & format ! (
869
+ "{}_{}" ,
870
+ & group. to_sanitized_snake_case( ) ,
871
+ & nb_name. to_sanitized_snake_case( )
872
+ ) ,
873
+ ty,
874
+ )
875
+ } else {
876
+ let ty = syn:: Type :: Array ( parse_str :: < syn:: TypeArray > ( & format ! (
877
+ "[{};{}]" ,
878
+ name_to_wrapped_ty_str( & nb_name, name) ,
879
+ u64 :: from( array_info. dim)
880
+ ) ) ?) ;
841
881
842
- new_syn_field ( & nb_name. to_sanitized_snake_case ( ) , ty)
882
+ new_syn_field ( & nb_name. to_sanitized_snake_case ( ) , ty)
883
+ }
843
884
}
844
885
} )
845
886
}
0 commit comments