Skip to content

Commit 5a762c1

Browse files
bors[bot]burrbull
andauthored
Merge #503
503: implement both owning and const generic field array writers r=adamgreig a=burrbull Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 26ddbe1 + 54a44ff commit 5a762c1

File tree

5 files changed

+113
-37
lines changed

5 files changed

+113
-37
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,22 @@ jobs:
2323
# Temporary hack as long as we use the current CI script
2424
TRAVIS_OS_NAME: [linux]
2525

26+
FEATURES: [""]
27+
2628
include:
2729
# Test MSRV
2830
- rust: 1.40.0
2931
VENDOR: Nordic
3032
TARGET: x86_64-unknown-linux-gnu
3133
TRAVIS_OS_NAME: linux
3234

35+
# Test features
36+
- rust: 1.51.0
37+
VENDOR: RISC-V
38+
TARGET: x86_64-unknown-linux-gnu
39+
TRAVIS_OS_NAME: linux
40+
FEATURES: "strict,const-generic"
41+
3342
# Use nightly for architectures which don't support stable
3443
- rust: nightly
3544
experimental: true
@@ -64,4 +73,4 @@ jobs:
6473
override: true
6574
components: rustfmt
6675
- name: Run CI script for ${{ matrix.VENDOR }} under ${{ matrix.rust }}
67-
run: TARGET=${{ matrix.TARGET }} VENDOR=${{ matrix.VENDOR }} TRAVIS_OS_NAME=${{ matrix.TRAVIS_OS_NAME }} bash ci/script.sh
76+
run: TARGET=${{ matrix.TARGET }} VENDOR=${{ matrix.VENDOR }} TRAVIS_OS_NAME=${{ matrix.TRAVIS_OS_NAME }} FEATURES=${{ matrix.FEATURES }} bash ci/script.sh

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3030

3131
### Changed
3232

33+
- with feature "const-generic" generate const generic variant of
34+
"field array" structure in addition to structure
35+
that contain offset (requires rust 1.51)
36+
3337
- move interrupt generation after generic file
3438

3539
- [breaking-change] make `write_with_zero` method `unsafe` because the way it is

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ features = ["full","extra-traits"]
5252

5353
[features]
5454
strict = ["svd-parser/strict"]
55+
const-generic = []

ci/script.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ main() {
5555
return
5656
fi
5757

58-
cargo build --target $TARGET --release
58+
if [ -z ${FEATURES-} ]; then
59+
cargo build --target $TARGET --release
60+
else
61+
cargo build --target $TARGET --release --features $FEATURES
62+
fi
5963

6064
case $TRAVIS_OS_NAME in
6165
linux)

src/generate/register.rs

Lines changed: 93 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,8 @@ pub fn fields(
563563
if can_write {
564564
let new_pc_aw = Ident::new(&(name_pc.clone() + "_AW"), span);
565565
let name_pc_w = Ident::new(&(name_pc.clone() + "_W"), span);
566+
#[cfg(feature = "const-generic")]
567+
let name_pc_cgw = Ident::new(&(name_pc.clone() + "_CGW"), span);
566568

567569
let mut proxy_items = TokenStream::new();
568570
let mut unsafety = unsafety(f.write_constraint.as_ref(), width);
@@ -639,61 +641,108 @@ pub fn fields(
639641
});
640642
}
641643

642-
proxy_items.extend(if field_dim.is_some() {
643-
quote! {
644+
let mut proxy_items_fa = TokenStream::new();
645+
#[cfg(feature = "const-generic")]
646+
let mut proxy_items_cg = TokenStream::new();
647+
if field_dim.is_some() {
648+
proxy_items_fa.extend(quote! {
644649
///Writes raw bits to the field
645650
#inline
646651
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
647652
self.w.bits = (self.w.bits & !(#hexmask << self.offset)) | ((value as #rty & #hexmask) << self.offset);
648653
self.w
649654
}
650-
}
651-
} else if offset != 0 {
652-
let offset = &util::unsuffixed(offset);
653-
quote! {
655+
});
656+
#[cfg(feature="const-generic")]
657+
proxy_items_cg.extend(quote! {
654658
///Writes raw bits to the field
655659
#inline
656660
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
657-
self.w.bits = (self.w.bits & !(#hexmask << #offset)) | ((value as #rty & #hexmask) << #offset);
661+
self.w.bits = (self.w.bits & !(#hexmask << O)) | ((value as #rty & #hexmask) << O);
658662
self.w
659663
}
660-
}
664+
});
661665
} else {
662-
quote! {
663-
///Writes raw bits to the field
664-
#inline
665-
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
666-
self.w.bits = (self.w.bits & !#hexmask) | (value as #rty & #hexmask);
667-
self.w
666+
proxy_items.extend(if offset != 0 {
667+
let offset = &util::unsuffixed(offset);
668+
quote! {
669+
///Writes raw bits to the field
670+
#inline
671+
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
672+
self.w.bits = (self.w.bits & !(#hexmask << #offset)) | ((value as #rty & #hexmask) << #offset);
673+
self.w
674+
}
668675
}
669-
}
670-
});
676+
} else {
677+
quote! {
678+
///Writes raw bits to the field
679+
#inline
680+
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
681+
self.w.bits = (self.w.bits & !#hexmask) | (value as #rty & #hexmask);
682+
self.w
683+
}
684+
}
685+
});
686+
}
671687

672-
let doc;
673-
let offset_entry;
674-
if let Some((_, _, _, _, suffixes_str)) = &field_dim {
675-
doc = format!(
688+
#[cfg(feature = "const-generic")]
689+
let mut cgdoc = String::new();
690+
let doc = if let Some((_, _, _, _, suffixes_str)) = &field_dim {
691+
#[cfg(feature = "const-generic")]
692+
{
693+
cgdoc = format!(
694+
"Fields `{}` const generic writer - {}",
695+
util::replace_suffix(&f.name, suffixes_str),
696+
description
697+
);
698+
}
699+
format!(
676700
"Fields `{}` writer - {}",
677701
util::replace_suffix(&f.name, suffixes_str),
678702
description
679-
);
680-
offset_entry = quote! {offset: usize,};
703+
)
681704
} else {
682-
doc = format!("Field `{}` writer - {}", f.name, description);
683-
offset_entry = quote! {};
684-
}
705+
format!("Field `{}` writer - {}", f.name, description)
706+
};
685707

686-
mod_items.extend(quote! {
687-
#[doc = #doc]
688-
pub struct #name_pc_w<'a> {
689-
w: &'a mut W,
690-
#offset_entry
691-
}
708+
if field_dim.is_some() {
709+
mod_items.extend(quote! {
710+
#[doc = #doc]
711+
pub struct #name_pc_w<'a> {
712+
w: &'a mut W,
713+
offset: usize,
714+
}
692715

693-
impl<'a> #name_pc_w<'a> {
694-
#proxy_items
695-
}
696-
});
716+
impl<'a> #name_pc_w<'a> {
717+
#proxy_items
718+
#proxy_items_fa
719+
}
720+
});
721+
722+
#[cfg(feature = "const-generic")]
723+
mod_items.extend(quote! {
724+
#[doc = #cgdoc]
725+
pub struct #name_pc_cgw<'a, const O: usize> {
726+
w: &'a mut W,
727+
}
728+
729+
impl<'a, const O: usize> #name_pc_cgw<'a, O> {
730+
#proxy_items
731+
#proxy_items_cg
732+
}
733+
});
734+
} else {
735+
mod_items.extend(quote! {
736+
#[doc = #doc]
737+
pub struct #name_pc_w<'a> {
738+
w: &'a mut W,
739+
}
740+
741+
impl<'a> #name_pc_w<'a> {
742+
#proxy_items
743+
}
744+
});
745+
}
697746

698747
if let Some((first, dim, increment, suffixes, suffixes_str)) = &field_dim {
699748
let offset_calc = calculate_offset(*first, *increment, offset);
@@ -716,13 +765,22 @@ pub fn fields(
716765
&suffix,
717766
);
718767
let sub_offset = util::unsuffixed(sub_offset as u64);
768+
#[cfg(not(feature = "const-generic"))]
719769
w_impl_items.extend(quote! {
720770
#[doc = #doc]
721771
#inline
722772
pub fn #name_sc_n(&mut self) -> #name_pc_w {
723773
#name_pc_w { w: self, offset: #sub_offset }
724774
}
725775
});
776+
#[cfg(feature = "const-generic")]
777+
w_impl_items.extend(quote! {
778+
#[doc = #doc]
779+
#inline
780+
pub fn #name_sc_n(&mut self) -> #name_pc_cgw<#sub_offset> {
781+
#name_pc_cgw { w: self }
782+
}
783+
});
726784
}
727785
} else {
728786
let doc = description_with_bits(&description, offset, width);

0 commit comments

Comments
 (0)