@@ -567,7 +567,31 @@ impl<'a> RWEnum<'a> {
567
567
_ => None ,
568
568
}
569
569
}
570
- pub fn gen_write_enum ( & self ) -> bool {
570
+ pub fn generate_reader ( & self ) -> bool {
571
+ matches ! (
572
+ self ,
573
+ Self :: ReadAndWriteEnum ( ( _, None ) )
574
+ | Self :: ReadEnumWriteEnum ( ( _, None ) , _)
575
+ | Self :: ReadEnumWriteRaw ( ( _, None ) )
576
+ | Self :: ReadRawWriteEnum ( _)
577
+ | Self :: ReadEnum ( ( _, None ) )
578
+ | Self :: ReadRaw
579
+ | Self :: ReadRawWriteRaw
580
+ )
581
+ }
582
+ pub fn generate_writer ( & self ) -> bool {
583
+ matches ! (
584
+ self ,
585
+ Self :: ReadAndWriteEnum ( ( _, None ) )
586
+ | Self :: ReadEnumWriteEnum ( _, ( _, None ) )
587
+ | Self :: ReadRawWriteEnum ( ( _, None ) )
588
+ | Self :: ReadEnumWriteRaw ( _)
589
+ | Self :: WriteEnum ( ( _, None ) )
590
+ | Self :: WriteRaw
591
+ | Self :: ReadRawWriteRaw
592
+ )
593
+ }
594
+ pub fn generate_write_enum ( & self ) -> bool {
571
595
matches ! (
572
596
self ,
573
597
Self :: ReadEnumWriteEnum ( _, _) | Self :: ReadRawWriteEnum ( _) | Self :: WriteEnum ( _)
@@ -691,7 +715,7 @@ pub fn fields(
691
715
( true , None , false , _) => RWEnum :: ReadRaw ,
692
716
( false , _, true , Some ( e) ) => RWEnum :: WriteEnum ( e) ,
693
717
( false , _, true , None ) => RWEnum :: WriteRaw ,
694
- ( true , _ , true , _ ) => RWEnum :: ReadRawWriteRaw ,
718
+ ( true , None , true , None ) => RWEnum :: ReadRawWriteRaw ,
695
719
( false , _, false , _) => {
696
720
return Err ( anyhow ! ( "Field {fpath} is not writtable or readable" ) )
697
721
}
@@ -710,29 +734,6 @@ pub fn fields(
710
734
711
735
// If this field can be read, generate read proxy structure and value structure.
712
736
if can_read {
713
- let cast = if width == 1 {
714
- quote ! { != 0 }
715
- } else {
716
- quote ! { as #fty }
717
- } ;
718
- let value = if offset != 0 {
719
- let offset = & unsuffixed ( offset) ;
720
- quote ! { ( self . bits >> #offset) }
721
- } else {
722
- quote ! { self . bits }
723
- } ;
724
- let value = if use_mask && use_cast {
725
- quote ! { ( #value & #hexmask) #cast }
726
- } else if use_mask {
727
- quote ! { #value & #hexmask }
728
- } else {
729
- value
730
- } ;
731
-
732
- // get a brief description for this field
733
- // the suffix string from field name is removed in brief description.
734
- let field_reader_brief = format ! ( "Field `{name}{brief_suffix}` reader - {description}" ) ;
735
-
736
737
// get the type of value structure. It can be generated from either name field
737
738
// in enumeratedValues if it's an enumeration, or from field name directly if it's not.
738
739
let value_read_ty = if let Some ( ( evs, _) ) = rwenum. read_enum ( ) {
@@ -747,45 +748,6 @@ pub fn fields(
747
748
fty. clone ( )
748
749
} ;
749
750
750
- // name of read proxy type
751
- let reader_ty = ident ( & name, config, "field_reader" , span) ;
752
-
753
- // if it's enumeratedValues and it's derived from base, don't derive the read proxy
754
- // as the base has already dealt with this;
755
- // if it's enumeratedValues but not derived from base, derive the reader from
756
- // information in enumeratedValues;
757
- // if it's not enumeratedValues, always derive the read proxy as we do not need to re-export
758
- // it again from BitReader or FieldReader.
759
- let should_derive_reader = matches ! ( rwenum. read_enum( ) , Some ( ( _, None ) ) | None ) ;
760
-
761
- // derive the read proxy structure if necessary.
762
- if should_derive_reader {
763
- let reader = if width == 1 {
764
- if value_read_ty == "bool" {
765
- quote ! { crate :: BitReader }
766
- } else {
767
- quote ! { crate :: BitReader <#value_read_ty> }
768
- }
769
- } else if value_read_ty == "u8" {
770
- quote ! { crate :: FieldReader }
771
- } else {
772
- quote ! { crate :: FieldReader <#value_read_ty> }
773
- } ;
774
- let mut readerdoc = field_reader_brief. clone ( ) ;
775
- if let Some ( action) = f. read_action {
776
- readerdoc += match action {
777
- ReadAction :: Clear => "\n \n The field is **cleared** (set to zero) following a read operation." ,
778
- ReadAction :: Set => "\n \n The field is **set** (set to ones) following a read operation." ,
779
- ReadAction :: Modify => "\n \n The field is **modified** in some way after a read operation." ,
780
- ReadAction :: ModifyExternal => "\n \n One or more dependent resources other than the current field are immediately affected by a read operation." ,
781
- } ;
782
- }
783
- mod_items. extend ( quote ! {
784
- #[ doc = #readerdoc]
785
- pub type #reader_ty = #reader;
786
- } ) ;
787
- }
788
-
789
751
// collect information on items in enumeration to generate it later.
790
752
let mut enum_items = TokenStream :: new ( ) ;
791
753
@@ -927,11 +889,61 @@ pub fn fields(
927
889
} ) ;
928
890
}
929
891
}
892
+ } else if let Some ( ( _, Some ( base) ) ) = rwenum. read_enum ( ) {
893
+ // only pub use enum when derived from another register.
894
+ // If field is in the same register it emits
895
+ // pub use enum from same module which is not expected
896
+ if base. register ( ) != fpath. register ( ) {
897
+ // use the same enum structure name
898
+ if !enum_derives. contains ( & value_read_ty) {
899
+ let base_path = base_syn_path ( base, & fpath, & value_read_ty, config) ?;
900
+ mod_items. extend ( quote ! {
901
+ #[ doc = #description]
902
+ pub use #base_path as #value_read_ty;
903
+ } ) ;
904
+ enum_derives. insert ( value_read_ty. clone ( ) ) ;
905
+ }
906
+ }
930
907
}
931
908
932
- // if this value is derived from a base, generate `pub use` code for each read proxy and value
933
- // if necessary.
934
- if let Some ( ( _, Some ( base) ) ) = rwenum. read_enum ( ) {
909
+ // get a brief description for this field
910
+ // the suffix string from field name is removed in brief description.
911
+ let field_reader_brief = format ! ( "Field `{name}{brief_suffix}` reader - {description}" ) ;
912
+
913
+ // name of read proxy type
914
+ let reader_ty = ident ( & name, config, "field_reader" , span) ;
915
+
916
+ if rwenum. generate_reader ( ) {
917
+ // Generate the read proxy structure if necessary.
918
+
919
+ let reader = if width == 1 {
920
+ if value_read_ty == "bool" {
921
+ quote ! { crate :: BitReader }
922
+ } else {
923
+ quote ! { crate :: BitReader <#value_read_ty> }
924
+ }
925
+ } else if value_read_ty == "u8" {
926
+ quote ! { crate :: FieldReader }
927
+ } else {
928
+ quote ! { crate :: FieldReader <#value_read_ty> }
929
+ } ;
930
+ let mut readerdoc = field_reader_brief. clone ( ) ;
931
+ if let Some ( action) = f. read_action {
932
+ readerdoc += match action {
933
+ ReadAction :: Clear => "\n \n The field is **cleared** (set to zero) following a read operation." ,
934
+ ReadAction :: Set => "\n \n The field is **set** (set to ones) following a read operation." ,
935
+ ReadAction :: Modify => "\n \n The field is **modified** in some way after a read operation." ,
936
+ ReadAction :: ModifyExternal => "\n \n One or more dependent resources other than the current field are immediately affected by a read operation." ,
937
+ } ;
938
+ }
939
+ mod_items. extend ( quote ! {
940
+ #[ doc = #readerdoc]
941
+ pub type #reader_ty = #reader;
942
+ } ) ;
943
+ } else if let Some ( ( _, Some ( base) ) ) = rwenum. read_enum ( ) {
944
+ // if this value is derived from a base, generate `pub use` code for each read proxy
945
+ // and value if necessary.
946
+
935
947
// generate pub use field_1 reader as field_2 reader
936
948
let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
937
949
let base_r = ident ( & base_field, config, "field_reader" , span) ;
@@ -943,21 +955,15 @@ pub fn fields(
943
955
} ) ;
944
956
reader_derives. insert ( reader_ty. clone ( ) ) ;
945
957
}
946
- // only pub use enum when base.register != None. if base.register == None, it emits
947
- // pub use enum from same module which is not expected
948
- if base. register ( ) != fpath. register ( ) {
949
- // use the same enum structure name
950
- if !enum_derives. contains ( & value_read_ty) {
951
- let base_path = base_syn_path ( base, & fpath, & value_read_ty, config) ?;
952
- mod_items. extend ( quote ! {
953
- #[ doc = #description]
954
- pub use #base_path as #value_read_ty;
955
- } ) ;
956
- enum_derives. insert ( value_read_ty. clone ( ) ) ;
957
- }
958
- }
959
958
}
960
959
960
+ // Generate field reader accessors
961
+ let cast = if width == 1 {
962
+ quote ! { != 0 }
963
+ } else {
964
+ quote ! { as #fty }
965
+ } ;
966
+
961
967
if let Field :: Array ( f, de) = & f {
962
968
let increment = de. dim_increment ;
963
969
let doc = util:: replace_suffix ( & description, & brief_suffix) ;
@@ -1015,6 +1021,20 @@ pub fn fields(
1015
1021
} ) ;
1016
1022
}
1017
1023
} else {
1024
+ let value = if offset != 0 {
1025
+ let offset = & unsuffixed ( offset) ;
1026
+ quote ! { ( self . bits >> #offset) }
1027
+ } else {
1028
+ quote ! { self . bits }
1029
+ } ;
1030
+ let value = if use_mask && use_cast {
1031
+ quote ! { ( #value & #hexmask) #cast }
1032
+ } else if use_mask {
1033
+ quote ! { #value & #hexmask }
1034
+ } else {
1035
+ value
1036
+ } ;
1037
+
1018
1038
let doc = description_with_bits ( description_raw, offset, width) ;
1019
1039
r_impl_items. extend ( quote ! {
1020
1040
#[ doc = #doc]
@@ -1038,10 +1058,6 @@ pub fn fields(
1038
1058
// If this field can be written, generate write proxy. Generate write value if it differs from
1039
1059
// the read value, or else we reuse read value.
1040
1060
if can_write {
1041
- let mwv = f. modified_write_values . or ( rmwv) . unwrap_or_default ( ) ;
1042
- // gets a brief of write proxy
1043
- let field_writer_brief = format ! ( "Field `{name}{brief_suffix}` writer - {description}" ) ;
1044
-
1045
1061
let value_write_ty = if let Some ( ( evs, _) ) = rwenum. write_enum ( ) {
1046
1062
let fmt = if rwenum. different_enums ( ) {
1047
1063
"enum_write_name"
@@ -1054,9 +1070,6 @@ pub fn fields(
1054
1070
fty. clone ( )
1055
1071
} ;
1056
1072
1057
- // name of write proxy type
1058
- let writer_ty = ident ( & name, config, "field_writer" , span) ;
1059
-
1060
1073
let mut proxy_items = TokenStream :: new ( ) ;
1061
1074
let mut unsafety = unsafety ( f. write_constraint . as_ref ( ) , width) ;
1062
1075
@@ -1083,7 +1096,7 @@ pub fn fields(
1083
1096
}
1084
1097
1085
1098
// generate write value structure and From conversation if we can't reuse read value structure.
1086
- if rwenum. gen_write_enum ( ) {
1099
+ if rwenum. generate_write_enum ( ) {
1087
1100
if variants. is_empty ( ) {
1088
1101
add_with_no_variants (
1089
1102
mod_items,
@@ -1119,14 +1132,33 @@ pub fn fields(
1119
1132
}
1120
1133
} ) ;
1121
1134
}
1135
+ } else if let Some ( ( _, Some ( base) ) ) = rwenum. write_enum ( ) {
1136
+ // If field is in the same register it emits pub use structure from same module.
1137
+ if base. register ( ) != fpath. register ( ) {
1138
+ if rwenum. generate_write_enum ( ) {
1139
+ // use the same enum structure name
1140
+ if !writer_enum_derives. contains ( & value_write_ty) {
1141
+ let base_path = base_syn_path ( base, & fpath, & value_write_ty, config) ?;
1142
+ mod_items. extend ( quote ! {
1143
+ #[ doc = #description]
1144
+ pub use #base_path as #value_write_ty;
1145
+ } ) ;
1146
+ writer_enum_derives. insert ( value_write_ty. clone ( ) ) ;
1147
+ }
1148
+ }
1149
+ }
1122
1150
}
1123
1151
1124
- // derive writer. We derive writer if the write proxy is in current register module,
1125
- // or writer in different register have different _SPEC structures
1126
- let should_derive_writer = matches ! ( rwenum. write_enum( ) , Some ( ( _, None ) ) | None ) ;
1152
+ let mwv = f. modified_write_values . or ( rmwv) . unwrap_or_default ( ) ;
1153
+
1154
+ // gets a brief of write proxy
1155
+ let field_writer_brief = format ! ( "Field `{name}{brief_suffix}` writer - {description}" ) ;
1156
+
1157
+ // name of write proxy type
1158
+ let writer_ty = ident ( & name, config, "field_writer" , span) ;
1127
1159
1128
- // derive writer structure by type alias to generic write proxy structure.
1129
- if should_derive_writer {
1160
+ // Generate writer structure by type alias to generic write proxy structure.
1161
+ if rwenum . generate_writer ( ) {
1130
1162
let proxy = if width == 1 {
1131
1163
use ModifiedWriteValues :: * ;
1132
1164
let wproxy = Ident :: new (
@@ -1166,6 +1198,23 @@ pub fn fields(
1166
1198
#[ doc = #field_writer_brief]
1167
1199
pub type #writer_ty<' a, REG > = #proxy;
1168
1200
} ) ;
1201
+ } else if let Some ( ( _, Some ( base) ) ) = rwenum. write_enum ( ) {
1202
+ // if base.register == None, derive write from the same module. This is allowed because both
1203
+ // the generated and source write proxy are in the same module.
1204
+ // we never reuse writer for writer in different module does not have the same _SPEC strcuture,
1205
+ // thus we cannot write to current register using re-exported write proxy.
1206
+
1207
+ // generate pub use field_1 writer as field_2 writer
1208
+ let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
1209
+ let base_w = ident ( & base_field, config, "field_writer" , span) ;
1210
+ if !writer_derives. contains ( & writer_ty) {
1211
+ let base_path = base_syn_path ( base, & fpath, & base_w, config) ?;
1212
+ mod_items. extend ( quote ! {
1213
+ #[ doc = #field_writer_brief]
1214
+ pub use #base_path as #writer_ty;
1215
+ } ) ;
1216
+ writer_derives. insert ( writer_ty. clone ( ) ) ;
1217
+ }
1169
1218
}
1170
1219
1171
1220
// generate proxy items from collected information
@@ -1192,39 +1241,7 @@ pub fn fields(
1192
1241
} ) ;
1193
1242
}
1194
1243
1195
- if let Some ( ( _, Some ( base) ) ) = rwenum. write_enum ( ) {
1196
- // if base.register == None, derive write from the same module. This is allowed because both
1197
- // the generated and source write proxy are in the same module.
1198
- // we never reuse writer for writer in different module does not have the same _SPEC strcuture,
1199
- // thus we cannot write to current register using re-exported write proxy.
1200
-
1201
- // generate pub use field_1 writer as field_2 writer
1202
- let base_field = util:: replace_suffix ( & base. field . name , "" ) ;
1203
- let base_w = ident ( & base_field, config, "field_writer" , span) ;
1204
- if !writer_derives. contains ( & writer_ty) {
1205
- let base_path = base_syn_path ( base, & fpath, & base_w, config) ?;
1206
- mod_items. extend ( quote ! {
1207
- #[ doc = #field_writer_brief]
1208
- pub use #base_path as #writer_ty;
1209
- } ) ;
1210
- writer_derives. insert ( writer_ty. clone ( ) ) ;
1211
- }
1212
- // if base.register == None, it emits pub use structure from same module.
1213
- if base. register ( ) != fpath. register ( ) {
1214
- if rwenum. gen_write_enum ( ) {
1215
- // use the same enum structure name
1216
- if !writer_enum_derives. contains ( & value_write_ty) {
1217
- let base_path = base_syn_path ( base, & fpath, & value_write_ty, config) ?;
1218
- mod_items. extend ( quote ! {
1219
- #[ doc = #description]
1220
- pub use #base_path as #value_write_ty;
1221
- } ) ;
1222
- writer_enum_derives. insert ( value_write_ty. clone ( ) ) ;
1223
- }
1224
- }
1225
- }
1226
- }
1227
-
1244
+ // Generate field writer accessors
1228
1245
if let Field :: Array ( f, de) = & f {
1229
1246
let increment = de. dim_increment ;
1230
1247
let offset_calc = calculate_offset ( increment, offset, false ) ;
@@ -1276,6 +1293,8 @@ pub fn fields(
1276
1293
}
1277
1294
} ) ;
1278
1295
}
1296
+
1297
+ // Update register modify bit masks
1279
1298
let bitmask = ( u64:: MAX >> ( 64 - width) ) << offset;
1280
1299
use ModifiedWriteValues :: * ;
1281
1300
match mwv {
0 commit comments