diff --git a/cranelift/src/libcretonne/isa/mod.rs b/cranelift/src/libcretonne/isa/mod.rs index 577f6e400e..43834be3ef 100644 --- a/cranelift/src/libcretonne/isa/mod.rs +++ b/cranelift/src/libcretonne/isa/mod.rs @@ -7,7 +7,7 @@ //! //! # Constructing a `TargetIsa` instance //! -//! The target ISA is build from the following information: +//! The target ISA is built from the following information: //! //! - The name of the target ISA as a string. Cretonne is a cross-compiler, so the ISA to target //! can be selected dynamically. Individual ISAs can be left out when Cretonne is compiled, so a @@ -19,18 +19,72 @@ //! The `isa::lookup()` function is the main entry point which returns an `isa::Builder` //! appropriate for the requested ISA: //! -//! ```ignore -//! let isa_builder = isa::lookup("riscv").unwrap(); -//! adjust_isa_settings(&mut isa_builder.settings); -//! let isa = builder.finish(shared_settings()); +//! ``` +//! use cretonne::settings::{self, Configurable}; +//! use cretonne::isa; +//! +//! let shared_builder = settings::builder(); +//! let shared_flags = settings::Flags::new(shared_builder); +//! +//! match isa::lookup("riscv") { +//! None => { +//! // The RISC-V target ISA is not available. +//! } +//! Some(mut isa_builder) => { +//! isa_builder.set("supports_m", "on"); +//! let isa = isa_builder.finish(shared_flags); +//! } +//! } //! ``` //! +//! The configured target ISA trait object is a `Box` which can be used for multiple +//! concurrent function compilations. pub mod riscv; +use settings; use ir::dfg::DataFlowGraph; use ir::entities::Inst; +/// Look for a supported ISA with the given `name`. +/// Return a builder that can create a corresponding `TargetIsa`. +pub fn lookup(name: &str) -> Option { + match name { + "riscv" => riscv_builder(), + _ => None, + } +} + +// Make a builder for RISC-V. +fn riscv_builder() -> Option { + Some(riscv::isa_builder()) +} + +/// Builder for a `TargetIsa`. +/// Modify the ISA-specific settings before creating the `TargetIsa` trait object with `finish`. +pub struct Builder { + setup: settings::Builder, + constructor: fn(settings::Flags, settings::Builder) -> Box, +} + +impl Builder { + /// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a + /// fully configured `TargetIsa` trait object. + pub fn finish(self, shared_flags: settings::Flags) -> Box { + (self.constructor)(shared_flags, self.setup) + } +} + +impl settings::Configurable for Builder { + fn set(&mut self, name: &str, value: &str) -> settings::Result<()> { + self.setup.set(name, value) + } + + fn set_bool(&mut self, name: &str, value: bool) -> settings::Result<()> { + self.setup.set_bool(name, value) + } +} + pub trait TargetIsa { /// Encode an instruction after determining it is legal. /// diff --git a/cranelift/src/libcretonne/isa/riscv/mod.rs b/cranelift/src/libcretonne/isa/riscv/mod.rs index 775154a3d6..641263b9f6 100644 --- a/cranelift/src/libcretonne/isa/riscv/mod.rs +++ b/cranelift/src/libcretonne/isa/riscv/mod.rs @@ -1,3 +1,37 @@ //! RISC-V Instruction Set Architecture. pub mod settings; + +use super::super::settings as shared_settings; +use super::Builder as IsaBuilder; +use super::{TargetIsa, Encoding}; +use ir::dfg::DataFlowGraph; +use ir::entities::Inst; + +#[allow(dead_code)] +struct Isa { + shared_flags: shared_settings::Flags, + isa_flags: settings::Flags, +} + +pub fn isa_builder() -> IsaBuilder { + IsaBuilder { + setup: settings::builder(), + constructor: isa_constructor, + } +} + +fn isa_constructor(shared_flags: shared_settings::Flags, + builder: shared_settings::Builder) + -> Box { + Box::new(Isa { + shared_flags: shared_flags, + isa_flags: settings::Flags::new(builder), + }) +} + +impl TargetIsa for Isa { + fn encode(&self, _: &DataFlowGraph, _: &Inst) -> Option { + unimplemented!() + } +} diff --git a/meta/gen_settings.py b/meta/gen_settings.py index a10dd5352a..486e71371e 100644 --- a/meta/gen_settings.py +++ b/meta/gen_settings.py @@ -211,6 +211,7 @@ def gen_group(sgrp, fmt): """ byte_size = layout_group(sgrp) + fmt.line('#[derive(Clone)]') fmt.doc_comment('Flags group `{}`.'.format(sgrp.name)) with fmt.indented('pub struct Flags {', '}'): fmt.line('bytes: [u8; {}],'.format(byte_size))