[build] Implement registers code generation in the Rust meta crate;
This commit is contained in:
committed by
Dan Gohman
parent
4f2d7dd54f
commit
b7f2acf0ea
39
lib/codegen/meta/src/isa/arm32/mod.rs
Normal file
39
lib/codegen/meta/src/isa/arm32/mod.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use cdsl::regs::{RegBankBuilder, RegClassBuilder};
|
||||
use isa;
|
||||
|
||||
pub fn define() -> isa::TargetIsa {
|
||||
let mut isa = isa::TargetIsa::new("arm32");
|
||||
|
||||
let builder = RegBankBuilder::new("FloatRegs", "s")
|
||||
.units(64)
|
||||
.track_pressure(true);
|
||||
let float_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("IntRegs", "r")
|
||||
.units(16)
|
||||
.track_pressure(true);
|
||||
let int_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FlagRegs", "")
|
||||
.units(1)
|
||||
.names(vec!["nzcv"])
|
||||
.track_pressure(false);
|
||||
let flag_reg = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "S", float_regs).count(32);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "D", float_regs).width(2);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "Q", float_regs).width(4);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "GPR", int_regs);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FLAG", flag_reg);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
isa
|
||||
}
|
||||
35
lib/codegen/meta/src/isa/arm64/mod.rs
Normal file
35
lib/codegen/meta/src/isa/arm64/mod.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use cdsl::regs::{RegBankBuilder, RegClassBuilder};
|
||||
use isa;
|
||||
|
||||
pub fn define() -> isa::TargetIsa {
|
||||
let mut isa = isa::TargetIsa::new("arm64");
|
||||
|
||||
// The `x31` regunit serves as the stack pointer / zero register depending on context. We
|
||||
// reserve it and don't model the difference.
|
||||
let builder = RegBankBuilder::new("IntRegs", "x")
|
||||
.units(32)
|
||||
.track_pressure(true);
|
||||
let int_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FloatRegs", "v")
|
||||
.units(32)
|
||||
.track_pressure(true);
|
||||
let float_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FlagRegs", "")
|
||||
.units(1)
|
||||
.names(vec!["nzcv"])
|
||||
.track_pressure(false);
|
||||
let flag_reg = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "GPR", int_regs);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FPR", float_regs);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FLAG", flag_reg);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
isa
|
||||
}
|
||||
@@ -1,3 +1,11 @@
|
||||
use cdsl::isa::TargetIsa;
|
||||
use std::fmt;
|
||||
|
||||
mod arm32;
|
||||
mod arm64;
|
||||
mod riscv;
|
||||
mod x86;
|
||||
|
||||
/// Represents known ISA target.
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Isa {
|
||||
@@ -13,7 +21,7 @@ impl Isa {
|
||||
Isa::all()
|
||||
.iter()
|
||||
.cloned()
|
||||
.filter(|isa| isa.name() == name)
|
||||
.filter(|isa| isa.to_string() == name)
|
||||
.next()
|
||||
}
|
||||
|
||||
@@ -31,16 +39,6 @@ impl Isa {
|
||||
[Isa::Riscv, Isa::X86, Isa::Arm32, Isa::Arm64]
|
||||
}
|
||||
|
||||
/// Returns name of the isa target.
|
||||
pub fn name(&self) -> &'static str {
|
||||
match *self {
|
||||
Isa::Riscv => "riscv",
|
||||
Isa::X86 => "x86",
|
||||
Isa::Arm32 => "arm32",
|
||||
Isa::Arm64 => "arm64",
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if arch is applicable for the isa target.
|
||||
fn is_arch_applicable(&self, arch: &str) -> bool {
|
||||
match *self {
|
||||
@@ -51,3 +49,27 @@ impl Isa {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Isa {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Isa::Riscv => write!(f, "riscv"),
|
||||
Isa::X86 => write!(f, "x86"),
|
||||
Isa::Arm32 => write!(f, "arm32"),
|
||||
Isa::Arm64 => write!(f, "arm64"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn define_all() -> Vec<TargetIsa> {
|
||||
let isas = vec![
|
||||
riscv::define(),
|
||||
arm32::define(),
|
||||
arm64::define(),
|
||||
x86::define(),
|
||||
];
|
||||
for isa in isas.iter() {
|
||||
isa.check();
|
||||
}
|
||||
isas
|
||||
}
|
||||
|
||||
24
lib/codegen/meta/src/isa/riscv/mod.rs
Normal file
24
lib/codegen/meta/src/isa/riscv/mod.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use cdsl::regs::{RegBankBuilder, RegClassBuilder};
|
||||
use isa;
|
||||
|
||||
pub fn define() -> isa::TargetIsa {
|
||||
let mut isa = isa::TargetIsa::new("riscv");
|
||||
|
||||
let builder = RegBankBuilder::new("IntRegs", "x")
|
||||
.units(32)
|
||||
.track_pressure(true);
|
||||
let int_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FloatRegs", "f")
|
||||
.units(32)
|
||||
.track_pressure(true);
|
||||
let float_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "GPR", int_regs);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FPR", float_regs);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
isa
|
||||
}
|
||||
43
lib/codegen/meta/src/isa/x86/mod.rs
Normal file
43
lib/codegen/meta/src/isa/x86/mod.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use cdsl::regs::{RegBankBuilder, RegClassBuilder};
|
||||
use isa;
|
||||
|
||||
pub fn define() -> isa::TargetIsa {
|
||||
let mut isa = isa::TargetIsa::new("x86");
|
||||
|
||||
let builder = RegBankBuilder::new("IntRegs", "r")
|
||||
.units(16)
|
||||
.names(vec!["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"])
|
||||
.track_pressure(true);
|
||||
let int_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FloatRegs", "xmm")
|
||||
.units(16)
|
||||
.track_pressure(true);
|
||||
let float_regs = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegBankBuilder::new("FlagRegs", "")
|
||||
.units(1)
|
||||
.names(vec!["rflags"])
|
||||
.track_pressure(false);
|
||||
let flag_reg = isa.add_reg_bank(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "GPR", int_regs);
|
||||
let gpr = isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FPR", float_regs);
|
||||
let fpr = isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::new_toplevel(&mut isa, "FLAG", flag_reg);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::subclass_of(&mut isa, "GPR8", gpr, 0, 8);
|
||||
let gpr8 = isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::subclass_of(&mut isa, "ABCD", gpr8, 0, 4);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
let builder = RegClassBuilder::subclass_of(&mut isa, "FPR8", fpr, 0, 8);
|
||||
isa.add_reg_class(builder);
|
||||
|
||||
isa
|
||||
}
|
||||
Reference in New Issue
Block a user