1 use crate::cdsl::cpu_modes::CpuMode;
2 use crate::cdsl::instructions::InstructionGroupBuilder;
3 use crate::cdsl::isa::TargetIsa;
4 use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
5 use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
6 
7 use crate::shared::types::Float::{F32, F64};
8 use crate::shared::types::Int::{I32, I64};
9 use crate::shared::Definitions as SharedDefinitions;
10 
11 mod encodings;
12 mod recipes;
13 
define_settings(shared: &SettingGroup) -> SettingGroup14 fn define_settings(shared: &SettingGroup) -> SettingGroup {
15     let mut setting = SettingGroupBuilder::new("riscv");
16 
17     let supports_m = setting.add_bool(
18         "supports_m",
19         "CPU supports the 'M' extension (mul/div)",
20         false,
21     );
22     let supports_a = setting.add_bool(
23         "supports_a",
24         "CPU supports the 'A' extension (atomics)",
25         false,
26     );
27     let supports_f = setting.add_bool(
28         "supports_f",
29         "CPU supports the 'F' extension (float)",
30         false,
31     );
32     let supports_d = setting.add_bool(
33         "supports_d",
34         "CPU supports the 'D' extension (double)",
35         false,
36     );
37 
38     let enable_m = setting.add_bool(
39         "enable_m",
40         "Enable the use of 'M' instructions if available",
41         true,
42     );
43 
44     setting.add_bool(
45         "enable_e",
46         "Enable the 'RV32E' instruction set with only 16 registers",
47         false,
48     );
49 
50     let shared_enable_atomics = shared.get_bool("enable_atomics");
51     let shared_enable_float = shared.get_bool("enable_float");
52     let shared_enable_simd = shared.get_bool("enable_simd");
53 
54     setting.add_predicate("use_m", predicate!(supports_m && enable_m));
55     setting.add_predicate("use_a", predicate!(supports_a && shared_enable_atomics));
56     setting.add_predicate("use_f", predicate!(supports_f && shared_enable_float));
57     setting.add_predicate("use_d", predicate!(supports_d && shared_enable_float));
58     setting.add_predicate(
59         "full_float",
60         predicate!(shared_enable_simd && supports_f && supports_d),
61     );
62 
63     setting.build()
64 }
65 
define_registers() -> IsaRegs66 fn define_registers() -> IsaRegs {
67     let mut regs = IsaRegsBuilder::new();
68 
69     let builder = RegBankBuilder::new("IntRegs", "x")
70         .units(32)
71         .track_pressure(true);
72     let int_regs = regs.add_bank(builder);
73 
74     let builder = RegBankBuilder::new("FloatRegs", "f")
75         .units(32)
76         .track_pressure(true);
77     let float_regs = regs.add_bank(builder);
78 
79     let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
80     regs.add_class(builder);
81 
82     let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
83     regs.add_class(builder);
84 
85     regs.build()
86 }
87 
define(shared_defs: &mut SharedDefinitions) -> TargetIsa88 pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
89     let settings = define_settings(&shared_defs.settings);
90     let regs = define_registers();
91 
92     let inst_group = InstructionGroupBuilder::new(&mut shared_defs.all_instructions).build();
93 
94     // CPU modes for 32-bit and 64-bit operation.
95     let mut rv_32 = CpuMode::new("RV32");
96     let mut rv_64 = CpuMode::new("RV64");
97 
98     let expand = shared_defs.transform_groups.by_name("expand");
99     let narrow_no_flags = shared_defs.transform_groups.by_name("narrow_no_flags");
100 
101     rv_32.legalize_monomorphic(expand);
102     rv_32.legalize_default(narrow_no_flags);
103     rv_32.legalize_type(I32, expand);
104     rv_32.legalize_type(F32, expand);
105     rv_32.legalize_type(F64, expand);
106 
107     rv_64.legalize_monomorphic(expand);
108     rv_64.legalize_default(narrow_no_flags);
109     rv_64.legalize_type(I32, expand);
110     rv_64.legalize_type(I64, expand);
111     rv_64.legalize_type(F32, expand);
112     rv_64.legalize_type(F64, expand);
113 
114     let recipes = recipes::define(shared_defs, &regs);
115 
116     let encodings = encodings::define(shared_defs, &settings, &recipes);
117     rv_32.set_encodings(encodings.enc32);
118     rv_64.set_encodings(encodings.enc64);
119     let encodings_predicates = encodings.inst_pred_reg.extract();
120 
121     let recipes = recipes.collect();
122 
123     let cpu_modes = vec![rv_32, rv_64];
124 
125     TargetIsa::new(
126         "riscv",
127         inst_group,
128         settings,
129         regs,
130         recipes,
131         cpu_modes,
132         encodings_predicates,
133     )
134 }
135