Skip to content

Commit f9e8a4c

Browse files
committed
support non-sequential & non-digit field arrays
1 parent c28da92 commit f9e8a4c

File tree

1 file changed

+41
-65
lines changed

1 file changed

+41
-65
lines changed

src/generate/register.rs

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ pub fn fields(
345345
let fpath = fpath.unwrap_or_else(|| rpath.new_field(&f.name));
346346
// TODO(AJM) - do we need to do anything with this range type?
347347
let BitRange { offset, width, .. } = f.bit_range;
348+
349+
if f.is_single() && f.name.contains("%s") {
350+
return Err(anyhow!("incorrect field {}", f.name));
351+
}
352+
348353
let name = util::replace_suffix(&f.name, "");
349354
let name_snake_case = name.to_snake_case_ident(span);
350355
let name_constant_case = name.to_sanitized_constant_case();
@@ -384,36 +389,15 @@ pub fn fields(
384389

385390
let mut evs_r = None;
386391

387-
// Reads dim information from svd field. If it has dim index, the field is treated as an
388-
// array; or it should be treated as a single register field.
389-
let field_dim = match &f {
390-
Field::Array(_, de) => {
391-
let first = if let Some(dim_index) = &de.dim_index {
392-
if let Ok(first) = dim_index[0].parse::<u32>() {
393-
let sequential_indexes = dim_index
394-
.iter()
395-
.map(|element| element.parse::<u32>())
396-
.eq((first..de.dim + first).map(Ok));
397-
if !sequential_indexes {
398-
return Err(anyhow!("unsupported array indexes in {}", f.name));
399-
}
400-
first
401-
} else {
402-
0
403-
}
404-
} else {
405-
0
406-
};
392+
let brief_suffix = if let Field::Array(_, de) = &f {
393+
if let Some(range) = de.indexes_as_range() {
394+
format!("[{}-{}]", *range.start(), *range.end())
395+
} else {
407396
let suffixes: Vec<_> = de.indexes().collect();
408-
let suffixes_str = format!("({first}-{})", first + de.dim - 1);
409-
Some((first, de.dim, de.dim_increment, suffixes, suffixes_str))
410-
}
411-
Field::Single(_) => {
412-
if f.name.contains("%s") {
413-
return Err(anyhow!("incorrect field {}", f.name));
414-
}
415-
None
397+
format!("[{}]", suffixes.join(","))
416398
}
399+
} else {
400+
String::new()
417401
};
418402

419403
// If this field can be read, generate read proxy structure and value structure.
@@ -440,14 +424,7 @@ pub fn fields(
440424

441425
// get a brief description for this field
442426
// the suffix string from field name is removed in brief description.
443-
let field_reader_brief = if let Some((_, _, _, _, suffixes_str)) = &field_dim {
444-
format!(
445-
"Fields `{}` reader - {description}",
446-
util::replace_suffix(&f.name, suffixes_str),
447-
)
448-
} else {
449-
format!("Field `{}` reader - {description}", f.name)
450-
};
427+
let field_reader_brief = format!("Field `{name}{brief_suffix}` reader - {description}");
451428

452429
// get the type of value structure. It can be generated from either name field
453430
// in enumeratedValues if it's an enumeration, or from field name directly if it's not.
@@ -644,19 +621,24 @@ pub fn fields(
644621
}
645622
}
646623

647-
if let Some((first, dim, increment, suffixes, suffixes_str)) = &field_dim {
648-
let offset_calc = calculate_offset(*first, *increment, offset, true);
649-
let value = quote! { ((self.bits >> #offset_calc) & #hexmask) #cast };
650-
let doc = &util::replace_suffix(&description, suffixes_str);
651-
r_impl_items.extend(quote! {
652-
#[doc = #doc]
653-
#inline
654-
pub unsafe fn #name_snake_case(&self, n: u8) -> #reader_ty {
655-
#reader_ty::new ( #value )
656-
}
657-
});
658-
for (i, suffix) in (0..*dim).zip(suffixes.iter()) {
659-
let sub_offset = offset + (i as u64) * (*increment as u64);
624+
if let Field::Array(_, de) = &f {
625+
let increment = de.dim_increment;
626+
let doc = &util::replace_suffix(&description, &brief_suffix);
627+
if let Some(range) = de.indexes_as_range() {
628+
let first = *range.start();
629+
630+
let offset_calc = calculate_offset(first, increment, offset, true);
631+
let value = quote! { ((self.bits >> #offset_calc) & #hexmask) #cast };
632+
r_impl_items.extend(quote! {
633+
#[doc = #doc]
634+
#inline
635+
pub unsafe fn #name_snake_case(&self, n: u8) -> #reader_ty {
636+
#reader_ty::new ( #value )
637+
}
638+
});
639+
}
640+
for (i, suffix) in de.indexes().enumerate() {
641+
let sub_offset = offset + (i as u64) * (increment as u64);
660642
let value = if sub_offset != 0 {
661643
let sub_offset = &util::unsuffixed(sub_offset);
662644
quote! {
@@ -671,11 +653,11 @@ pub fn fields(
671653
self.bits
672654
}
673655
};
674-
let name_snake_case_n = util::replace_suffix(&f.name, suffix)
656+
let name_snake_case_n = util::replace_suffix(&f.name, &suffix)
675657
.to_snake_case_ident(Span::call_site());
676658
let doc = util::replace_suffix(
677659
&description_with_bits(description_raw, sub_offset, width),
678-
suffix,
660+
&suffix,
679661
);
680662
r_impl_items.extend(quote! {
681663
#[doc = #doc]
@@ -714,14 +696,7 @@ pub fn fields(
714696
.or(register.modified_write_values)
715697
.unwrap_or_default();
716698
// gets a brief of write proxy
717-
let field_writer_brief = if let Some((_, _, _, _, suffixes_str)) = &field_dim {
718-
format!(
719-
"Fields `{}` writer - {description}",
720-
util::replace_suffix(&f.name, suffixes_str),
721-
)
722-
} else {
723-
format!("Field `{}` writer - {description}", f.name)
724-
};
699+
let field_writer_brief = format!("Field `{name}{brief_suffix}` writer - {description}");
725700

726701
let value_write_ty =
727702
if let Some((evs, _)) = lookup_filter(&lookup_results, Usage::Write) {
@@ -889,8 +864,9 @@ pub fn fields(
889864
}
890865
}
891866

892-
if let Some((_, dim, increment, suffixes, suffixes_str)) = &field_dim {
893-
let doc = &util::replace_suffix(&description, suffixes_str);
867+
if let Field::Array(_, de) = &f {
868+
let increment = de.dim_increment;
869+
let doc = &util::replace_suffix(&description, &brief_suffix);
894870
w_impl_items.extend(quote! {
895871
#[doc = #doc]
896872
#inline
@@ -899,13 +875,13 @@ pub fn fields(
899875
}
900876
});
901877

902-
for (i, suffix) in (0..*dim).zip(suffixes.iter()) {
903-
let sub_offset = offset + (i as u64) * (*increment as u64);
904-
let name_snake_case_n = &util::replace_suffix(&f.name, suffix)
878+
for (i, suffix) in de.indexes().enumerate() {
879+
let sub_offset = offset + (i as u64) * (increment as u64);
880+
let name_snake_case_n = &util::replace_suffix(&f.name, &suffix)
905881
.to_snake_case_ident(Span::call_site());
906882
let doc = util::replace_suffix(
907883
&description_with_bits(description_raw, sub_offset, width),
908-
suffix,
884+
&suffix,
909885
);
910886
let sub_offset = util::unsuffixed(sub_offset as u64);
911887

0 commit comments

Comments
 (0)