[meta] Add CPU modes to the meta crate;
This commit is contained in:
84
cranelift/codegen/meta/src/cdsl/cpu_modes.rs
Normal file
84
cranelift/codegen/meta/src/cdsl/cpu_modes.rs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
use crate::cdsl::types::LaneType;
|
||||||
|
use crate::cdsl::xform::{TransformGroup, TransformGroupIndex, TransformGroups};
|
||||||
|
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
pub struct CpuMode {
|
||||||
|
_name: &'static str,
|
||||||
|
default_legalize: Option<TransformGroupIndex>,
|
||||||
|
monomorphic_legalize: Option<TransformGroupIndex>,
|
||||||
|
typed_legalize: HashMap<String, TransformGroupIndex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CpuMode {
|
||||||
|
pub fn new(name: &'static str) -> Self {
|
||||||
|
Self {
|
||||||
|
_name: name,
|
||||||
|
default_legalize: None,
|
||||||
|
monomorphic_legalize: None,
|
||||||
|
typed_legalize: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn legalize_monomorphic(&mut self, group: &TransformGroup) {
|
||||||
|
assert!(self.monomorphic_legalize.is_none());
|
||||||
|
self.monomorphic_legalize = Some(group.id);
|
||||||
|
}
|
||||||
|
pub fn legalize_default(&mut self, group: &TransformGroup) {
|
||||||
|
assert!(self.default_legalize.is_none());
|
||||||
|
self.default_legalize = Some(group.id);
|
||||||
|
}
|
||||||
|
pub fn legalize_type(&mut self, lane_type: impl Into<LaneType>, group: &TransformGroup) {
|
||||||
|
assert!(self
|
||||||
|
.typed_legalize
|
||||||
|
.insert(lane_type.into().to_string(), group.id)
|
||||||
|
.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the
|
||||||
|
/// transitive set of TransformGroup this TargetIsa uses.
|
||||||
|
pub fn transitive_transform_groups(
|
||||||
|
&self,
|
||||||
|
all_groups: &TransformGroups,
|
||||||
|
) -> Vec<TransformGroupIndex> {
|
||||||
|
let mut roots = Vec::new();
|
||||||
|
if let Some(i) = &self.default_legalize {
|
||||||
|
roots.push(*i);
|
||||||
|
}
|
||||||
|
if let Some(i) = &self.monomorphic_legalize {
|
||||||
|
roots.push(*i);
|
||||||
|
}
|
||||||
|
roots.extend(self.typed_legalize.values().cloned());
|
||||||
|
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
for root in roots {
|
||||||
|
set.insert(root);
|
||||||
|
let mut base = root;
|
||||||
|
// Follow the chain of chain_with.
|
||||||
|
while let Some(chain_with) = &all_groups.get(base).chain_with {
|
||||||
|
set.insert(*chain_with);
|
||||||
|
base = *chain_with;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ret = Vec::from_iter(set);
|
||||||
|
ret.sort();
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
|
||||||
|
/// reachable set of TransformGroup this TargetIsa uses.
|
||||||
|
pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
if let Some(i) = &self.default_legalize {
|
||||||
|
set.insert(*i);
|
||||||
|
}
|
||||||
|
if let Some(i) = &self.monomorphic_legalize {
|
||||||
|
set.insert(*i);
|
||||||
|
}
|
||||||
|
set.extend(self.typed_legalize.values().cloned());
|
||||||
|
let mut ret = Vec::from_iter(set);
|
||||||
|
ret.sort();
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,18 @@
|
|||||||
|
use crate::cdsl::cpu_modes::CpuMode;
|
||||||
use crate::cdsl::inst::InstructionGroup;
|
use crate::cdsl::inst::InstructionGroup;
|
||||||
use crate::cdsl::regs::IsaRegs;
|
use crate::cdsl::regs::IsaRegs;
|
||||||
use crate::cdsl::settings::SettingGroup;
|
use crate::cdsl::settings::SettingGroup;
|
||||||
|
use crate::cdsl::xform::{TransformGroupIndex, TransformGroups};
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
pub struct TargetIsa {
|
pub struct TargetIsa {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub instructions: InstructionGroup,
|
pub instructions: InstructionGroup,
|
||||||
pub settings: SettingGroup,
|
pub settings: SettingGroup,
|
||||||
pub regs: IsaRegs,
|
pub regs: IsaRegs,
|
||||||
|
pub cpu_modes: Vec<CpuMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetIsa {
|
impl TargetIsa {
|
||||||
@@ -15,12 +21,41 @@ impl TargetIsa {
|
|||||||
instructions: InstructionGroup,
|
instructions: InstructionGroup,
|
||||||
settings: SettingGroup,
|
settings: SettingGroup,
|
||||||
regs: IsaRegs,
|
regs: IsaRegs,
|
||||||
|
cpu_modes: Vec<CpuMode>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
instructions,
|
instructions,
|
||||||
settings,
|
settings,
|
||||||
regs,
|
regs,
|
||||||
|
cpu_modes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the
|
||||||
|
/// transitive set of TransformGroup this TargetIsa uses.
|
||||||
|
pub fn transitive_transform_groups(
|
||||||
|
&self,
|
||||||
|
all_groups: &TransformGroups,
|
||||||
|
) -> Vec<TransformGroupIndex> {
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
for cpu_mode in &self.cpu_modes {
|
||||||
|
set.extend(cpu_mode.transitive_transform_groups(all_groups));
|
||||||
|
}
|
||||||
|
let mut vec = Vec::from_iter(set);
|
||||||
|
vec.sort();
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
|
||||||
|
/// reachable set of TransformGroup this TargetIsa uses.
|
||||||
|
pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
|
||||||
|
let mut set = HashSet::new();
|
||||||
|
for cpu_mode in &self.cpu_modes {
|
||||||
|
set.extend(cpu_mode.direct_transform_groups());
|
||||||
|
}
|
||||||
|
let mut vec = Vec::from_iter(set);
|
||||||
|
vec.sort();
|
||||||
|
vec
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
|
pub mod cpu_modes;
|
||||||
pub mod formats;
|
pub mod formats;
|
||||||
pub mod inst;
|
pub mod inst;
|
||||||
pub mod isa;
|
pub mod isa;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
use crate::cdsl::cpu_modes::CpuMode;
|
||||||
use crate::cdsl::inst::InstructionGroup;
|
use crate::cdsl::inst::InstructionGroup;
|
||||||
use crate::cdsl::isa::TargetIsa;
|
use crate::cdsl::isa::TargetIsa;
|
||||||
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
||||||
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
|
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
|
||||||
|
|
||||||
use crate::shared::Definitions as SharedDefinitions;
|
use crate::shared::Definitions as SharedDefinitions;
|
||||||
|
|
||||||
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
||||||
@@ -52,5 +54,16 @@ pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
|
|||||||
|
|
||||||
let inst_group = InstructionGroup::new("arm32", "arm32 specific instruction set");
|
let inst_group = InstructionGroup::new("arm32", "arm32 specific instruction set");
|
||||||
|
|
||||||
TargetIsa::new("arm32", inst_group, settings, regs)
|
// CPU modes for 32-bit ARM and Thumb2.
|
||||||
|
let mut a32 = CpuMode::new("A32");
|
||||||
|
let mut t32 = CpuMode::new("T32");
|
||||||
|
|
||||||
|
// TODO refine these.
|
||||||
|
let narrow = shared_defs.transform_groups.by_name("narrow");
|
||||||
|
a32.legalize_default(narrow);
|
||||||
|
t32.legalize_default(narrow);
|
||||||
|
|
||||||
|
let cpu_modes = vec![a32, t32];
|
||||||
|
|
||||||
|
TargetIsa::new("arm32", inst_group, settings, regs, cpu_modes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
use crate::cdsl::cpu_modes::CpuMode;
|
||||||
use crate::cdsl::inst::InstructionGroup;
|
use crate::cdsl::inst::InstructionGroup;
|
||||||
use crate::cdsl::isa::TargetIsa;
|
use crate::cdsl::isa::TargetIsa;
|
||||||
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
||||||
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
|
use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
|
||||||
|
|
||||||
use crate::shared::Definitions as SharedDefinitions;
|
use crate::shared::Definitions as SharedDefinitions;
|
||||||
|
|
||||||
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
||||||
@@ -48,5 +50,13 @@ pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
|
|||||||
|
|
||||||
let inst_group = InstructionGroup::new("arm64", "arm64 specific instruction set");
|
let inst_group = InstructionGroup::new("arm64", "arm64 specific instruction set");
|
||||||
|
|
||||||
TargetIsa::new("arm64", inst_group, settings, regs)
|
let mut a64 = CpuMode::new("A64");
|
||||||
|
|
||||||
|
// TODO refine these.
|
||||||
|
let narrow = shared_defs.transform_groups.by_name("narrow");
|
||||||
|
a64.legalize_default(narrow);
|
||||||
|
|
||||||
|
let cpu_modes = vec![a64];
|
||||||
|
|
||||||
|
TargetIsa::new("arm64", inst_group, settings, regs, cpu_modes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
use crate::cdsl::cpu_modes::CpuMode;
|
||||||
use crate::cdsl::inst::InstructionGroup;
|
use crate::cdsl::inst::InstructionGroup;
|
||||||
use crate::cdsl::isa::TargetIsa;
|
use crate::cdsl::isa::TargetIsa;
|
||||||
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
||||||
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
|
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
|
||||||
|
|
||||||
|
use crate::shared::types::Float::{F32, F64};
|
||||||
|
use crate::shared::types::Int::{I32, I64};
|
||||||
use crate::shared::Definitions as SharedDefinitions;
|
use crate::shared::Definitions as SharedDefinitions;
|
||||||
|
|
||||||
fn define_settings(shared: &SettingGroup) -> SettingGroup {
|
fn define_settings(shared: &SettingGroup) -> SettingGroup {
|
||||||
@@ -84,5 +88,26 @@ pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
|
|||||||
|
|
||||||
let inst_group = InstructionGroup::new("riscv", "riscv specific instruction set");
|
let inst_group = InstructionGroup::new("riscv", "riscv specific instruction set");
|
||||||
|
|
||||||
TargetIsa::new("riscv", inst_group, settings, regs)
|
// CPU modes for 32-bit and 64-bit operation.
|
||||||
|
let mut rv_32 = CpuMode::new("RV32");
|
||||||
|
let mut rv_64 = CpuMode::new("RV64");
|
||||||
|
|
||||||
|
let expand = shared_defs.transform_groups.by_name("expand");
|
||||||
|
let narrow = shared_defs.transform_groups.by_name("narrow");
|
||||||
|
rv_32.legalize_monomorphic(expand);
|
||||||
|
rv_32.legalize_default(narrow);
|
||||||
|
rv_32.legalize_type(I32, expand);
|
||||||
|
rv_32.legalize_type(F32, expand);
|
||||||
|
rv_32.legalize_type(F64, expand);
|
||||||
|
|
||||||
|
rv_64.legalize_monomorphic(expand);
|
||||||
|
rv_64.legalize_default(narrow);
|
||||||
|
rv_64.legalize_type(I32, expand);
|
||||||
|
rv_64.legalize_type(I64, expand);
|
||||||
|
rv_64.legalize_type(F32, expand);
|
||||||
|
rv_64.legalize_type(F64, expand);
|
||||||
|
|
||||||
|
let cpu_modes = vec![rv_32, rv_64];
|
||||||
|
|
||||||
|
TargetIsa::new("riscv", inst_group, settings, regs, cpu_modes)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
mod instructions;
|
use crate::cdsl::cpu_modes::CpuMode;
|
||||||
|
|
||||||
use crate::cdsl::isa::TargetIsa;
|
use crate::cdsl::isa::TargetIsa;
|
||||||
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
||||||
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
|
use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
|
||||||
|
|
||||||
|
use crate::shared::types::Bool::B1;
|
||||||
|
use crate::shared::types::Float::{F32, F64};
|
||||||
|
use crate::shared::types::Int::{I16, I32, I64, I8};
|
||||||
use crate::shared::Definitions as SharedDefinitions;
|
use crate::shared::Definitions as SharedDefinitions;
|
||||||
|
|
||||||
|
mod instructions;
|
||||||
|
mod legalize;
|
||||||
|
|
||||||
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
fn define_settings(_shared: &SettingGroup) -> SettingGroup {
|
||||||
let mut settings = SettingGroupBuilder::new("x86");
|
let mut settings = SettingGroupBuilder::new("x86");
|
||||||
|
|
||||||
@@ -118,6 +123,37 @@ pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
|
|||||||
let regs = define_registers();
|
let regs = define_registers();
|
||||||
|
|
||||||
let inst_group = instructions::define(&shared_defs.format_registry);
|
let inst_group = instructions::define(&shared_defs.format_registry);
|
||||||
|
legalize::define(shared_defs, &inst_group);
|
||||||
|
|
||||||
TargetIsa::new("x86", inst_group, settings, regs)
|
// CPU modes for 32-bit and 64-bit operations.
|
||||||
|
let mut x86_64 = CpuMode::new("I64");
|
||||||
|
let mut x86_32 = CpuMode::new("I32");
|
||||||
|
|
||||||
|
let expand_flags = shared_defs.transform_groups.by_name("expand_flags");
|
||||||
|
let narrow = shared_defs.transform_groups.by_name("narrow");
|
||||||
|
let widen = shared_defs.transform_groups.by_name("widen");
|
||||||
|
let x86_expand = shared_defs.transform_groups.by_name("x86_expand");
|
||||||
|
|
||||||
|
x86_32.legalize_monomorphic(expand_flags);
|
||||||
|
x86_32.legalize_default(narrow);
|
||||||
|
x86_32.legalize_type(B1, expand_flags);
|
||||||
|
x86_32.legalize_type(I8, widen);
|
||||||
|
x86_32.legalize_type(I16, widen);
|
||||||
|
x86_32.legalize_type(I32, x86_expand);
|
||||||
|
x86_32.legalize_type(F32, x86_expand);
|
||||||
|
x86_32.legalize_type(F64, x86_expand);
|
||||||
|
|
||||||
|
x86_64.legalize_monomorphic(expand_flags);
|
||||||
|
x86_64.legalize_default(narrow);
|
||||||
|
x86_64.legalize_type(B1, expand_flags);
|
||||||
|
x86_64.legalize_type(I8, widen);
|
||||||
|
x86_64.legalize_type(I16, widen);
|
||||||
|
x86_64.legalize_type(I32, x86_expand);
|
||||||
|
x86_64.legalize_type(I64, x86_expand);
|
||||||
|
x86_64.legalize_type(F32, x86_expand);
|
||||||
|
x86_64.legalize_type(F64, x86_expand);
|
||||||
|
|
||||||
|
let cpu_modes = vec![x86_64, x86_32];
|
||||||
|
|
||||||
|
TargetIsa::new("x86", inst_group, settings, regs, cpu_modes)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user