Skip to content

Commit c021fbb

Browse files
committed
add variant to reader
1 parent ce0a47c commit c021fbb

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

src/generate/generic.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ pub fn render() -> Result<Vec<Tokens>> {
7474
}
7575
});
7676

77+
generic_items.push(quote! {
78+
///Used if enumerated values cover not the whole range
79+
#[derive(Clone,Copy,PartialEq)]
80+
pub enum Variant<U, T> {
81+
///Expected variant
82+
Val(T),
83+
///Raw bits
84+
Res(U),
85+
}
86+
});
87+
7788
code.push(quote! {
7889
#[allow(unused_imports)]
7990
use generic::*;

src/generate/register.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ pub fn fields(
277277
let pc_r = Ident::from(&*format!("{}R", pc));
278278
let _pc_r = Ident::from(&*format!("{}_R", pc));
279279
let pc_w = Ident::from(&*format!("{}W", pc));
280-
let _pc_w = Ident::from(&*format!("_{}W", pc));
280+
let _pc_w = Ident::from(&*format!("{}_W", pc));
281281
let _sc = Ident::from(&*format!("_{}", sc));
282282
let bits = if width == 1 {
283283
Ident::from("bit")
@@ -359,8 +359,6 @@ pub fn fields(
359359
let _pc_r = &f._pc_r;
360360

361361
if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Read) {
362-
let variants = Variant::from_enumerated_values(evs)?;
363-
364362
if let Some(base) = &base {
365363
let pc = base.field.to_sanitized_upper_case();
366364
let base_pc_r = Ident::from(&*format!("{}_R", pc));
@@ -402,7 +400,9 @@ pub fn fields(
402400
}
403401
});
404402

403+
let variants = Variant::from_enumerated_values(evs)?;
405404
if base.is_none() {
405+
let has_reserved_variant = evs.values.len() != (1 << f.width);
406406
let desc = format!("Possible values of the field `{}`", f.name,);
407407

408408
let vars = variants
@@ -447,6 +447,53 @@ pub fn fields(
447447
}
448448
});
449449

450+
let mut arms = variants
451+
.iter()
452+
.map(|v| {
453+
let i = util::unsuffixed_or_bool(v.value, f.width);
454+
let pc = &v.pc;
455+
456+
if has_reserved_variant {
457+
quote! { #i => Val(#pc_r::#pc) }
458+
} else {
459+
quote! { #i => #pc_r::#pc }
460+
}
461+
})
462+
.collect::<Vec<_>>();
463+
464+
if has_reserved_variant {
465+
arms.push(quote! {
466+
i => Res(i)
467+
});
468+
} else if 1 << f.width.to_ty_width()? != variants.len() {
469+
arms.push(quote! {
470+
_ => unreachable!()
471+
});
472+
}
473+
474+
if has_reserved_variant {
475+
enum_items.push(quote! {
476+
///Enumerated values
477+
#[inline(always)]
478+
pub fn variant(&self) -> crate::Variant<#fty, #pc_r> {
479+
use crate::Variant::*;
480+
match self.bits() {
481+
#(#arms),*
482+
}
483+
}
484+
});
485+
} else {
486+
enum_items.push(quote! {
487+
///Enumerated values
488+
#[inline(always)]
489+
pub fn variant(&self) -> #pc_r {
490+
match self.bits() {
491+
#(#arms),*
492+
}
493+
}
494+
});
495+
}
496+
450497
for v in &variants {
451498
let pc = &v.pc;
452499
let sc = &v.sc;
@@ -578,11 +625,9 @@ pub fn fields(
578625
});
579626

580627
mod_items.push(quote! {
581-
impl #pc_w {
582-
#[allow(missing_docs)]
583-
#[doc(hidden)]
628+
impl crate::ToBits<#fty> for #pc_w {
584629
#[inline(always)]
585-
pub fn _bits(&self) -> #fty {
630+
fn _bits(&self) -> #fty {
586631
match *self {
587632
#(#arms),*
588633
}
@@ -595,6 +640,7 @@ pub fn fields(
595640
///Writes `variant` to the field
596641
#[inline(always)]
597642
pub fn variant(self, variant: #pc_w) -> &'a mut W {
643+
use crate::ToBits;
598644
#unsafety {
599645
self.#bits(variant._bits())
600646
}

0 commit comments

Comments
 (0)