Implement the machinery to create a TargetIsa.

Add an isa::lookup() function which serves as a target registry for creating
Box<TargetIsa> trait objects.

An isa::Builder makes it possible to confugure the trait object before it is
created.
This commit is contained in:
Jakob Stoklund Olesen
2016-08-11 11:39:42 -07:00
parent 1ae9a37796
commit 1087aa67f0
3 changed files with 94 additions and 5 deletions

View File

@@ -7,7 +7,7 @@
//! //!
//! # Constructing a `TargetIsa` instance //! # 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 //! - 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 //! 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` //! The `isa::lookup()` function is the main entry point which returns an `isa::Builder`
//! appropriate for the requested ISA: //! appropriate for the requested ISA:
//! //!
//! ```ignore //! ```
//! let isa_builder = isa::lookup("riscv").unwrap(); //! use cretonne::settings::{self, Configurable};
//! adjust_isa_settings(&mut isa_builder.settings); //! use cretonne::isa;
//! let isa = builder.finish(shared_settings()); //!
//! 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<TargetIsa>` which can be used for multiple
//! concurrent function compilations.
pub mod riscv; pub mod riscv;
use settings;
use ir::dfg::DataFlowGraph; use ir::dfg::DataFlowGraph;
use ir::entities::Inst; 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<Builder> {
match name {
"riscv" => riscv_builder(),
_ => None,
}
}
// Make a builder for RISC-V.
fn riscv_builder() -> Option<Builder> {
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<TargetIsa>,
}
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<TargetIsa> {
(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 { pub trait TargetIsa {
/// Encode an instruction after determining it is legal. /// Encode an instruction after determining it is legal.
/// ///

View File

@@ -1,3 +1,37 @@
//! RISC-V Instruction Set Architecture. //! RISC-V Instruction Set Architecture.
pub mod settings; 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<TargetIsa> {
Box::new(Isa {
shared_flags: shared_flags,
isa_flags: settings::Flags::new(builder),
})
}
impl TargetIsa for Isa {
fn encode(&self, _: &DataFlowGraph, _: &Inst) -> Option<Encoding> {
unimplemented!()
}
}

View File

@@ -211,6 +211,7 @@ def gen_group(sgrp, fmt):
""" """
byte_size = layout_group(sgrp) byte_size = layout_group(sgrp)
fmt.line('#[derive(Clone)]')
fmt.doc_comment('Flags group `{}`.'.format(sgrp.name)) fmt.doc_comment('Flags group `{}`.'.format(sgrp.name))
with fmt.indented('pub struct Flags {', '}'): with fmt.indented('pub struct Flags {', '}'):
fmt.line('bytes: [u8; {}],'.format(byte_size)) fmt.line('bytes: [u8; {}],'.format(byte_size))