@@ -402,6 +402,12 @@ fn unsafety(write_constraint: Option<&WriteConstraint>, width: u32) -> Option<Id
402
402
// any value that can fit in the field
403
403
None
404
404
}
405
+ None if width == 1 => {
406
+ // the field is one bit wide, so we assume it's legal to write
407
+ // either value into it or it wouldn't exist; despite that
408
+ // if a writeConstraint exists then respect it
409
+ None
410
+ }
405
411
_ => Some ( Ident :: new ( "unsafe" ) )
406
412
}
407
413
}
@@ -635,6 +641,7 @@ pub fn fields(
635
641
pc_r : Ident ,
636
642
pc_w : Ident ,
637
643
sc : Ident ,
644
+ bits : Ident ,
638
645
ty : Ident ,
639
646
width : u32 ,
640
647
write_constraint : Option < & ' a WriteConstraint > ,
@@ -649,6 +656,11 @@ pub fn fields(
649
656
let pc_w = Ident :: new ( & * format ! ( "{}W" , pc) ) ;
650
657
let _pc_w = Ident :: new ( & * format ! ( "_{}W" , pc) ) ;
651
658
let _sc = Ident :: new ( & * format ! ( "_{}" , sc) ) ;
659
+ let bits = if width == 1 {
660
+ Ident :: new ( "bit" )
661
+ } else {
662
+ Ident :: new ( "bits" )
663
+ } ;
652
664
let mut description = if width == 1 {
653
665
format ! ( "Bit {}" , offset)
654
666
} else {
@@ -665,11 +677,12 @@ pub fn fields(
665
677
description : description,
666
678
pc_r : pc_r,
667
679
pc_w : pc_w,
680
+ bits : bits,
668
681
width : width,
669
682
access : f. access ,
670
683
evs : & f. enumerated_values ,
671
684
sc : Ident :: new ( & * sc) ,
672
- mask : util:: unsuffixed ( ( 1 << width) - 1 ) ,
685
+ mask : util:: unsuffixed_or_bool ( ( 1 << width) - 1 , width ) ,
673
686
name : & f. name ,
674
687
offset : util:: unsuffixed ( u64 ( f. bit_range . offset ) ) ,
675
688
ty : width. to_ty ( ) ?,
@@ -688,14 +701,20 @@ pub fn fields(
688
701
continue ;
689
702
}
690
703
704
+ let bits = & f. bits ;
691
705
let mask = & f. mask ;
692
706
let offset = & f. offset ;
693
707
let fty = & f. ty ;
694
- let bits = quote ! {
708
+ let cast = if f. width == 1 {
709
+ quote ! { != 0 }
710
+ } else {
711
+ quote ! { as #fty }
712
+ } ;
713
+ let value = quote ! {
695
714
const MASK : #fty = #mask;
696
715
const OFFSET : u8 = #offset;
697
716
698
- ( ( self . bits >> OFFSET ) & MASK as #rty) as #fty
717
+ ( ( self . bits >> OFFSET ) & MASK as #rty) #cast
699
718
} ;
700
719
701
720
if let Some ( ( evs, base) ) =
@@ -775,7 +794,7 @@ pub fn fields(
775
794
#[ doc = #description]
776
795
#[ inline( always) ]
777
796
pub fn #sc( & self ) -> #pc_r {
778
- #pc_r:: _from( { #bits } )
797
+ #pc_r:: _from( { #value } )
779
798
}
780
799
} ,
781
800
) ;
@@ -821,7 +840,7 @@ pub fn fields(
821
840
. iter ( )
822
841
. map (
823
842
|v| {
824
- let value = util:: unsuffixed ( v. value ) ;
843
+ let value = util:: unsuffixed_or_bool ( v. value , f . width ) ;
825
844
let pc = & v. pc ;
826
845
827
846
quote ! {
@@ -841,7 +860,7 @@ pub fn fields(
841
860
quote ! {
842
861
/// Value of the field as raw bits
843
862
#[ inline( always) ]
844
- pub fn bits( & self ) -> #fty {
863
+ pub fn # bits( & self ) -> #fty {
845
864
match * self {
846
865
#( #arms) , *
847
866
}
@@ -853,7 +872,7 @@ pub fn fields(
853
872
. iter ( )
854
873
. map (
855
874
|v| {
856
- let i = util:: unsuffixed ( v. value ) ;
875
+ let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
857
876
let pc = & v. pc ;
858
877
859
878
quote ! {
@@ -869,7 +888,7 @@ pub fn fields(
869
888
i => #pc_r:: _Reserved( i)
870
889
} ,
871
890
) ;
872
- } else {
891
+ } else if 1 << f . width . to_ty_width ( ) ? != variants . len ( ) {
873
892
arms. push (
874
893
quote ! {
875
894
_ => unreachable!( )
@@ -882,8 +901,8 @@ pub fn fields(
882
901
#[ allow( missing_docs) ]
883
902
#[ doc( hidden) ]
884
903
#[ inline( always) ]
885
- pub fn _from( bits : #fty) -> #pc_r {
886
- match bits {
904
+ pub fn _from( value : #fty) -> #pc_r {
905
+ match value {
887
906
#( #arms) , * ,
888
907
}
889
908
}
@@ -932,7 +951,7 @@ pub fn fields(
932
951
#[ doc = #description]
933
952
#[ inline( always) ]
934
953
pub fn #sc( & self ) -> #pc_r {
935
- let bits = { # bits } ;
954
+ let bits = { #value } ;
936
955
#pc_r { bits }
937
956
}
938
957
} ,
@@ -948,7 +967,7 @@ pub fn fields(
948
967
impl #pc_r {
949
968
/// Value of the field as raw bits
950
969
#[ inline( always) ]
951
- pub fn bits( & self ) -> #fty {
970
+ pub fn # bits( & self ) -> #fty {
952
971
self . bits
953
972
}
954
973
}
@@ -968,9 +987,11 @@ pub fn fields(
968
987
let mut proxy_items = vec ! [ ] ;
969
988
970
989
let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
990
+ let bits = & f. bits ;
971
991
let fty = & f. ty ;
972
992
let offset = & f. offset ;
973
993
let mask = & f. mask ;
994
+ let width = f. width ;
974
995
975
996
if let Some ( ( evs, base) ) =
976
997
util:: lookup (
@@ -1078,7 +1099,7 @@ pub fn fields(
1078
1099
. map (
1079
1100
|v| {
1080
1101
let pc = & v. pc ;
1081
- let value = util:: unsuffixed ( v. value ) ;
1102
+ let value = util:: unsuffixed_or_bool ( v. value , f . width ) ;
1082
1103
1083
1104
quote ! {
1084
1105
#pc_w:: #pc => #value
@@ -1109,7 +1130,7 @@ pub fn fields(
1109
1130
#[ inline( always) ]
1110
1131
pub fn variant( self , variant: #pc_w) -> & ' a mut W {
1111
1132
#unsafety {
1112
- self . bits( variant. _bits( ) )
1133
+ self . # bits( variant. _bits( ) )
1113
1134
}
1114
1135
}
1115
1136
} ,
@@ -1142,18 +1163,32 @@ pub fn fields(
1142
1163
) ;
1143
1164
}
1144
1165
}
1166
+ } else if width == 1 {
1167
+ proxy_items. push (
1168
+ quote ! {
1169
+ /// Sets the field bit
1170
+ pub fn set( self ) -> & ' a mut W {
1171
+ self . bit( true )
1172
+ }
1173
+
1174
+ /// Clears the field bit
1175
+ pub fn clear( self ) -> & ' a mut W {
1176
+ self . bit( false )
1177
+ }
1178
+ }
1179
+ ) ;
1145
1180
}
1146
1181
1147
1182
proxy_items. push (
1148
1183
quote ! {
1149
1184
/// Writes raw bits to the field
1150
1185
#[ inline( always) ]
1151
- pub #unsafety fn bits( self , bits : #fty) -> & ' a mut W {
1186
+ pub #unsafety fn # bits( self , value : #fty) -> & ' a mut W {
1152
1187
const MASK : #fty = #mask;
1153
1188
const OFFSET : u8 = #offset;
1154
1189
1155
1190
self . w. bits &= !( ( MASK as #rty) << OFFSET ) ;
1156
- self . w. bits |= ( ( bits & MASK ) as #rty) << OFFSET ;
1191
+ self . w. bits |= ( ( value & MASK ) as #rty) << OFFSET ;
1157
1192
self . w
1158
1193
}
1159
1194
} ,
0 commit comments