Skip to content

Commit 2d578ba

Browse files
wezburrbull
authored andcommitted
fixup padding of fields emitted after a union!
1 parent 445a238 commit 2d578ba

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

src/generate/peripheral.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ fn register_or_cluster_block(
356356

357357
// We need to compute the idents of each register/union block first to make sure no conflicts exists.
358358
regions.resolve_idents()?;
359-
// The end of the region from the prior iteration of the loop
359+
// The end of the region for which we previously emitted a field into `fields`
360360
let mut last_end = 0;
361361

362362
for (i, region) in regions.regions.iter().enumerate() {
@@ -370,20 +370,10 @@ fn register_or_cluster_block(
370370
});
371371
}
372372

373-
last_end = region.end;
374-
375373
let mut region_fields = Tokens::new();
376374
let is_region_a_union = region.is_union();
377375

378376
for reg_block_field in &region.fields {
379-
if reg_block_field.offset != region.offset {
380-
// TODO: need to emit padding for this case.
381-
// Happens for freescale_mkl43z4
382-
warn!(
383-
"field {:?} has different offset {} than its union container {}",
384-
reg_block_field.field.ident, reg_block_field.offset, region.offset
385-
);
386-
}
387377
let comment = &format!(
388378
"0x{:02x} - {}",
389379
reg_block_field.offset,
@@ -411,7 +401,6 @@ fn register_or_cluster_block(
411401
}
412402
}
413403
});
414-
415404
} else {
416405
region_fields.append(quote! {
417406
#[doc = #comment]
@@ -424,7 +413,26 @@ fn register_or_cluster_block(
424413

425414
if !is_region_a_union {
426415
fields.append(&region_fields);
416+
} else {
417+
// Emit padding for the items that we're not emitting
418+
// as fields so that subsequent fields have the correct
419+
// alignment in the struct. We could omit this and just
420+
// not updated `last_end`, so that the padding check in
421+
// the outer loop kicks in, but it is nice to be able to
422+
// see that the padding is attributed to a union when
423+
// visually inspecting the alignment in the struct.
424+
//
425+
// Include the computed ident for the union in the padding
426+
// name, along with the region number, falling back to
427+
// the offset and end in case we couldn't figure out a
428+
// nice identifier.
429+
let name = Ident::new(format!("_reserved_{}_{}", i, region.compute_ident().unwrap_or_else(|| format!("{}_{}", region.offset, region.end))));
430+
let pad = (region.end - region.offset) as usize;
431+
fields.append(quote! {
432+
#name: [u8; #pad],
433+
})
427434
}
435+
last_end = region.end;
428436
}
429437

430438
let name = Ident::new(match name {

0 commit comments

Comments
 (0)