1 //! This crate generates Rust sources for use by
2 //! [`cranelift_codegen`](../cranelift_codegen/index.html).
3 #[macro_use]
4 mod cdsl;
5 mod srcgen;
6 
7 pub mod error;
8 pub mod isa;
9 
10 mod gen_inst;
11 mod gen_settings;
12 mod gen_types;
13 
14 mod default_map;
15 mod shared;
16 mod unique_table;
17 
18 /// Generate an ISA from an architecture string (e.g. "x86_64").
19 pub fn isa_from_arch(arch: &str) -> Result<isa::Isa, String> {
20     isa::Isa::from_arch(arch).ok_or_else(|| format!("no supported isa found for arch `{}`", arch))
21 }
22 
23 /// Generates all the Rust source files used in Cranelift from the meta-language.
24 pub fn generate(
25     old_backend_isas: &[isa::Isa],
26     new_backend_isas: &[isa::Isa],
27     out_dir: &str,
28 ) -> Result<(), error::Error> {
29     // Create all the definitions:
30     // - common definitions.
31     let mut shared_defs = shared::define();
32 
33     gen_settings::generate(
34         &shared_defs.settings,
35         gen_settings::ParentGroup::None,
36         "settings.rs",
37         &out_dir,
38     )?;
39     gen_types::generate("types.rs", &out_dir)?;
40 
41     // - per ISA definitions.
42     let target_isas = isa::define(old_backend_isas, &mut shared_defs);
43 
44     // At this point, all definitions are done.
45     let all_formats = shared_defs.verify_instruction_formats();
46 
47     // Generate all the code.
48     gen_inst::generate(
49         all_formats,
50         &shared_defs.all_instructions,
51         "opcodes.rs",
52         "inst_builder.rs",
53         &out_dir,
54     )?;
55 
56     for isa in target_isas {
57         gen_settings::generate(
58             &isa.settings,
59             gen_settings::ParentGroup::Shared,
60             &format!("settings-{}.rs", isa.name),
61             &out_dir,
62         )?;
63     }
64 
65     for isa in new_backend_isas {
66         match isa {
67             isa::Isa::X86 => {
68                 // If the old backend ISAs contained x86, this file has already been generated.
69                 if old_backend_isas.iter().any(|isa| *isa == isa::Isa::X86) {
70                     continue;
71                 }
72 
73                 let settings = crate::isa::x86::define_settings(&shared_defs.settings);
74                 gen_settings::generate(
75                     &settings,
76                     gen_settings::ParentGroup::Shared,
77                     "settings-x86.rs",
78                     &out_dir,
79                 )?;
80             }
81             isa::Isa::Arm64 => {
82                 // aarch64 doesn't have platform-specific settings.
83             }
84             isa::Isa::S390x => {
85                 // s390x doesn't have platform-specific settings.
86             }
87             isa::Isa::Arm32 => todo!(),
88         }
89     }
90 
91     Ok(())
92 }
93