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
134 let src_opts = codegen_crate_dir.join("src").join("opts");
136
137 let src_isa_x64 = codegen_crate_dir.join("src").join("isa").join("x64");
139 let src_isa_aarch64 = codegen_crate_dir.join("src").join("isa").join("aarch64");
140 let src_isa_s390x = codegen_crate_dir.join("src").join("isa").join("s390x");
141 let src_isa_risc_v = codegen_crate_dir.join("src").join("isa").join("riscv64");
142 #[cfg(feature = "pulley")]
143 let src_isa_pulley_shared = codegen_crate_dir
144 .join("src")
145 .join("isa")
146 .join("pulley_shared");
147
148 IsleCompilations {
162 items: vec![
163 IsleCompilation {
165 name: "opt".to_string(),
166 output: gen_dir.join("isle_opt.rs"),
167 tracked_inputs: [
168 vec![prelude_isle.clone(), prelude_opt_isle],
169 spec_inputs(&[]),
170 vec![
171 src_opts.join("arithmetic.isle"),
172 src_opts.join("bitops.isle"),
173 src_opts.join("cprop.isle"),
174 src_opts.join("extends.isle"),
175 src_opts.join("icmp.isle"),
176 src_opts.join("remat.isle"),
177 src_opts.join("selects.isle"),
178 src_opts.join("shifts.isle"),
179 src_opts.join("skeleton.isle"),
180 src_opts.join("spaceship.isle"),
181 src_opts.join("spectre.isle"),
182 src_opts.join("vector.isle"),
183 ],
184 ]
185 .concat(),
186 untracked_inputs: vec![numerics_isle.clone(), clif_opt_isle],
187 },
188 IsleCompilation {
190 name: "x64".to_string(),
191 output: gen_dir.join("isle_x64.rs"),
192 tracked_inputs: [
193 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
194 spec_inputs(&["state.isle"]),
195 vec![
196 src_isa_x64.join("inst.isle"),
197 src_isa_x64.join("lower.isle"),
198 ],
199 ]
200 .concat(),
201 untracked_inputs: vec![
202 numerics_isle.clone(),
203 clif_lower_isle.clone(),
204 gen_dir.join("assembler.isle"),
205 ],
206 },
207 IsleCompilation {
209 name: "aarch64".to_string(),
210 output: gen_dir.join("isle_aarch64.rs"),
211 tracked_inputs: [
212 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
213 spec_inputs(&["fpconst.isle", "state.isle"]),
214 vec![
215 src_isa_aarch64.join("inst.isle"),
216 src_isa_aarch64.join("inst_neon.isle"),
217 ],
218 if cfg!(feature = "spec") {
220 vec![src_isa_aarch64.join("spec")]
221 } else {
222 vec![]
223 },
224 vec![
225 src_isa_aarch64.join("lower.isle"),
226 src_isa_aarch64.join("lower_dynamic_neon.isle"),
227 ],
228 ]
229 .concat(),
230 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
231 },
232 IsleCompilation {
234 name: "s390x".to_string(),
235 output: gen_dir.join("isle_s390x.rs"),
236 tracked_inputs: [
237 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
238 spec_inputs(&[]),
239 vec![
240 src_isa_s390x.join("inst.isle"),
241 src_isa_s390x.join("lower.isle"),
242 ],
243 ]
244 .concat(),
245 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
246 },
247 IsleCompilation {
249 name: "riscv64".to_string(),
250 output: gen_dir.join("isle_riscv64.rs"),
251 tracked_inputs: [
252 vec![prelude_isle.clone(), prelude_lower_isle.clone()],
253 spec_inputs(&[]),
254 vec![
255 src_isa_risc_v.join("inst.isle"),
256 src_isa_risc_v.join("inst_vector.isle"),
257 src_isa_risc_v.join("lower.isle"),
258 ],
259 ]
260 .concat(),
261 untracked_inputs: vec![numerics_isle.clone(), clif_lower_isle.clone()],
262 },
263 #[cfg(feature = "pulley")]
265 IsleCompilation {
266 name: "pulley".to_string(),
267 output: gen_dir.join("isle_pulley_shared.rs"),
268 tracked_inputs: vec![
269 prelude_isle.clone(),
270 prelude_lower_isle.clone(),
271 src_isa_pulley_shared.join("inst.isle"),
272 src_isa_pulley_shared.join("lower.isle"),
273 ],
274 untracked_inputs: vec![
275 numerics_isle.clone(),
276 pulley_gen.clone(),
277 clif_lower_isle.clone(),
278 ],
279 },
280 ],
281 }
282}