1 //! This crate generates Rust sources for use by
2 //! [`cranelift_codegen`](../cranelift_codegen/index.html).
3 
4 use shared::Definitions;
5 
6 #[macro_use]
7 mod cdsl;
8 mod srcgen;
9 
10 pub mod error;
11 pub mod isa;
12 pub mod isle;
13 
14 mod gen_inst;
15 mod gen_isle;
16 mod gen_settings;
17 mod gen_types;
18 
19 mod constant_hash;
20 mod shared;
21 mod unique_table;
22 
23 #[cfg(feature = "pulley")]
24 mod pulley;
25 
26 /// Generate an ISA from an architecture string (e.g. "x86_64").
27 pub fn isa_from_arch(arch: &str) -> Result<isa::Isa, String> {
28     isa::Isa::from_arch(arch).ok_or_else(|| format!("no supported isa found for arch `{arch}`"))
29 }
30 
31 /// Generates all the Rust source files used in Cranelift from the meta-language.
32 pub fn generate_rust(isas: &[isa::Isa], out_dir: &std::path::Path) -> Result<(), error::Error> {
33     let shared_defs = shared::define();
34     generate_rust_for_shared_defs(&shared_defs, isas, out_dir)
35 }
36 
37 fn generate_rust_for_shared_defs(
38     shared_defs: &Definitions,
39     isas: &[isa::Isa],
40     out_dir: &std::path::Path,
41 ) -> Result<(), error::Error> {
42     gen_settings::generate(
43         &shared_defs.settings,
44         gen_settings::ParentGroup::None,
45         "settings.rs",
46         out_dir,
47     )?;
48 
49     gen_types::generate("types.rs", out_dir)?;
50 
51     gen_inst::generate(
52         &shared_defs.all_formats,
53         &shared_defs.all_instructions,
54         "opcodes.rs",
55         "inst_builder.rs",
56         out_dir,
57     )?;
58 
59     // Per ISA definitions.
60     for isa in isa::define(isas) {
61         gen_settings::generate(
62             &isa.settings,
63             gen_settings::ParentGroup::Shared,
64             &format!("settings-{}.rs", isa.name),
65             out_dir,
66         )?;
67     }
68 
69     #[cfg(feature = "pulley")]
70     if isas.contains(&isa::Isa::Pulley32) || isas.contains(&isa::Isa::Pulley64) {
71         pulley::generate_rust("pulley_inst_gen.rs", out_dir)?;
72     }
73 
74     Ok(())
75 }
76 
77 /// Generates all the ISLE source files used in Cranelift from the meta-language.
78 pub fn generate_isle(isle_dir: &std::path::Path) -> Result<(), error::Error> {
79     let shared_defs = shared::define();
80     generate_isle_for_shared_defs(&shared_defs, isle_dir)
81 }
82 
83 fn generate_isle_for_shared_defs(
84     shared_defs: &Definitions,
85     isle_dir: &std::path::Path,
86 ) -> Result<(), error::Error> {
87     gen_isle::generate(
88         &shared_defs.all_formats,
89         &shared_defs.all_instructions,
90         "clif_opt.isle",
91         "clif_lower.isle",
92         isle_dir,
93     )?;
94 
95     #[cfg(feature = "pulley")]
96     pulley::generate_isle("pulley_gen.isle", isle_dir)?;
97 
98     Ok(())
99 }
100 
101 /// Generates all the source files used in Cranelift from the meta-language.
102 pub fn generate(
103     isas: &[isa::Isa],
104     out_dir: &std::path::Path,
105     isle_dir: &std::path::Path,
106 ) -> Result<(), error::Error> {
107     let shared_defs = shared::define();
108     generate_rust_for_shared_defs(&shared_defs, isas, out_dir)?;
109     generate_isle_for_shared_defs(&shared_defs, isle_dir)?;
110     Ok(())
111 }
112