Skip to content

Commit 004a68f

Browse files
committed
Refactor some more and get rid of intermediate structure
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
1 parent 3262d71 commit 004a68f

File tree

1 file changed

+55
-109
lines changed

1 file changed

+55
-109
lines changed

src/generate/register.rs

Lines changed: 55 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -223,133 +223,81 @@ pub fn fields(
223223
r_impl_items: &mut Vec<TokenStream>,
224224
w_impl_items: &mut Vec<TokenStream>,
225225
) -> Result<()> {
226-
struct F<'a> {
227-
_pc_w: Ident,
228-
_sc: Ident,
229-
access: Option<Access>,
230-
description: String,
231-
description_with_bits: String,
232-
evs: &'a [EnumeratedValues],
233-
mask: u64,
234-
name: &'a str,
235-
offset: u64,
236-
pc_r: Ident,
237-
_pc_r: Ident,
238-
pc_w: Ident,
239-
sc: Ident,
240-
bits: Ident,
241-
ty: Ident,
242-
width: u32,
243-
write_constraint: Option<&'a WriteConstraint>,
244-
}
245-
246-
impl<'a> F<'a> {
247-
fn from(f: &'a Field) -> Result<Self> {
248-
// TODO(AJM) - do we need to do anything with this range type?
249-
let BitRange { offset, width, .. } = f.bit_range;
250-
let sc = f.name.to_sanitized_snake_case();
251-
let pc = f.name.to_sanitized_upper_case();
252-
let span = Span::call_site();
253-
let pc_r = Ident::new(&format!("{}_A", pc), span);
254-
let _pc_r = Ident::new(&format!("{}_R", pc), span);
255-
let pc_w = Ident::new(&format!("{}_AW", pc), span);
256-
let _pc_w = Ident::new(&format!("{}_W", pc), span);
257-
let _sc = Ident::new(&format!("_{}", sc), span);
258-
let bits = Ident::new(if width == 1 { "bit" } else { "bits" }, span);
259-
let mut description_with_bits = if width == 1 {
260-
format!("Bit {}", offset)
261-
} else {
262-
format!("Bits {}:{}", offset, offset + width - 1)
263-
};
264-
if let Some(d) = &f.description {
265-
description_with_bits.push_str(" - ");
266-
description_with_bits.push_str(&util::respace(&util::escape_brackets(d)));
267-
}
268-
let description = if let Some(d) = &f.description {
269-
util::respace(&util::escape_brackets(d))
270-
} else {
271-
"".to_owned()
272-
};
273-
274-
Ok(F {
275-
_pc_w,
276-
_sc,
277-
description,
278-
description_with_bits,
279-
pc_r,
280-
_pc_r,
281-
pc_w,
282-
bits,
283-
width,
284-
access: f.access,
285-
evs: &f.enumerated_values,
286-
sc: Ident::new(&sc, span),
287-
mask: 1u64.wrapping_neg() >> (64 - width),
288-
name: &f.name,
289-
offset: u64::from(offset),
290-
ty: width.to_ty()?,
291-
write_constraint: f.write_constraint.as_ref(),
292-
})
293-
}
294-
}
295-
296226
// TODO enumeratedValues
297-
for f in fields.iter().map(F::from) {
298-
let f = f?;
227+
for f in fields.into_iter() {
228+
// TODO(AJM) - do we need to do anything with this range type?
229+
let BitRange { offset, width, .. } = f.bit_range;
230+
let span = Span::call_site();
231+
let sc = Ident::new(&f.name.to_sanitized_snake_case(), span);
232+
let pc = f.name.to_sanitized_upper_case();
233+
let bits = Ident::new(if width == 1 { "bit" } else { "bits" }, span);
234+
let mut description_with_bits = if width == 1 {
235+
format!("Bit {}", offset)
236+
} else {
237+
format!("Bits {}:{}", offset, offset + width - 1)
238+
};
239+
let description = if let Some(d) = &f.description {
240+
util::respace(&util::escape_brackets(d))
241+
} else {
242+
"".to_owned()
243+
};
244+
if !description.is_empty() {
245+
description_with_bits.push_str(" - ");
246+
description_with_bits.push_str(&description);
247+
}
299248

300249
let can_read = [Access::ReadOnly, Access::ReadWriteOnce, Access::ReadWrite]
301250
.contains(&access)
302251
&& (f.access != Some(Access::WriteOnly))
303252
&& (f.access != Some(Access::WriteOnce));
304253
let can_write = (access != Access::ReadOnly) && (f.access != Some(Access::ReadOnly));
305254

306-
let bits = &f.bits;
307-
let mask = &util::hex(f.mask);
308-
let offset = f.offset;
309-
let rv = reset_value.map(|rv| (rv >> offset) & f.mask);
310-
let fty = &f.ty;
255+
let mask = 1u64.wrapping_neg() >> (64 - width);
256+
let hexmask = &util::hex(mask);
257+
let offset = u64::from(offset);
258+
let rv = reset_value.map(|rv| (rv >> offset) & mask);
259+
let fty = width.to_ty()?;
260+
let evs = &f.enumerated_values;
311261

312262
let lookup_results = lookup(
313-
&f.evs,
263+
evs,
314264
fields,
315265
parent,
316266
all_registers,
317267
peripheral,
318268
all_peripherals,
319269
)?;
320270

321-
let pc_r = &f.pc_r;
322-
let mut pc_w = &f.pc_r;
271+
// Reader and writer use one common `Enum_A` unless a fields have two `enumeratedValues`,
272+
// then we have one for read-only `Enum_A` and another for write-only `Enum_AW`
273+
let pc_r = Ident::new(&(pc.clone() + "_A"), span);
274+
let mut pc_w = &pc_r;
323275

324276
let mut base_pc_w = None;
325277
let mut evs_r = None;
326278

327-
let _pc_r = &f._pc_r;
328-
let _pc_w = &f._pc_w;
329-
let description = &f.description;
330-
let description_with_bits = &f.description_with_bits;
331-
332279
if can_read {
333-
let cast = if f.width == 1 {
280+
let _pc_r = Ident::new(&(pc.clone() + "_R"), span);
281+
282+
let cast = if width == 1 {
334283
quote! { != 0 }
335284
} else {
336285
quote! { as #fty }
337286
};
338287
let value = if offset != 0 {
339288
let offset = &util::unsuffixed(offset);
340289
quote! {
341-
((self.bits >> #offset) & #mask) #cast
290+
((self.bits >> #offset) & #hexmask) #cast
342291
}
343292
} else {
344293
quote! {
345-
(self.bits & #mask) #cast
294+
(self.bits & #hexmask) #cast
346295
}
347296
};
348297

349298
if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Read) {
350299
evs_r = Some(evs.clone());
351300

352-
let sc = &f.sc;
353301
r_impl_items.push(quote! {
354302
#[doc = #description_with_bits]
355303
#[inline(always)]
@@ -360,9 +308,9 @@ pub fn fields(
360308

361309
base_pc_w = base.as_ref().map(|base| {
362310
let pc = base.field.to_sanitized_upper_case();
363-
let base_pc_r = Ident::new(&format!("{}_A", pc), Span::call_site());
311+
let base_pc_r = Ident::new(&(pc.clone() + "_A"), span);
364312
let base_pc_r =
365-
derive_from_base(mod_items, &base, &pc_r, &base_pc_r, description);
313+
derive_from_base(mod_items, &base, &pc_r, &base_pc_r, &description);
366314

367315
let doc = format!("Reader of field `{}`", f.name);
368316
mod_items.push(quote! {
@@ -374,17 +322,17 @@ pub fn fields(
374322
});
375323

376324
if base.is_none() {
377-
let has_reserved_variant = evs.values.len() != (1 << f.width);
325+
let has_reserved_variant = evs.values.len() != (1 << width);
378326
let variants = Variant::from_enumerated_values(evs)?;
379327

380-
add_from_variants(mod_items, &variants, pc_r, fty, description, rv);
328+
add_from_variants(mod_items, &variants, &pc_r, &fty, &description, rv);
381329

382330
let mut enum_items = vec![];
383331

384332
let mut arms = variants
385333
.iter()
386334
.map(|v| {
387-
let i = util::unsuffixed_or_bool(v.value, f.width);
335+
let i = util::unsuffixed_or_bool(v.value, width);
388336
let pc = &v.pc;
389337

390338
if has_reserved_variant {
@@ -399,7 +347,7 @@ pub fn fields(
399347
arms.push(quote! {
400348
i => Res(i)
401349
});
402-
} else if 1 << f.width.to_ty_width()? != variants.len() {
350+
} else if 1 << width.to_ty_width()? != variants.len() {
403351
arms.push(quote! {
404352
_ => unreachable!()
405353
});
@@ -438,7 +386,7 @@ pub fn fields(
438386
} else {
439387
format!("is_{}", sc)
440388
},
441-
Span::call_site(),
389+
span,
442390
);
443391

444392
let doc = format!("Checks if the value of the field is `{}`", pc);
@@ -461,7 +409,6 @@ pub fn fields(
461409
});
462410
}
463411
} else {
464-
let sc = &f.sc;
465412
r_impl_items.push(quote! {
466413
#[doc = #description_with_bits]
467414
#[inline(always)]
@@ -479,29 +426,29 @@ pub fn fields(
479426
}
480427

481428
if can_write {
482-
let mut proxy_items = vec![];
429+
let new_pc_w = Ident::new(&(pc.clone() + "_AW"), span);
430+
let _pc_w = Ident::new(&(pc.clone() + "_W"), span);
483431

484-
let mut unsafety = unsafety(f.write_constraint, f.width);
485-
let width = f.width;
432+
let mut proxy_items = vec![];
433+
let mut unsafety = unsafety(f.write_constraint.as_ref(), width);
486434

487435
if let Some((evs, base)) = lookup_filter(&lookup_results, Usage::Write) {
488436
let variants = Variant::from_enumerated_values(evs)?;
489437

490-
if variants.len() == 1 << f.width {
438+
if variants.len() == 1 << width {
491439
unsafety = None;
492440
}
493441

494442
if Some(evs) != evs_r.as_ref() {
495-
pc_w = &f.pc_w;
496-
443+
pc_w = &new_pc_w;
497444
base_pc_w = base.as_ref().map(|base| {
498445
let pc = base.field.to_sanitized_upper_case();
499-
let base_pc_w = Ident::new(&format!("{}_AW", pc), Span::call_site());
500-
derive_from_base(mod_items, &base, &pc_w, &base_pc_w, description)
446+
let base_pc_w = Ident::new(&(pc + "_AW"), span);
447+
derive_from_base(mod_items, &base, &pc_w, &base_pc_w, &description)
501448
});
502449

503450
if base.is_none() {
504-
add_from_variants(mod_items, &variants, pc_w, fty, description, rv);
451+
add_from_variants(mod_items, &variants, &pc_w, &fty, &description, rv);
505452
}
506453
}
507454

@@ -562,7 +509,7 @@ pub fn fields(
562509
///Writes raw bits to the field
563510
#[inline(always)]
564511
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
565-
self.w.bits = (self.w.bits & !(#mask << #offset)) | (((value as #rty) & #mask) << #offset);
512+
self.w.bits = (self.w.bits & !(#hexmask << #offset)) | (((value as #rty) & #hexmask) << #offset);
566513
self.w
567514
}
568515
}
@@ -571,7 +518,7 @@ pub fn fields(
571518
///Writes raw bits to the field
572519
#[inline(always)]
573520
pub #unsafety fn #bits(self, value: #fty) -> &'a mut W {
574-
self.w.bits = (self.w.bits & !#mask) | ((value as #rty) & #mask);
521+
self.w.bits = (self.w.bits & !#hexmask) | ((value as #rty) & #hexmask);
575522
self.w
576523
}
577524
}
@@ -589,7 +536,6 @@ pub fn fields(
589536
}
590537
});
591538

592-
let sc = &f.sc;
593539
w_impl_items.push(quote! {
594540
#[doc = #description_with_bits]
595541
#[inline(always)]

0 commit comments

Comments
 (0)