Skip to content

Commit

Permalink
Add --nightly flag to gate untagged unions feature
Browse files Browse the repository at this point in the history
  • Loading branch information
wez committed May 8, 2018
1 parent 2de3249 commit 1e4756e
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 8 deletions.
11 changes: 8 additions & 3 deletions src/generate/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use Target;
use generate::{interrupt, peripheral};

/// Whole device generation
pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
pub fn render(d: &Device, target: &Target, nightly: bool) -> Result<Vec<Tokens>> {
let mut out = vec![];

let doc = format!(
Expand Down Expand Up @@ -43,10 +43,15 @@ pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
#![allow(non_camel_case_types)]
#![feature(const_fn)]
#![feature(try_from)]
#![feature(untagged_unions)]
#![no_std]
});

if nightly {
out.push(quote! {
#![feature(untagged_unions)]
});
}

match *target {
Target::CortexM => {
out.push(quote! {
Expand Down Expand Up @@ -128,7 +133,7 @@ pub fn render(d: &Device, target: &Target) -> Result<Vec<Tokens>> {
}


out.extend(peripheral::render(p, &d.peripherals, &d.defaults)?);
out.extend(peripheral::render(p, &d.peripherals, &d.defaults, nightly)?);

if p.registers
.as_ref()
Expand Down
88 changes: 84 additions & 4 deletions src/generate/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn render(
p: &Peripheral,
all_peripherals: &[Peripheral],
defaults: &Defaults,
nightly: bool,
) -> Result<Vec<Tokens>> {
let mut out = vec![];

Expand Down Expand Up @@ -76,11 +77,11 @@ pub fn render(

// Push any register or cluster blocks into the output
let mut mod_items = vec![];
mod_items.push(register_or_cluster_block(ercs, defaults, None)?);
mod_items.push(register_or_cluster_block(ercs, defaults, None, nightly)?);

// Push all cluster related information into the peripheral module
for c in &clusters {
mod_items.push(cluster_block(c, defaults, p, all_peripherals)?);
mod_items.push(cluster_block(c, defaults, p, all_peripherals, nightly)?);
}

// Push all regsiter realted information into the peripheral module
Expand Down Expand Up @@ -348,6 +349,84 @@ fn register_or_cluster_block(
ercs: &[Either<Register, Cluster>],
defs: &Defaults,
name: Option<&str>,
nightly: bool,
) -> Result<Tokens> {
if nightly {
register_or_cluster_block_nightly(ercs, defs, name)
} else {
register_or_cluster_block_stable(ercs, defs, name)
}
}

fn register_or_cluster_block_stable(
ercs: &[Either<Register, Cluster>],
defs: &Defaults,
name: Option<&str>,
) -> Result<Tokens> {
let mut fields = Tokens::new();
// enumeration of reserved fields
let mut i = 0;
// offset from the base address, in bytes
let mut offset = 0;

let ercs_expanded = expand(ercs, defs, name)?;

for reg_block_field in ercs_expanded {
let pad = if let Some(pad) = reg_block_field.offset.checked_sub(offset) {
pad
} else {
eprintln!(
"WARNING {:?} overlaps with another register block at offset {}. \
Ignoring.",
reg_block_field.field.ident,
reg_block_field.offset
);
continue;
};

if pad != 0 {
let name = Ident::new(format!("_reserved{}", i));
let pad = pad as usize;
fields.append(quote! {
#name : [u8; #pad],
});
i += 1;
}

let comment = &format!(
"0x{:02x} - {}",
reg_block_field.offset,
util::respace(&reg_block_field.description),
)[..];

fields.append(quote! {
#[doc = #comment]
});

reg_block_field.field.to_tokens(&mut fields);
Ident::new(",").to_tokens(&mut fields);

offset = reg_block_field.offset + reg_block_field.size / BITS_PER_BYTE;
}

let name = Ident::new(match name {
Some(name) => name.to_sanitized_upper_case(),
None => "RegisterBlock".into(),
});

Ok(quote! {
/// Register block
#[repr(C)]
pub struct #name {
#fields
}
})
}

fn register_or_cluster_block_nightly(
ercs: &[Either<Register, Cluster>],
defs: &Defaults,
name: Option<&str>,
) -> Result<Tokens> {
let mut fields = Tokens::new();
let mut helper_types = Tokens::new();
Expand Down Expand Up @@ -636,6 +715,7 @@ fn cluster_block(
defaults: &Defaults,
p: &Peripheral,
all_peripherals: &[Peripheral],
nightly: bool,
) -> Result<Tokens> {
let mut mod_items: Vec<Tokens> = vec![];

Expand All @@ -649,7 +729,7 @@ fn cluster_block(
}.replace("[%s]", "")
.replace("%s", "");
let name_sc = Ident::new(&*mod_name.to_sanitized_snake_case());
let reg_block = register_or_cluster_block(&c.children, defaults, Some(&mod_name))?;
let reg_block = register_or_cluster_block(&c.children, defaults, Some(&mod_name), nightly)?;

// Generate definition for each of the registers.
let registers = util::only_registers(&c.children);
Expand All @@ -666,7 +746,7 @@ fn cluster_block(
// Generate the sub-cluster blocks.
let clusters = util::only_clusters(&c.children);
for c in &clusters {
mod_items.push(cluster_block(c, defaults, p, all_peripherals)?);
mod_items.push(cluster_block(c, defaults, p, all_peripherals, nightly)?);
}

Ok(quote! {
Expand Down
9 changes: 8 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ fn run() -> Result<()> {
.takes_value(true)
.value_name("ARCH"),
)
.arg(
Arg::with_name("nightly_features")
.long("nightly")
.help("Enable features only available to nightly rustc")
)
.version(concat!(
env!("CARGO_PKG_VERSION"),
include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"))
Expand Down Expand Up @@ -91,7 +96,9 @@ fn run() -> Result<()> {

let device = svd::parse(xml);

let items = generate::device::render(&device, &target)?;
let nightly = matches.is_present("nightly_features");

let items = generate::device::render(&device, &target, nightly)?;

println!(
"{}",
Expand Down

0 comments on commit 1e4756e

Please sign in to comment.