Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

array-proxy for disjoint arrays #749

Merged
merged 1 commit into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

- Use `ArrayProxy` for memory disjoined register arrays
- Use `const fn` where allowed

## [v0.30.1] - 2023-10-01
Expand Down
1 change: 1 addition & 0 deletions src/generate/array_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/// ensure that the memory really is backed by appropriate content.
///
/// Typically, this is used for accessing hardware registers.
#[derive(Debug)]
pub struct ArrayProxy<T, const COUNT: usize, const STRIDE: usize> {
/// As well as providing a PhantomData, this field is non-public, and
/// therefore ensures that code outside of this module can never create
Expand Down
4 changes: 2 additions & 2 deletions src/generate/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,12 @@ impl<FI> BitReader<FI> {
}
/// Returns `true` if the bit is clear (0).
#[inline(always)]
pub fn bit_is_clear(&self) -> bool {
pub const fn bit_is_clear(&self) -> bool {
!self.bit()
}
/// Returns `true` if the bit is set (1).
#[inline(always)]
pub fn bit_is_set(&self) -> bool {
pub const fn bit_is_set(&self) -> bool {
self.bit()
}
}
Expand Down
46 changes: 33 additions & 13 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ struct Region {
}

impl Region {
fn size(&self) -> u32 {
self.end - self.offset
}
fn shortest_ident(&self) -> Option<String> {
let mut idents: Vec<_> = self
.rbfs
Expand Down Expand Up @@ -490,12 +493,17 @@ impl FieldRegions {
.binary_search_by_key(&new_region.offset, |r| r.offset);
match idx {
Ok(idx) => {
bail!(
"we shouldn't exist in the vec, but are at idx {} {:#?}\n{:#?}",
idx,
new_region,
self.regions
);
if new_region.size() == 0 {
// add ArrayProxy
self.regions.insert(idx, new_region);
} else {
bail!(
"we shouldn't exist in the vec, but are at idx {} {:#?}\n{:#?}",
idx,
new_region,
self.regions
);
}
}
Err(idx) => self.regions.insert(idx, new_region),
};
Expand Down Expand Up @@ -1185,6 +1193,8 @@ fn expand_register(
Register::Array(info, array_info) => {
let sequential_addresses = (array_info.dim == 1)
|| (register_size == array_info.dim_increment * BITS_PER_BYTE);
let disjoint_sequential_addresses = (array_info.dim == 1)
|| (register_size <= array_info.dim_increment * BITS_PER_BYTE);

let convert_list = match config.keep_list {
true => match &array_info.dim_name {
Expand All @@ -1208,20 +1218,22 @@ fn expand_register(
} else {
"".into()
};
let array_convertible = match derive_info {
let ac = match derive_info {
DeriveInfo::Implicit(_) => {
ty_name = util::replace_suffix(&info_name, &index);
sequential_addresses && convert_list && sequential_indexes_from0
convert_list && sequential_indexes_from0
}
DeriveInfo::Explicit(_) => {
ty_name = util::replace_suffix(&info_name, &index);
sequential_addresses && convert_list && sequential_indexes_from0
convert_list && sequential_indexes_from0
}
_ => sequential_addresses && convert_list,
_ => convert_list,
};
let array_convertible = ac && sequential_addresses;
let array_proxy_convertible = ac && disjoint_sequential_addresses;
let ty = name_to_ty(&ty_name);

if array_convertible {
if array_convertible || (array_proxy_convertible && config.const_generic) {
let accessors = if sequential_indexes_from0 {
Vec::new()
} else {
Expand All @@ -1247,14 +1259,22 @@ fn expand_register(
}
accessors
};
let array_ty = new_syn_array(ty, array_info.dim);
let array_ty = if array_convertible {
new_syn_array(ty, array_info.dim)
} else {
array_proxy_type(ty, array_info)
};
let syn_field =
new_syn_field(ty_name.to_snake_case_ident(Span::call_site()), array_ty);
register_expanded.push(RegisterBlockField {
syn_field,
description,
offset: info.address_offset,
size: register_size * array_info.dim,
size: if array_convertible {
register_size * array_info.dim
} else {
0
},
accessors,
});
} else {
Expand Down
Loading