diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index b808b8874642..7caac93a67ad 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -27,10 +27,10 @@ //! let shared_flags = settings::Flags::new(&shared_builder); //! //! match isa::lookup("riscv") { -//! None => { +//! Err(_) => { //! // The RISC-V target ISA is not available. //! } -//! Some(mut isa_builder) => { +//! Ok(mut isa_builder) => { //! isa_builder.set("supports_m", "on"); //! let isa = isa_builder.finish(shared_flags); //! } @@ -51,42 +51,61 @@ use ir; use regalloc; use isa::enc_tables::Encodings; +#[cfg(build_riscv)] pub mod riscv; + +#[cfg(build_intel)] pub mod intel; + +#[cfg(build_arm32)] pub mod arm32; + +#[cfg(build_arm64)] pub mod arm64; + pub mod registers; mod encoding; mod enc_tables; mod constraints; +/// Returns a builder that can create a corresponding `TargetIsa` +/// or `Err(LookupError::Unsupported)` if not enabled. +macro_rules! isa_builder { + ($module:ident, $name:ident) => { + { + #[cfg($name)] + fn $name() -> Result { + Ok($module::isa_builder()) + }; + #[cfg(not($name))] + fn $name() -> Result { + Err(LookupError::Unsupported) + } + $name() + } + }; +} + /// Look for a supported ISA with the given `name`. /// Return a builder that can create a corresponding `TargetIsa`. -pub fn lookup(name: &str) -> Option { +pub fn lookup(name: &str) -> Result { match name { - "riscv" => riscv_builder(), - "intel" => intel_builder(), - "arm32" => arm32_builder(), - "arm64" => arm64_builder(), - _ => None, + "riscv" => isa_builder!(riscv, build_riscv), + "intel" => isa_builder!(intel, build_intel), + "arm32" => isa_builder!(arm32, build_arm32), + "arm64" => isa_builder!(arm64, build_arm64), + _ => Err(LookupError::Unknown), } } -// Make a builder for RISC-V. -fn riscv_builder() -> Option { - Some(riscv::isa_builder()) -} - -fn intel_builder() -> Option { - Some(intel::isa_builder()) -} - -fn arm32_builder() -> Option { - Some(arm32::isa_builder()) -} +/// Describes reason for target lookup failure +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +pub enum LookupError { + /// Unknown Target + Unknown, -fn arm64_builder() -> Option { - Some(arm64::isa_builder()) + /// Target known but not built and thus not supported + Unsupported, } /// Builder for a `TargetIsa`. diff --git a/lib/cretonne/src/regalloc/pressure.rs b/lib/cretonne/src/regalloc/pressure.rs index fd9cf7c36375..a9ab6bbbcb52 100644 --- a/lib/cretonne/src/regalloc/pressure.rs +++ b/lib/cretonne/src/regalloc/pressure.rs @@ -247,6 +247,7 @@ impl fmt::Display for Pressure { } #[cfg(test)] +#[cfg(build_arm32)] mod tests { use isa::{TargetIsa, RegClass}; use regalloc::AllocatableSet; @@ -261,7 +262,7 @@ mod tests { let shared_builder = settings::builder(); let shared_flags = settings::Flags::new(&shared_builder); - isa::lookup("arm32").map(|b| b.finish(shared_flags)) + isa::lookup("arm32").ok().map(|b| b.finish(shared_flags)) } // Get a register class by name. diff --git a/lib/cretonne/src/regalloc/solver.rs b/lib/cretonne/src/regalloc/solver.rs index b135f051f35a..ea028f551b03 100644 --- a/lib/cretonne/src/regalloc/solver.rs +++ b/lib/cretonne/src/regalloc/solver.rs @@ -700,6 +700,7 @@ impl Solver { } #[cfg(test)] +#[cfg(build_arm32)] mod tests { use entity_ref::EntityRef; use ir::Value; @@ -716,7 +717,7 @@ mod tests { let shared_builder = settings::builder(); let shared_flags = settings::Flags::new(&shared_builder); - isa::lookup("arm32").map(|b| b.finish(shared_flags)) + isa::lookup("arm32").ok().map(|b| b.finish(shared_flags)) } // Get a register class by name. diff --git a/lib/reader/src/parser.rs b/lib/reader/src/parser.rs index fb659a6b8eea..865cdcbd0d3f 100644 --- a/lib/reader/src/parser.rs +++ b/lib/reader/src/parser.rs @@ -621,8 +621,6 @@ impl<'a> Parser<'a> { &self.loc)?; } "isa" => { - last_set_loc = None; - seen_isa = true; let loc = self.loc; // Grab the whole line so the lexer won't go looking for tokens on the // following lines. @@ -633,9 +631,16 @@ impl<'a> Parser<'a> { Some(w) => w, }; let mut isa_builder = match isa::lookup(isa_name) { - None => return err!(loc, "unknown ISA '{}'", isa_name), - Some(b) => b, + Err(isa::LookupError::Unknown) => { + return err!(loc, "unknown ISA '{}'", isa_name) + } + Err(isa::LookupError::Unsupported) => { + continue; + } + Ok(b) => b, }; + last_set_loc = None; + seen_isa = true; // Apply the ISA-specific settings to `isa_builder`. isaspec::parse_options(words, &mut isa_builder, &self.loc)?; @@ -1939,6 +1944,7 @@ mod tests { } #[test] + #[cfg(build_riscv)] fn isa_spec() { assert!(parse_test("isa function %foo() {}")