@@ -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
}
@@ -630,6 +636,7 @@ pub fn fields(
630
636
pc_r : Ident ,
631
637
pc_w : Ident ,
632
638
sc : Ident ,
639
+ bits : Ident ,
633
640
ty : Ident ,
634
641
width : u32 ,
635
642
write_constraint : Option < & ' a WriteConstraint > ,
@@ -644,6 +651,11 @@ pub fn fields(
644
651
let pc_w = Ident :: new ( & * format ! ( "{}W" , pc) ) ;
645
652
let _pc_w = Ident :: new ( & * format ! ( "_{}W" , pc) ) ;
646
653
let _sc = Ident :: new ( & * format ! ( "_{}" , sc) ) ;
654
+ let bits = if width == 1 {
655
+ Ident :: new ( "bit" )
656
+ } else {
657
+ Ident :: new ( "bits" )
658
+ } ;
647
659
let mut description = if width == 1 {
648
660
format ! ( "Bit {}" , offset)
649
661
} else {
@@ -660,11 +672,12 @@ pub fn fields(
660
672
description : description,
661
673
pc_r : pc_r,
662
674
pc_w : pc_w,
675
+ bits : bits,
663
676
width : width,
664
677
access : f. access ,
665
678
evs : & f. enumerated_values ,
666
679
sc : Ident :: new ( & * sc) ,
667
- mask : util:: unsuffixed ( ( 1 << width) - 1 ) ,
680
+ mask : util:: unsuffixed_or_bool ( ( 1 << width) - 1 , width ) ,
668
681
name : & f. name ,
669
682
offset : util:: unsuffixed ( u64 ( f. bit_range . offset ) ) ,
670
683
ty : width. to_ty ( ) ?,
@@ -683,14 +696,20 @@ pub fn fields(
683
696
continue ;
684
697
}
685
698
699
+ let bits = & f. bits ;
686
700
let mask = & f. mask ;
687
701
let offset = & f. offset ;
688
702
let fty = & f. ty ;
689
- let bits = quote ! {
703
+ let cast = if f. width == 1 {
704
+ quote ! { != 0 }
705
+ } else {
706
+ quote ! { as #fty }
707
+ } ;
708
+ let value = quote ! {
690
709
const MASK : #fty = #mask;
691
710
const OFFSET : u8 = #offset;
692
711
693
- ( ( self . bits >> OFFSET ) & MASK as #rty) as #fty
712
+ ( ( self . bits >> OFFSET ) & MASK as #rty) #cast
694
713
} ;
695
714
696
715
if let Some ( ( evs, base) ) =
@@ -768,7 +787,7 @@ pub fn fields(
768
787
#[ doc = #description]
769
788
#[ inline( always) ]
770
789
pub fn #sc( & self ) -> #pc_r {
771
- #pc_r:: _from( { #bits } )
790
+ #pc_r:: _from( { #value } )
772
791
}
773
792
} ,
774
793
) ;
@@ -814,7 +833,7 @@ pub fn fields(
814
833
. iter ( )
815
834
. map (
816
835
|v| {
817
- let value = util:: unsuffixed ( v. value ) ;
836
+ let value = util:: unsuffixed_or_bool ( v. value , f . width ) ;
818
837
let pc = & v. pc ;
819
838
820
839
quote ! {
@@ -834,7 +853,7 @@ pub fn fields(
834
853
quote ! {
835
854
/// Value of the field as raw bits
836
855
#[ inline( always) ]
837
- pub fn bits( & self ) -> #fty {
856
+ pub fn # bits( & self ) -> #fty {
838
857
match * self {
839
858
#( #arms) , *
840
859
}
@@ -846,7 +865,7 @@ pub fn fields(
846
865
. iter ( )
847
866
. map (
848
867
|v| {
849
- let i = util:: unsuffixed ( v. value ) ;
868
+ let i = util:: unsuffixed_or_bool ( v. value , f . width ) ;
850
869
let pc = & v. pc ;
851
870
852
871
quote ! {
@@ -862,7 +881,7 @@ pub fn fields(
862
881
i => #pc_r:: _Reserved( i)
863
882
} ,
864
883
) ;
865
- } else {
884
+ } else if 1 << f . width . to_ty_width ( ) ? != variants . len ( ) {
866
885
arms. push (
867
886
quote ! {
868
887
_ => unreachable!( )
@@ -875,8 +894,8 @@ pub fn fields(
875
894
#[ allow( missing_docs) ]
876
895
#[ doc( hidden) ]
877
896
#[ inline( always) ]
878
- pub fn _from( bits : #fty) -> #pc_r {
879
- match bits {
897
+ pub fn _from( value : #fty) -> #pc_r {
898
+ match value {
880
899
#( #arms) , * ,
881
900
}
882
901
}
@@ -925,7 +944,7 @@ pub fn fields(
925
944
#[ doc = #description]
926
945
#[ inline( always) ]
927
946
pub fn #sc( & self ) -> #pc_r {
928
- let bits = { # bits } ;
947
+ let bits = { #value } ;
929
948
#pc_r { bits }
930
949
}
931
950
} ,
@@ -941,7 +960,7 @@ pub fn fields(
941
960
impl #pc_r {
942
961
/// Value of the field as raw bits
943
962
#[ inline( always) ]
944
- pub fn bits( & self ) -> #fty {
963
+ pub fn # bits( & self ) -> #fty {
945
964
self . bits
946
965
}
947
966
}
@@ -961,9 +980,11 @@ pub fn fields(
961
980
let mut proxy_items = vec ! [ ] ;
962
981
963
982
let mut unsafety = unsafety ( f. write_constraint , f. width ) ;
983
+ let bits = & f. bits ;
964
984
let fty = & f. ty ;
965
985
let offset = & f. offset ;
966
986
let mask = & f. mask ;
987
+ let width = f. width ;
967
988
968
989
if let Some ( ( evs, base) ) =
969
990
util:: lookup (
@@ -1069,7 +1090,7 @@ pub fn fields(
1069
1090
. map (
1070
1091
|v| {
1071
1092
let pc = & v. pc ;
1072
- let value = util:: unsuffixed ( v. value ) ;
1093
+ let value = util:: unsuffixed_or_bool ( v. value , f . width ) ;
1073
1094
1074
1095
quote ! {
1075
1096
#pc_w:: #pc => #value
@@ -1100,7 +1121,7 @@ pub fn fields(
1100
1121
#[ inline( always) ]
1101
1122
pub fn variant( self , variant: #pc_w) -> & ' a mut W {
1102
1123
#unsafety {
1103
- self . bits( variant. _bits( ) )
1124
+ self . # bits( variant. _bits( ) )
1104
1125
}
1105
1126
}
1106
1127
} ,
@@ -1133,18 +1154,32 @@ pub fn fields(
1133
1154
) ;
1134
1155
}
1135
1156
}
1157
+ } else if width == 1 {
1158
+ proxy_items. push (
1159
+ quote ! {
1160
+ /// Sets the field bit
1161
+ pub fn set( self ) -> & ' a mut W {
1162
+ self . bit( true )
1163
+ }
1164
+
1165
+ /// Clears the field bit
1166
+ pub fn clear( self ) -> & ' a mut W {
1167
+ self . bit( false )
1168
+ }
1169
+ }
1170
+ ) ;
1136
1171
}
1137
1172
1138
1173
proxy_items. push (
1139
1174
quote ! {
1140
1175
/// Writes raw bits to the field
1141
1176
#[ inline( always) ]
1142
- pub #unsafety fn bits( self , bits : #fty) -> & ' a mut W {
1177
+ pub #unsafety fn # bits( self , value : #fty) -> & ' a mut W {
1143
1178
const MASK : #fty = #mask;
1144
1179
const OFFSET : u8 = #offset;
1145
1180
1146
1181
self . w. bits &= !( ( MASK as #rty) << OFFSET ) ;
1147
- self . w. bits |= ( ( bits & MASK ) as #rty) << OFFSET ;
1182
+ self . w. bits |= ( ( value & MASK ) as #rty) << OFFSET ;
1148
1183
self . w
1149
1184
}
1150
1185
} ,
0 commit comments