Skip to content

Commit 8f49896

Browse files
committed
Generate safe bits writers when possible
The 'bits' method of register writers can be safe if: * there is a single field that covers the entire register * that field can represent all values
1 parent 877196f commit 8f49896

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3131
- Bumped `xtensa-lx` and add `xtensa_lx::interrupt::InterruptNumber` implementation.
3232
- Don't use a mask when the width of the mask is the same as the width of the parent register.
3333
- Improved error handling
34+
- Registers with single fields that span the entire register now generate safe `bits` writers.
3435

3536
## [v0.19.0] - 2021-05-26
3637

src/generate/register.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use core::u64;
77
use log::warn;
88
use proc_macro2::{Ident, Punct, Spacing, Span, TokenStream};
99
use quote::{quote, ToTokens};
10+
use std::ops::Deref;
1011

1112
use crate::util::{self, Config, ToSanitizedSnakeCase, ToSanitizedUpperCase, U32Ext};
1213
use anyhow::{anyhow, Result};
@@ -168,10 +169,34 @@ pub fn render(
168169

169170
mod_items.extend(w_impl_items);
170171

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+
171196
mod_items.extend(quote! {
172197
#[doc = "Writes raw bits to the register."]
173198
#[inline(always)]
174-
pub unsafe fn bits(&mut self, bits: #rty) -> &mut Self {
199+
pub #unsafefn fn bits(&mut self, bits: #rty) -> &mut Self {
175200
self.0.bits(bits);
176201
self
177202
}

0 commit comments

Comments
 (0)