Skip to content

Commit f574025

Browse files
committed
check bitmask on _add
1 parent c605222 commit f574025

File tree

7 files changed

+54
-41
lines changed

7 files changed

+54
-41
lines changed

.github/workflows/ci.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,4 @@ jobs:
6363
python -m pip install --upgrade pip
6464
pip install .
6565
- name: Check
66-
run: bash tools/check_${{ matrix.target }}.sh
66+
run: RUST_LOG=warn bash tools/check_${{ matrix.target }}.sh

CHANGELOG-rust.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ This changelog tracks the Rust `svdtools` project. See
55

66
## [Unreleased]
77

8+
* Update `svd-rs` to 0.4.10
9+
810
## [v0.4.4] 2025-02-08
911

1012
* Add `prefix` and `suffix` as opposite to `strip` and `strip_end`
@@ -30,6 +32,7 @@ This changelog tracks the Rust `svdtools` project. See
3032
## [v0.3.21] 2024-12-31
3133

3234
* `_derive` field
35+
* WARN when add field intersecting with other fields
3336

3437
## [v0.3.20] 2024-11-14
3538

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ rust-version = "1.70"
2929
clap = { version = "4.5", features = ["derive", "cargo", "color"] }
3030
serde = { version = "1.0", features = ["derive"] }
3131
quick-xml = { version = "0.36", features = ["serialize"] }
32-
svd-rs = { version = "0.14.9", features = ["serde", "derive-from"] }
33-
svd-parser = { version = "0.14.7", features = ["expand"] }
34-
svd-encoder = "0.14.5"
32+
svd-rs = { version = "0.14.10", features = ["serde", "derive-from"] }
33+
svd-parser = { version = "0.14.8", features = ["expand"] }
34+
svd-encoder = "0.14.6"
3535
# serde_yaml 0.9.x looks broken
3636
serde_yaml = "0.8.26"
3737
serde_json = { version = "1.0", features = ["preserve_order"] }

src/html/html_cli.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,7 @@ fn parse_register(
283283

284284
let foffset = ftag.bit_offset();
285285
let fwidth = ftag.bit_width();
286-
let bit_mask = (u64::MAX >> (u64::BITS - fwidth)) << foffset;
287-
filling |= bit_mask;
286+
filling |= ftag.bitmask();
288287

289288
let faccs = ftag.access.map(Access::as_str).unwrap_or(raccs);
290289
let enums = ftag.enumerated_values.first();

src/patch/device.rs

+9
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,15 @@ impl DeviceExt for Device {
183183
}
184184

185185
fn delete_peripheral(&mut self, pspec: &str) -> PatchResult {
186+
if self
187+
.peripherals
188+
.iter()
189+
.filter(|p| matchname(&p.name, pspec))
190+
.count()
191+
== 0
192+
{
193+
log::info!("Trying to delete absent `{}` peripheral", pspec);
194+
}
186195
self.peripherals.retain(|p| !(matchname(&p.name, pspec)));
187196
Ok(())
188197
}

src/patch/peripheral.rs

+22-14
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use svd_parser::svd::{
99
use yaml_rust::{yaml::Hash, Yaml};
1010

1111
use super::iterators::{MatchIter, Matched};
12-
use super::register::{RegisterExt, RegisterInfoExt};
12+
use super::register::RegisterExt;
1313
use super::yaml_ext::{AsType, GetVal, ToYaml};
1414
use super::{
1515
check_offsets, common_description, make_dim_element, matchname, matchsubspec,
@@ -172,8 +172,22 @@ pub(crate) trait RegisterBlockExt: Name {
172172
}
173173

174174
/// Delete registers matched by rspec inside ptag
175-
fn delete_register(&mut self, rspec: &str) -> PatchResult {
175+
fn delete_register(&mut self, rspec: &str, bpath: &BlockPath) -> PatchResult {
176176
if let Some(children) = self.children_mut() {
177+
if children
178+
.iter()
179+
.filter(
180+
|rc| matches!(rc, RegisterCluster::Register(r) if matchname(&r.name, rspec)),
181+
)
182+
.count()
183+
== 0
184+
{
185+
log::info!(
186+
"Trying to delete absent `{}` register from {}",
187+
rspec,
188+
bpath
189+
);
190+
}
177191
children.retain(
178192
|rc| !matches!(rc, RegisterCluster::Register(r) if matchname(&r.name, rspec)),
179193
);
@@ -1043,7 +1057,7 @@ impl PeripheralExt for Peripheral {
10431057
}
10441058
Yaml::Hash(deletions) => {
10451059
for rspec in deletions.str_vec_iter("_registers")? {
1046-
self.delete_register(rspec)
1060+
self.delete_register(rspec, &ppath)
10471061
.with_context(|| format!("Deleting registers matched to `{rspec}`"))?;
10481062
}
10491063
for cspec in deletions.str_vec_iter("_clusters")? {
@@ -1344,6 +1358,8 @@ impl InterruptExt for Peripheral {
13441358

13451359
impl ClusterExt for Cluster {
13461360
fn pre_process(&mut self, cmod: &Hash, parent: &BlockPath, _config: &Config) -> PatchResult {
1361+
let cpath = parent.new_cluster(&self.name);
1362+
13471363
// Handle deletions
13481364
if let Some(deletions) = cmod.get_yaml("_delete") {
13491365
match deletions {
@@ -1362,7 +1378,7 @@ impl ClusterExt for Cluster {
13621378
}
13631379
Yaml::Hash(deletions) => {
13641380
for rspec in deletions.str_vec_iter("_registers")? {
1365-
self.delete_register(rspec)
1381+
self.delete_register(rspec, &cpath)
13661382
.with_context(|| format!("Deleting registers matched to `{rspec}`"))?;
13671383
}
13681384
for cspec in deletions.str_vec_iter("_clusters")? {
@@ -1386,8 +1402,6 @@ impl ClusterExt for Cluster {
13861402
}
13871403
}
13881404

1389-
let cpath = parent.new_cluster(&self.name);
1390-
13911405
// Handle any copied peripherals
13921406
for (rname, rcopy) in cmod.hash_iter("_copy") {
13931407
let rname = rname.str()?;
@@ -1643,10 +1657,7 @@ fn collect_in_array(
16431657
if !check_offsets(&offsets, dim_increment) {
16441658
return Err(anyhow!("{path}: registers cannot be collected into {rspec} array. Different addressOffset increments"));
16451659
}
1646-
let bitmasks = registers
1647-
.iter()
1648-
.map(RegisterInfo::get_bitmask)
1649-
.collect::<Vec<_>>();
1660+
let bitmasks = registers.iter().map(|r| r.bitmask()).collect::<Vec<_>>();
16501661
if !bitmasks.iter().all(|&m| m == bitmasks[0]) {
16511662
return Err(anyhow!(
16521663
"{path}: registers cannot be collected into {rspec} array. Different bit masks"
@@ -1769,10 +1780,7 @@ fn collect_in_cluster(
17691780
"Some of `{rspec}` registers are arrays and some are not"
17701781
));
17711782
}
1772-
let bitmasks = registers
1773-
.iter()
1774-
.map(|r| RegisterInfo::get_bitmask(r))
1775-
.collect::<Vec<_>>();
1783+
let bitmasks = registers.iter().map(|r| r.bitmask()).collect::<Vec<_>>();
17761784
let new_dim_index = registers
17771785
.iter()
17781786
.map(|r| {

src/patch/register.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use itertools::Itertools;
55
use svd_parser::expand::{BlockPath, RegisterPath};
66
use svd_parser::svd::{
77
Access, BitRange, DimElement, EnumeratedValues, Field, FieldInfo, ModifiedWriteValues,
8-
ReadAction, Register, RegisterInfo, Usage, WriteConstraint, WriteConstraintRange,
8+
ReadAction, Register, Usage, WriteConstraint, WriteConstraintRange,
99
};
1010
use yaml_rust::{yaml::Hash, Yaml};
1111

@@ -21,23 +21,6 @@ use super::{make_derived_enumerated_values, make_ev_array, make_ev_name, make_fi
2121

2222
pub type FieldMatchIterMut<'a, 'b> = MatchIter<'b, std::slice::IterMut<'a, Field>>;
2323

24-
pub(crate) trait RegisterInfoExt {
25-
/// Calculate filling of register
26-
fn get_bitmask(&self) -> u64;
27-
}
28-
29-
impl RegisterInfoExt for RegisterInfo {
30-
fn get_bitmask(&self) -> u64 {
31-
let mut mask = 0x0;
32-
if let Some(fields) = self.fields.as_ref() {
33-
for ftag in fields {
34-
mask |= (!0 >> (64 - ftag.bit_range.width)) << ftag.bit_range.offset;
35-
}
36-
}
37-
mask
38-
}
39-
}
40-
4124
/// Collecting methods for processing register contents
4225
pub trait RegisterExt {
4326
const KEYWORDS: &'static [&'static str] = &[
@@ -70,7 +53,7 @@ pub trait RegisterExt {
7053
fn add_field(&mut self, fname: &str, fadd: &Hash, rpath: &RegisterPath) -> PatchResult;
7154

7255
/// Delete fields matched by fspec inside rtag
73-
fn delete_field(&mut self, fspec: &str) -> PatchResult;
56+
fn delete_field(&mut self, fspec: &str, rpath: &RegisterPath) -> PatchResult;
7457

7558
/// Clear field from rname and mark it as derivedFrom rderive.
7659
fn derive_field(&mut self, fname: &str, fderive: &Yaml, rpath: &RegisterPath) -> PatchResult;
@@ -166,7 +149,7 @@ impl RegisterExt for Register {
166149

167150
// Handle deletions
168151
for fspec in rmod.str_vec_iter("_delete")? {
169-
self.delete_field(fspec)
152+
self.delete_field(fspec, &rpath)
170153
.with_context(|| format!("Deleting fields matched to `{fspec}`"))?;
171154
}
172155

@@ -380,12 +363,23 @@ impl RegisterExt for Register {
380363
} else {
381364
fnew.single()
382365
};
366+
let exist_bits = self.bitmask();
367+
if exist_bits & fnew.bitmask() != 0 {
368+
log::warn!("field {fname} conflicts with other fields in register {rpath}");
369+
}
383370
self.fields.get_or_insert_with(Default::default).push(fnew);
384371
Ok(())
385372
}
386373

387-
fn delete_field(&mut self, fspec: &str) -> PatchResult {
374+
fn delete_field(&mut self, fspec: &str, rpath: &RegisterPath) -> PatchResult {
388375
if let Some(fields) = self.fields.as_mut() {
376+
if fields.iter().filter(|f| matchname(&f.name, fspec)).count() == 0 {
377+
log::info!(
378+
"Trying to delete absent `{}` field from register {}",
379+
fspec,
380+
rpath
381+
);
382+
}
389383
fields.retain(|f| !(matchname(&f.name, fspec)));
390384
}
391385
Ok(())

0 commit comments

Comments
 (0)