@@ -221,8 +221,9 @@ pub fn fields(
221221 width,
222222 range_type : _,
223223 } = 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 ( ) ;
226227 let span = Span :: call_site ( ) ;
227228 let pc_r = Ident :: new ( & format ! ( "{}_A" , pc) , span) ;
228229 let _pc_r = Ident :: new ( & format ! ( "{}_R" , pc) , span) ;
@@ -234,26 +235,46 @@ pub fn fields(
234235 } else {
235236 "bits"
236237 } , 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- }
246238 let description = if let Some ( d) = & f. description {
247239 util:: respace ( & util:: escape_brackets ( d) )
248240 } else {
249241 "" . to_owned ( )
250242 } ;
251243
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+
252274 Ok ( F {
253275 _pc_w,
254276 _sc,
255277 description,
256- description_with_bits,
257278 pc_r,
258279 _pc_r,
259280 pc_w,
@@ -267,6 +288,7 @@ pub fn fields(
267288 offset : u64:: from ( offset) ,
268289 ty : width. to_ty ( ) ?,
269290 write_constraint : f. write_constraint . as_ref ( ) ,
291+ dim,
270292 } )
271293 }
272294 }
@@ -306,10 +328,10 @@ pub fn fields(
306328 let _pc_r = & f. _pc_r ;
307329 let _pc_w = & f. _pc_w ;
308330 let description = & f. description ;
309- let description_with_bits = & f . description_with_bits ;
331+ let width = f . width ;
310332
311333 if can_read {
312- let cast = if f . width == 1 {
334+ let cast = if width == 1 {
313335 quote ! { != 0 }
314336 } else {
315337 quote ! { as #fty }
@@ -325,17 +347,56 @@ pub fn fields(
325347 }
326348 } ;
327349
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 ;
332358 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]
334391 #[ inline( always) ]
335392 pub fn #sc( & self ) -> #_pc_r {
336393 #_pc_r:: new( #value )
337394 }
338395 } ) ;
396+ }
397+
398+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
399+ evs_r = Some ( evs. clone ( ) ) ;
339400
340401 base_pc_w = base. as_ref ( ) . map ( |base| {
341402 let pc = base. field . to_sanitized_upper_case ( ) ;
@@ -352,7 +413,7 @@ pub fn fields(
352413 } ) ;
353414
354415 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) ;
356417 let variants = Variant :: from_enumerated_values ( evs) ?;
357418
358419 add_from_variants ( mod_items, & variants, pc_r, & f, description, rv) ;
@@ -362,7 +423,7 @@ pub fn fields(
362423 let mut arms = variants
363424 . iter ( )
364425 . map ( |v| {
365- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
426+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
366427 let pc = & v. pc ;
367428
368429 if has_reserved_variant {
@@ -377,7 +438,7 @@ pub fn fields(
377438 arms. push ( quote ! {
378439 i => Res ( i)
379440 } ) ;
380- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
441+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
381442 arms. push ( quote ! {
382443 _ => unreachable!( )
383444 } ) ;
@@ -437,15 +498,6 @@ pub fn fields(
437498 }
438499
439500 } 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-
449501 let doc = format ! ( "Reader of field `{}`" , f. name) ;
450502 mod_items. push ( quote ! {
451503 #[ doc = #doc]
@@ -458,13 +510,12 @@ pub fn fields(
458510 if can_write {
459511 let mut proxy_items = vec ! [ ] ;
460512
461- let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
462- let width = f. width ;
513+ let mut unsafety = unsafety ( f. write_constraint , width) ;
463514
464515 if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
465516 let variants = Variant :: from_enumerated_values ( evs) ?;
466517
467- if variants. len ( ) == 1 << f . width {
518+ if variants. len ( ) == 1 << width {
468519 unsafety = None ;
469520 }
470521
@@ -533,7 +584,19 @@ pub fn fields(
533584 } ) ;
534585 }
535586
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 {
537600 let offset = & util:: unsuffixed ( offset) ;
538601 quote ! {
539602 ///Writes raw bits to the field
@@ -554,11 +617,18 @@ pub fn fields(
554617 }
555618 } ) ;
556619
620+ let n_entry = if f. dim . is_some ( ) {
621+ quote ! { n: u32 , }
622+ } else {
623+ quote ! { }
624+ } ;
625+
557626 let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
558627 mod_items. push ( quote ! {
559628 #[ doc = #doc]
560629 pub struct #_pc_w<' a> {
561630 w: & ' a mut W ,
631+ #n_entry
562632 }
563633
564634 impl <' a> #_pc_w<' a> {
@@ -567,13 +637,39 @@ pub fn fields(
567637 } ) ;
568638
569639 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+ } ) ;
575662 }
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+ }
577673 }
578674 }
579675
@@ -719,12 +815,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719815 }
720816}
721817
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+
722831struct F < ' a > {
723832 _pc_w : Ident ,
724833 _sc : Ident ,
725834 access : Option < Access > ,
726835 description : String ,
727- description_with_bits : String ,
728836 evs : & ' a [ EnumeratedValues ] ,
729837 mask : u64 ,
730838 name : & ' a str ,
@@ -737,6 +845,7 @@ struct F<'a> {
737845 ty : Ident ,
738846 width : u32 ,
739847 write_constraint : Option < & ' a WriteConstraint > ,
848+ dim : Option < ( u32 , u32 , TokenStream , Vec < Ident > ) > ,
740849}
741850
742851#[ derive( Clone , Debug ) ]
0 commit comments