Skip to content

Commit fde8568

Browse files
bors[bot]burrbull
andcommitted
Merge #333
333: Refactor fields r=therealprof a=burrbull Non-breaking change. r? @therealprof Co-authored-by: Andrey Zgarbul <[email protected]>
2 parents 36c3ec3 + 95038d9 commit fde8568

File tree

1 file changed

+74
-113
lines changed

1 file changed

+74
-113
lines changed

src/generate/register.rs

Lines changed: 74 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -269,16 +269,27 @@ pub fn fields(
269269
let fs = fields.iter().map(F::from).collect::<Result<Vec<_>>>()?;
270270

271271
// TODO enumeratedValues
272-
if [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite].contains(&access) {
273-
for f in &fs {
274-
if f.access == Some(Access::WriteOnly) || f.access == Some(Access::WriteOnce) {
275-
continue;
276-
}
272+
for f in &fs {
273+
let can_read = [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite].contains(&access) &&
274+
(f.access != Some(Access::WriteOnly)) &&
275+
(f.access != Some(Access::WriteOnce));
276+
let can_write = (access != Access::ReadOnly) && (f.access != Some(Access::ReadOnly));
277+
278+
let bits = &f.bits;
279+
let mask = &f.mask;
280+
let offset = &f.offset;
281+
let fty = &f.ty;
282+
283+
let lookup_results = lookup(
284+
&f.evs,
285+
fields,
286+
parent,
287+
all_registers,
288+
peripheral,
289+
all_peripherals,
290+
)?;
277291

278-
let bits = &f.bits;
279-
let mask = &f.mask;
280-
let offset = &f.offset;
281-
let fty = &f.ty;
292+
if can_read {
282293
let cast = if f.width == 1 {
283294
quote! { != 0 }
284295
} else {
@@ -288,49 +299,9 @@ pub fn fields(
288299
((self.bits >> #offset) & #mask) #cast
289300
};
290301

291-
if let Some((evs, base)) = lookup(
292-
f.evs,
293-
fields,
294-
parent,
295-
all_registers,
296-
peripheral,
297-
all_peripherals,
298-
Usage::Read,
299-
)? {
300-
struct Variant<'a> {
301-
description: &'a str,
302-
pc: Ident,
303-
sc: Ident,
304-
value: u64,
305-
}
306-
302+
if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Read) {
307303
let has_reserved_variant = evs.values.len() != (1 << f.width);
308-
let variants = evs.values
309-
.iter()
310-
// filter out all reserved variants, as we should not
311-
// generate code for them
312-
.filter(|field| field.name.to_lowercase() != "reserved")
313-
.map(|ev| {
314-
let sc =
315-
Ident::from(&*ev.name.to_sanitized_snake_case());
316-
let description = ev.description
317-
.as_ref()
318-
.map(|s| &**s)
319-
.unwrap_or("undocumented");
320-
321-
let value = u64(ev.value.ok_or_else(|| {
322-
format!("EnumeratedValue {} has no <value> field",
323-
ev.name)
324-
})?);
325-
Ok(Variant {
326-
description,
327-
sc,
328-
pc: Ident::from(&*ev.name
329-
.to_sanitized_upper_case()),
330-
value,
331-
})
332-
})
333-
.collect::<Result<Vec<_>>>()?;
304+
let variants = Variant::from_enumerated_values(evs)?;
334305

335306
let pc_r = &f.pc_r;
336307
if let Some(base) = &base {
@@ -380,7 +351,7 @@ pub fn fields(
380351
let mut vars = variants
381352
.iter()
382353
.map(|v| {
383-
let desc = util::escape_brackets(&v.description);
354+
let desc = util::escape_brackets(&v.doc);
384355
let pc = &v.pc;
385356
quote! {
386357
#[doc = #desc]
@@ -557,39 +528,19 @@ pub fn fields(
557528
});
558529
}
559530
}
560-
}
561-
562-
if access != Access::ReadOnly {
563-
for f in &fs {
564-
if f.access == Some(Access::ReadOnly) {
565-
continue;
566-
}
567531

532+
if can_write {
568533
let mut proxy_items = vec![];
569534

570535
let mut unsafety = unsafety(f.write_constraint, f.width);
571-
let bits = &f.bits;
572-
let fty = &f.ty;
573-
let offset = &f.offset;
574-
let mask = &f.mask;
575536
let width = f.width;
576537

577-
if let Some((evs, base)) = lookup(
578-
&f.evs,
579-
fields,
580-
parent,
581-
all_registers,
582-
peripheral,
583-
all_peripherals,
584-
Usage::Write,
585-
)? {
586-
struct Variant {
587-
doc: String,
588-
pc: Ident,
589-
sc: Ident,
590-
value: u64,
591-
}
538+
if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Write) {
539+
let variants = Variant::from_enumerated_values(evs)?;
592540

541+
if variants.len() == 1 << f.width {
542+
unsafety = None;
543+
}
593544
let pc_w = &f.pc_w;
594545
let pc_w_doc = format!("Values that can be written to the field `{}`", f.name);
595546

@@ -637,37 +588,6 @@ pub fn fields(
637588
}
638589
});
639590

640-
let variants = evs.values
641-
.iter()
642-
// filter out all reserved variants, as we should not
643-
// generate code for them
644-
.filter(|field| field.name.to_lowercase() != "reserved")
645-
.map(
646-
|ev| {
647-
let value = u64(ev.value.ok_or_else(|| {
648-
format!("EnumeratedValue {} has no `<value>` field",
649-
ev.name)})?);
650-
651-
Ok(Variant {
652-
doc: ev.description
653-
.clone()
654-
.unwrap_or_else(|| {
655-
format!("`{:b}`", value)
656-
}),
657-
pc: Ident::from(&*ev.name
658-
.to_sanitized_upper_case()),
659-
sc: Ident::from(&*ev.name
660-
.to_sanitized_snake_case()),
661-
value,
662-
})
663-
},
664-
)
665-
.collect::<Result<Vec<_>>>()?;
666-
667-
if variants.len() == 1 << f.width {
668-
unsafety = None;
669-
}
670-
671591
if base.is_none() {
672592
let variants_pc = variants.iter().map(|v| &v.pc);
673593
let variants_doc = variants.iter().map(|v| util::escape_brackets(&v.doc).to_owned());
@@ -808,6 +728,44 @@ fn unsafety(write_constraint: Option<&WriteConstraint>, width: u32) -> Option<Id
808728
}
809729
}
810730

731+
struct Variant {
732+
doc: String,
733+
pc: Ident,
734+
sc: Ident,
735+
value: u64,
736+
}
737+
738+
impl Variant {
739+
fn from_enumerated_values(evs: &EnumeratedValues) -> Result<Vec<Self>> {
740+
evs.values
741+
.iter()
742+
// filter out all reserved variants, as we should not
743+
// generate code for them
744+
.filter(|field| field.name.to_lowercase() != "reserved")
745+
.map(
746+
|ev| {
747+
let value = u64(ev.value.ok_or_else(|| {
748+
format!("EnumeratedValue {} has no `<value>` field",
749+
ev.name)})?);
750+
751+
Ok(Variant {
752+
doc: ev.description
753+
.clone()
754+
.unwrap_or_else(|| {
755+
format!("`{:b}`", value)
756+
}),
757+
pc: Ident::from(&*ev.name
758+
.to_sanitized_upper_case()),
759+
sc: Ident::from(&*ev.name
760+
.to_sanitized_snake_case()),
761+
value,
762+
})
763+
},
764+
)
765+
.collect::<Result<Vec<_>>>()
766+
}
767+
}
768+
811769
#[derive(Clone, Debug)]
812770
pub struct Base<'a> {
813771
pub peripheral: Option<&'a str>,
@@ -822,8 +780,7 @@ fn lookup<'a>(
822780
all_registers: &'a [&'a Register],
823781
peripheral: &'a Peripheral,
824782
all_peripherals: &'a [Peripheral],
825-
usage: Usage,
826-
) -> Result<Option<(&'a EnumeratedValues, Option<Base<'a>>)>> {
783+
) -> Result<Vec<(&'a EnumeratedValues, Option<Base<'a>>)>> {
827784
let evs = evs.iter()
828785
.map(|evs| {
829786
if let Some(base) = &evs.derived_from {
@@ -864,13 +821,17 @@ fn lookup<'a>(
864821
})
865822
.collect::<Result<Vec<_>>>()?;
866823

824+
Ok(evs)
825+
}
826+
827+
fn lookup_filter<'a> (evs: &Vec<(&'a EnumeratedValues, Option<Base<'a>>)>, usage: Usage) -> Option<(&'a EnumeratedValues, Option<Base<'a>>)> {
867828
for (evs, base) in evs.iter() {
868829
if evs.usage == Some(usage) {
869-
return Ok(Some((*evs, base.clone())));
830+
return Some((*evs, base.clone()));
870831
}
871832
}
872833

873-
Ok(evs.first().cloned())
834+
evs.first().cloned()
874835
}
875836

876837
fn lookup_in_fields<'f>(

0 commit comments

Comments
 (0)