@@ -7,6 +7,7 @@ use core::u64;
7
7
use log:: warn;
8
8
use proc_macro2:: { Ident , Punct , Spacing , Span , TokenStream } ;
9
9
use quote:: { quote, ToTokens } ;
10
+ use std:: ops:: Deref ;
10
11
11
12
use crate :: util:: { self , Config , ToSanitizedSnakeCase , ToSanitizedUpperCase , U32Ext } ;
12
13
use anyhow:: { anyhow, Result } ;
@@ -168,10 +169,34 @@ pub fn render(
168
169
169
170
mod_items. extend ( w_impl_items) ;
170
171
172
+ // the writer can be safe if:
173
+ // * there is a single field that covers the entire register
174
+ // * that field can represent all values
175
+ let unsafefn: Option < Ident > = register
176
+ . deref ( )
177
+ . fields
178
+ . as_ref ( )
179
+ . map ( |fields| fields. iter ( ) . next ( ) )
180
+ . flatten ( )
181
+ . map ( |field| field. deref ( ) . write_constraint )
182
+ . flatten ( )
183
+ . map ( |constraint| match constraint {
184
+ WriteConstraint :: Range ( range) => {
185
+ if range. min == 0 && range. max == 2_u64 . pow ( rsize) - 1 {
186
+ None
187
+ } else {
188
+ Some ( ( ) )
189
+ }
190
+ }
191
+ _ => Some ( ( ) ) ,
192
+ } )
193
+ . flatten ( )
194
+ . map ( |_| Ident :: new ( "unsafe" , span) ) ;
195
+
171
196
mod_items. extend ( quote ! {
172
197
#[ doc = "Writes raw bits to the register." ]
173
198
#[ inline( always) ]
174
- pub unsafe fn bits( & mut self , bits: #rty) -> & mut Self {
199
+ pub #unsafefn fn bits( & mut self , bits: #rty) -> & mut Self {
175
200
self . 0 . bits( bits) ;
176
201
self
177
202
}
0 commit comments