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:
@@ -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.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -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!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user