@@ -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:: replace_suffix ( & f. name , "" ) ;
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,43 @@ 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+ 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+
252271 Ok ( F {
253272 _pc_w,
254273 _sc,
255274 description,
256- description_with_bits,
257275 pc_r,
258276 _pc_r,
259277 pc_w,
@@ -267,6 +285,7 @@ pub fn fields(
267285 offset : u64:: from ( offset) ,
268286 ty : width. to_ty ( ) ?,
269287 write_constraint : f. write_constraint . as_ref ( ) ,
288+ dim,
270289 } )
271290 }
272291 }
@@ -306,10 +325,10 @@ pub fn fields(
306325 let _pc_r = & f. _pc_r ;
307326 let _pc_w = & f. _pc_w ;
308327 let description = & f. description ;
309- let description_with_bits = & f . description_with_bits ;
328+ let width = f . width ;
310329
311330 if can_read {
312- let cast = if f . width == 1 {
331+ let cast = if width == 1 {
313332 quote ! { != 0 }
314333 } else {
315334 quote ! { as #fty }
@@ -325,21 +344,72 @@ pub fn fields(
325344 }
326345 } ;
327346
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 ;
332367 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]
334401 #[ inline( always) ]
335402 pub fn #sc( & self ) -> #_pc_r {
336403 #_pc_r:: new( #value )
337404 }
338405 } ) ;
406+ }
407+
408+ if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Read ) {
409+ evs_r = Some ( evs. clone ( ) ) ;
339410
340411 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 ( ) ) ;
343413 let base_pc_r = derive_from_base ( mod_items, & base, & pc_r, & base_pc_r, description) ;
344414
345415 let doc = format ! ( "Reader of field `{}`" , f. name) ;
@@ -352,7 +422,7 @@ pub fn fields(
352422 } ) ;
353423
354424 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) ;
356426 let variants = Variant :: from_enumerated_values ( evs) ?;
357427
358428 add_from_variants ( mod_items, & variants, pc_r, & f, description, rv) ;
@@ -362,7 +432,7 @@ pub fn fields(
362432 let mut arms = variants
363433 . iter ( )
364434 . map ( |v| {
365- let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
435+ let i = util:: unsuffixed_or_bool ( v. value , width) ;
366436 let pc = & v. pc ;
367437
368438 if has_reserved_variant {
@@ -377,7 +447,7 @@ pub fn fields(
377447 arms. push ( quote ! {
378448 i => Res ( i)
379449 } ) ;
380- } else if 1 << f . width . to_ty_width ( ) ? != variants. len ( ) {
450+ } else if 1 << width. to_ty_width ( ) ? != variants. len ( ) {
381451 arms. push ( quote ! {
382452 _ => unreachable!( )
383453 } ) ;
@@ -437,15 +507,6 @@ pub fn fields(
437507 }
438508
439509 } 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-
449510 let doc = format ! ( "Reader of field `{}`" , f. name) ;
450511 mod_items. push ( quote ! {
451512 #[ doc = #doc]
@@ -458,22 +519,20 @@ pub fn fields(
458519 if can_write {
459520 let mut proxy_items = vec ! [ ] ;
460521
461- let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
462- let width = f. width ;
522+ let mut unsafety = unsafety ( f. write_constraint , width) ;
463523
464524 if let Some ( ( evs, base) ) = lookup_filter ( & lookup_results, Usage :: Write ) {
465525 let variants = Variant :: from_enumerated_values ( evs) ?;
466526
467- if variants. len ( ) == 1 << f . width {
527+ if variants. len ( ) == 1 << width {
468528 unsafety = None ;
469529 }
470530
471531 if Some ( evs) != evs_r. as_ref ( ) {
472532 pc_w = & f. pc_w ;
473533
474534 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 ( ) ) ;
477536 derive_from_base ( mod_items, & base, & pc_w, & base_pc_w, description)
478537 } ) ;
479538
@@ -533,7 +592,33 @@ pub fn fields(
533592 } ) ;
534593 }
535594
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 {
537622 let offset = & util:: unsuffixed ( offset) ;
538623 quote ! {
539624 ///Writes raw bits to the field
@@ -554,11 +639,18 @@ pub fn fields(
554639 }
555640 } ) ;
556641
642+ let n_entry = if f. dim . is_some ( ) {
643+ quote ! { n: u32 , }
644+ } else {
645+ quote ! { }
646+ } ;
647+
557648 let doc = format ! ( "Write proxy for field `{}`" , f. name) ;
558649 mod_items. push ( quote ! {
559650 #[ doc = #doc]
560651 pub struct #_pc_w<' a> {
561652 w: & ' a mut W ,
653+ #n_entry
562654 }
563655
564656 impl <' a> #_pc_w<' a> {
@@ -567,13 +659,39 @@ pub fn fields(
567659 } ) ;
568660
569661 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+ } ) ;
575684 }
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+ }
577695 }
578696 }
579697
@@ -719,12 +837,24 @@ fn derive_from_base(mod_items: &mut Vec<TokenStream>, base: &Base, pc: &Ident, b
719837 }
720838}
721839
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+
722853struct F < ' a > {
723854 _pc_w : Ident ,
724855 _sc : Ident ,
725856 access : Option < Access > ,
726857 description : String ,
727- description_with_bits : String ,
728858 evs : & ' a [ EnumeratedValues ] ,
729859 mask : u64 ,
730860 name : & ' a str ,
@@ -737,6 +867,7 @@ struct F<'a> {
737867 ty : Ident ,
738868 width : u32 ,
739869 write_constraint : Option < & ' a WriteConstraint > ,
870+ dim : Option < ( u32 , u32 , u32 , Vec < String > ) > ,
740871}
741872
742873#[ derive( Clone , Debug ) ]
0 commit comments