Move encoding-related information into an EncInfo struct.
The tables returned by recipe_names() and recipe_constraints() are now collected into an EncInfo struct that is available from TargetIsa::encoding_info(). This is equivalent to the register bank tables available fro TargetIsa::register_info(). This cleans of the TargetIsa interface and makes it easier to add encoding-related information.
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
|
||||
use ir::InstructionData;
|
||||
use ir::types;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-arm32.rs"));
|
||||
|
||||
@@ -9,7 +9,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -55,6 +55,10 @@ impl TargetIsa for Isa {
|
||||
registers::INFO.clone()
|
||||
}
|
||||
|
||||
fn encoding_info(&self) -> EncInfo {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn encode(&self,
|
||||
dfg: &ir::DataFlowGraph,
|
||||
inst: &ir::InstructionData)
|
||||
@@ -72,14 +76,6 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn recipe_names(&self) -> &'static [&'static str] {
|
||||
&enc_tables::RECIPE_NAMES[..]
|
||||
}
|
||||
|
||||
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
|
||||
&enc_tables::RECIPE_CONSTRAINTS
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
use ir::InstructionData;
|
||||
use ir::types;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-arm64.rs"));
|
||||
|
||||
@@ -9,7 +9,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -48,6 +48,10 @@ impl TargetIsa for Isa {
|
||||
registers::INFO.clone()
|
||||
}
|
||||
|
||||
fn encoding_info(&self) -> EncInfo {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn encode(&self,
|
||||
dfg: &ir::DataFlowGraph,
|
||||
inst: &ir::InstructionData)
|
||||
@@ -65,14 +69,6 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn recipe_names(&self) -> &'static [&'static str] {
|
||||
&enc_tables::RECIPE_NAMES[..]
|
||||
}
|
||||
|
||||
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
|
||||
&enc_tables::RECIPE_CONSTRAINTS
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! The `Encoding` struct.
|
||||
|
||||
use std::fmt;
|
||||
use isa::constraints::RecipeConstraints;
|
||||
|
||||
/// Bits needed to encode an instruction as binary machine code.
|
||||
///
|
||||
@@ -76,3 +77,28 @@ impl fmt::Display for DisplayEncoding {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about all the encodings in this ISA.
|
||||
#[derive(Clone)]
|
||||
pub struct EncInfo {
|
||||
/// Constraints on value operands per recipe.
|
||||
pub constraints: &'static [RecipeConstraints],
|
||||
|
||||
/// Names of encoding recipes.
|
||||
pub names: &'static [&'static str],
|
||||
}
|
||||
|
||||
impl EncInfo {
|
||||
/// Get the value operand constraints for `enc` if it is a legal encoding.
|
||||
pub fn operand_constraints(&self, enc: Encoding) -> Option<&RecipeConstraints> {
|
||||
self.constraints.get(enc.recipe())
|
||||
}
|
||||
|
||||
/// Create an object that can display an ISA-dependent encoding properly.
|
||||
pub fn display(&self, enc: Encoding) -> DisplayEncoding {
|
||||
DisplayEncoding {
|
||||
encoding: enc,
|
||||
recipe_names: self.names,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
use ir::InstructionData;
|
||||
use ir::types;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs"));
|
||||
|
||||
@@ -9,7 +9,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -55,6 +55,10 @@ impl TargetIsa for Isa {
|
||||
registers::INFO.clone()
|
||||
}
|
||||
|
||||
fn encoding_info(&self) -> EncInfo {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn encode(&self,
|
||||
dfg: &ir::DataFlowGraph,
|
||||
inst: &ir::InstructionData)
|
||||
@@ -72,14 +76,6 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn recipe_names(&self) -> &'static [&'static str] {
|
||||
&enc_tables::RECIPE_NAMES[..]
|
||||
}
|
||||
|
||||
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
|
||||
&enc_tables::RECIPE_CONSTRAINTS
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
//! The configured target ISA trait object is a `Box<TargetIsa>` which can be used for multiple
|
||||
//! concurrent function compilations.
|
||||
|
||||
pub use isa::encoding::Encoding;
|
||||
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex};
|
||||
pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind};
|
||||
pub use isa::encoding::{Encoding, EncInfo};
|
||||
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex};
|
||||
|
||||
use binemit::CodeSink;
|
||||
use settings;
|
||||
@@ -143,25 +143,8 @@ pub trait TargetIsa {
|
||||
/// This is also the main entry point for determining if an instruction is legal.
|
||||
fn encode(&self, dfg: &DataFlowGraph, inst: &InstructionData) -> Result<Encoding, Legalize>;
|
||||
|
||||
/// Get a static array of names associated with encoding recipes in this ISA. Encoding recipes
|
||||
/// are numbered starting from 0, corresponding to indexes into the name array.
|
||||
///
|
||||
/// This is just used for printing and parsing encodings in the textual IL format.
|
||||
fn recipe_names(&self) -> &'static [&'static str];
|
||||
|
||||
/// Get a static array of value operand constraints associated with encoding recipes in this
|
||||
/// ISA.
|
||||
///
|
||||
/// The constraints describe which registers can be used with an encoding recipe.
|
||||
fn recipe_constraints(&self) -> &'static [RecipeConstraints];
|
||||
|
||||
/// Create an object that can display an ISA-dependent encoding properly.
|
||||
fn display_enc(&self, enc: Encoding) -> encoding::DisplayEncoding {
|
||||
encoding::DisplayEncoding {
|
||||
encoding: enc,
|
||||
recipe_names: self.recipe_names(),
|
||||
}
|
||||
}
|
||||
/// Get a data structure describing the instruction encodings in this ISA.
|
||||
fn encoding_info(&self) -> EncInfo;
|
||||
|
||||
/// Legalize a function signature.
|
||||
///
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
//! Encoding tables for RISC-V.
|
||||
|
||||
use ir::condcodes::IntCC;
|
||||
use ir::{Opcode, InstructionData};
|
||||
use ir::types;
|
||||
use predicates;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use ir::{Opcode, InstructionData};
|
||||
use isa::EncInfo;
|
||||
use isa::constraints::*;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
use predicates;
|
||||
use super::registers::*;
|
||||
|
||||
// Include the generated encoding tables:
|
||||
@@ -13,4 +14,5 @@ use super::registers::*;
|
||||
// - `LEVEL1_RV64`
|
||||
// - `LEVEL2`
|
||||
// - `ENCLIST`
|
||||
// - `INFO`
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-riscv.rs"));
|
||||
|
||||
@@ -10,7 +10,7 @@ use super::super::settings as shared_settings;
|
||||
use binemit::CodeSink;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, Encoding, Legalize, RecipeConstraints};
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use ir::{Function, Inst, InstructionData, DataFlowGraph, Signature};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -56,6 +56,10 @@ impl TargetIsa for Isa {
|
||||
registers::INFO.clone()
|
||||
}
|
||||
|
||||
fn encoding_info(&self) -> EncInfo {
|
||||
enc_tables::INFO.clone()
|
||||
}
|
||||
|
||||
fn encode(&self, dfg: &DataFlowGraph, inst: &InstructionData) -> Result<Encoding, Legalize> {
|
||||
lookup_enclist(inst.ctrl_typevar(dfg),
|
||||
inst.opcode(),
|
||||
@@ -70,14 +74,6 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn recipe_names(&self) -> &'static [&'static str] {
|
||||
&enc_tables::RECIPE_NAMES[..]
|
||||
}
|
||||
|
||||
fn recipe_constraints(&self) -> &'static [RecipeConstraints] {
|
||||
&enc_tables::RECIPE_CONSTRAINTS
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut Signature) {
|
||||
// We can pass in `self.isa_flags` too, if we need it.
|
||||
abi::legalize_signature(sig, &self.shared_flags)
|
||||
@@ -100,7 +96,7 @@ mod tests {
|
||||
use ir::{types, immediates};
|
||||
|
||||
fn encstr(isa: &isa::TargetIsa, enc: isa::Encoding) -> String {
|
||||
isa.display_enc(enc).to_string()
|
||||
isa.encoding_info().display(enc).to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user