1use std::io::Result;
2
3#[derive(Clone, Debug)]
12pub struct IsleCompilations {
13 pub items: Vec<IsleCompilation>,
14}
15
16impl IsleCompilations {
17 pub fn lookup(&self, name: &str) -> Option<&IsleCompilation> {
18 for compilation in &self.items {
19 if compilation.name == name {
20 return Some(compilation);
21 }
22 }
23 None
24 }
25}
26
27#[derive(Clone, Debug)]
28pub struct IsleCompilation {
29 pub name: String,
30 pub output: std::path::PathBuf,
31 pub tracked_inputs: Vec<std::path::PathBuf>,
32 pub untracked_inputs: Vec<std::path::PathBuf>,
33}
34
35impl IsleCompilation {
36 pub fn inputs(&self) -> Vec<std::path::PathBuf> {
38 self.tracked_inputs
39 .iter()
40 .chain(self.untracked_inputs.iter())
41 .cloned()
42 .collect()
43 }
44
45 pub fn paths(&self) -> Result<Vec<std::path::PathBuf>> {
48 let mut paths = Vec::new();
49 for input in self.inputs() {
50 paths.extend(Self::expand_paths(&input)?);
51 }
52 Ok(paths)
53 }
54
55 fn expand_paths(input: &std::path::PathBuf) -> Result<Vec<std::path::PathBuf>> {
56 if input.is_file() {
57 return Ok(vec![input.clone()]);
58 }
59
60 if !input.exists() {
61 return Err(std::io::Error::new(
62 std::io::ErrorKind::NotFound,
63 format!("ISLE input does not exist: {}", input.display()),
64 ));
65 }
66
67 let mut paths = Vec::new();
68 for entry in std::fs::read_dir(input).map_err(|e| {
69 std::io::Error::new(
70 e.kind(),
71 format!(
72 "failed to read ISLE input directory {}: {e}",
73 input.display()
74 ),
75 )
76 })? {
77 let path = entry?.path();
78 if let Some(ext) = path.extension() {
79 if ext == "isle" {
80 paths.push(path);
81 }
82 }
83 }
84 Ok(paths)
85 }
86}
87
88pub fn shared_isle_lower_paths(codegen_crate_dir: &std::path::Path) -> Vec<std::path::PathBuf> {
89 let inst_specs_isle = codegen_crate_dir.join("src").join("inst_specs.isle");
90 let prelude_isle = codegen_crate_dir.join("src").join("prelude.isle");
91 let prelude_lower_isle = codegen_crate_dir.join("src").join("prelude_lower.isle");
92 vec![
94 inst_specs_isle.clone(),
95 prelude_isle.clone(),
96 prelude_lower_isle.clone(),
97 ]
98}
99
100pub fn get_isle_compilations(
103 codegen_crate_dir: &std::path::Path,
104 gen_dir: &std::path::Path,
105) -> IsleCompilations {
106 let numerics_isle = gen_dir.join("numerics.isle");
108 let clif_lower_isle = gen_dir.join("clif_lower.isle");
109 let clif_opt_isle = gen_dir.join("clif_opt.isle");
110 let prelude_isle = codegen_crate_dir.join("src").join("prelude.isle");
111 let prelude_opt_isle = codegen_crate_dir.join("src").join("prelude_opt.isle");
112 let prelude_lower_isle = codegen_crate_dir.join("src").join("prelude_lower.isle");
113 #[cfg(feature = "pulley")]
114 let pulley_gen = gen_dir.join("pulley_gen.isle");
115
116 let spec_inputs = |extra: &[&str]| -> Vec<std::path::PathBuf> {
121 if !cfg!(feature = "spec") {
122 return vec![];
123 }
124 let spec_dir = codegen_crate_dir.join("src").join("spec");
125 let mut inputs = vec![
126 spec_dir.join("prelude_spec.isle"),
127 spec_dir.join("inst_specs.isle"),
128 spec_dir.join("inst_tags.isle"),
129 ];
130 inputs.extend(extra.iter().map(|f| spec_dir.join(f)));
131 inputs
132 };
133 let lower_spec_inputs = |extra: &[&str]| -> Vec<std::path::PathBuf> {
134 let mut inputs = spec_inputs(extra);
135 if cfg!(feature = "spec") {
136 let spec_dir = codegen_crate_dir.join("src").join("spec");
137 inputs.push(spec_dir.join("prelude_lower_spec.isle"));
138 }
139 inputs
140 };
141
142 let src_opts = codegen_crate_dir.join("src").join("opts");
144
145 let src_isa_x64 = codegen_crate_dir.join("src").join("isa").join("x64");
147 let src_isa_aarch64 = codegen_crate_dir.join("src").join("isa").join("aarch64");
148 let src_isa_s390x = codegen_crate_dir.join("src").join("isa").join("s390x");
149 let src_isa_risc_v = codegen_crate_dir.join("src").join("isa").join("riscv64");
150 #[cfg(feature = "pulley")]
151 let src_isa_pulley_shared = codegen_crate_dir
152 .join("src")
153 .join("isa")
154 .join("pulley_shared");
155
156 IsleCompilations {
170 items: vec![
171 IsleCompilation {
173 name: "opt".to_string(),
174 output: gen_dir.join("isle_opt.rs"),
175 tracked_inputs: [
176 vec![prelude_isle.clone(), prelude_opt_isle],
177 spec_inputs(&["fpconst.isle", "opt.isle"]),
178 vec![
179 src_opts.join("arithmetic.isle"),
180 src_opts.join("bitops.isle"),
181 src_opts.join("cprop.isle"),
182 src_opts.join("extends.isle"),
183 src_opts.join("icmp.isle"),
184 src_opts.join("remat.isle"),
185 src_opts.join("selects.isle"),
186 src_opts.join("shifts.isle"),
187 src_opts.join("skeleton.isle"),
188 src_opts.join("spaceship.isle"),
189 src_opts.join("spectre.isle"),
190 src_opts.join("vector.isle"),
191 ],
192 ]
193 .concat(),
194 untracked_inputs: vec![numerics_isle.clone(), clif_opt_isle],
195 },
196 IsleCompilation {
198 name: "x64".to_string(),
199 output: gen_dir.join("isle_x64.rs"),
200 tracked_inputs: [
201 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
202 lower_spec_inputs(&["fpconst.isle", "state.isle"]),
203 vec![
204 src_isa_x64.join("inst.isle"),
205 src_isa_x64.join("lower.isle"),
206 ],
207 ]
208 .concat(),
209 untracked_inputs: vec![
210 numerics_isle.clone(),
211 clif_lower_isle.clone(),
212 gen_dir.join("assembler.isle"),
213 ],
214 },
215 IsleCompilation {
217 name: "aarch64".to_string(),
218 output: gen_dir.join("isle_aarch64.rs"),
219 tracked_inputs: [
220 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
221 lower_spec_inputs(&["fpconst.isle", "state.isle"]),
222 vec![
223 src_isa_aarch64.join("inst.isle"),
224 src_isa_aarch64.join("inst_neon.isle"),
225 ],
226 if cfg!(feature = "spec") {
228 vec![src_isa_aarch64.join("spec")]
229 } else {
230 vec![]
231 },
232 vec![
233 src_isa_aarch64.join("lower.isle"),
234 src_isa_aarch64.join("lower_dynamic_neon.isle"),
235 ],
236 ]
237 .concat(),
238 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
239 },
240 IsleCompilation {
242 name: "s390x".to_string(),
243 output: gen_dir.join("isle_s390x.rs"),
244 tracked_inputs: [
245 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
246 lower_spec_inputs(&[]),
247 vec![
248 src_isa_s390x.join("inst.isle"),
249 src_isa_s390x.join("lower.isle"),
250 ],
251 ]
252 .concat(),
253 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
254 },
255 IsleCompilation {
257 name: "riscv64".to_string(),
258 output: gen_dir.join("isle_riscv64.rs"),
259 tracked_inputs: [
260 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
261 lower_spec_inputs(&[]),
262 vec![
263 src_isa_risc_v.join("inst.isle"),
264 src_isa_risc_v.join("inst_vector.isle"),
265 src_isa_risc_v.join("lower.isle"),
266 ],
267 ]
268 .concat(),
269 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
270 },
271 #[cfg(feature = "pulley")]
273 IsleCompilation {
274 name: "pulley".to_string(),
275 output: gen_dir.join("isle_pulley_shared.rs"),
276 tracked_inputs: vec![
277 prelude_isle.clone(),
278 prelude_lower_isle.clone(),
279 src_isa_pulley_shared.join("inst.isle"),
280 src_isa_pulley_shared.join("lower.isle"),
281 ],
282 untracked_inputs: vec![
283 numerics_isle.clone(),
284 pulley_gen.clone(),
285 clif_lower_isle.clone(),
286 ],
287 },
288 ],
289 }
290}