120 lines
3.7 KiB
Rust
120 lines
3.7 KiB
Rust
use crate::cdsl::cpu_modes::CpuMode;
|
|
use crate::cdsl::instructions::InstructionGroupBuilder;
|
|
use crate::cdsl::isa::TargetIsa;
|
|
use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
|
|
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;
|
|
|
|
fn define_settings(shared: &SettingGroup) -> SettingGroup {
|
|
let mut setting = SettingGroupBuilder::new("riscv");
|
|
|
|
let supports_m = setting.add_bool(
|
|
"supports_m",
|
|
"CPU supports the 'M' extension (mul/div)",
|
|
false,
|
|
);
|
|
let supports_a = setting.add_bool(
|
|
"supports_a",
|
|
"CPU supports the 'A' extension (atomics)",
|
|
false,
|
|
);
|
|
let supports_f = setting.add_bool(
|
|
"supports_f",
|
|
"CPU supports the 'F' extension (float)",
|
|
false,
|
|
);
|
|
let supports_d = setting.add_bool(
|
|
"supports_d",
|
|
"CPU supports the 'D' extension (double)",
|
|
false,
|
|
);
|
|
|
|
let enable_m = setting.add_bool(
|
|
"enable_m",
|
|
"Enable the use of 'M' instructions if available",
|
|
true,
|
|
);
|
|
|
|
setting.add_bool(
|
|
"enable_e",
|
|
"Enable the 'RV32E' instruction set with only 16 registers",
|
|
false,
|
|
);
|
|
|
|
let shared_enable_atomics = shared.get_bool("enable_atomics");
|
|
let shared_enable_float = shared.get_bool("enable_float");
|
|
let shared_enable_simd = shared.get_bool("enable_simd");
|
|
|
|
setting.add_predicate("use_m", predicate!(supports_m && enable_m));
|
|
setting.add_predicate("use_a", predicate!(supports_a && shared_enable_atomics));
|
|
setting.add_predicate("use_f", predicate!(supports_f && shared_enable_float));
|
|
setting.add_predicate("use_d", predicate!(supports_d && shared_enable_float));
|
|
setting.add_predicate(
|
|
"full_float",
|
|
predicate!(shared_enable_simd && supports_f && supports_d),
|
|
);
|
|
|
|
setting.build()
|
|
}
|
|
|
|
fn define_registers() -> IsaRegs {
|
|
let mut regs = IsaRegsBuilder::new();
|
|
|
|
let builder = RegBankBuilder::new("IntRegs", "x")
|
|
.units(32)
|
|
.track_pressure(true);
|
|
let int_regs = regs.add_bank(builder);
|
|
|
|
let builder = RegBankBuilder::new("FloatRegs", "f")
|
|
.units(32)
|
|
.track_pressure(true);
|
|
let float_regs = regs.add_bank(builder);
|
|
|
|
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
|
|
regs.add_class(builder);
|
|
|
|
let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
|
|
regs.add_class(builder);
|
|
|
|
regs.build()
|
|
}
|
|
|
|
pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
|
|
let settings = define_settings(&shared_defs.settings);
|
|
let regs = define_registers();
|
|
|
|
let inst_group = InstructionGroupBuilder::new(
|
|
"riscv",
|
|
"riscv specific instruction set",
|
|
&mut shared_defs.all_instructions,
|
|
&shared_defs.format_registry,
|
|
)
|
|
.build();
|
|
|
|
// 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)
|
|
}
|