1f1945664SAndrew Brown //! This crate generates Rust sources for use by
2f1945664SAndrew Brown //! [`cranelift_codegen`](../cranelift_codegen/index.html).
3d377b665SNick Fitzgerald 
490ac295eSAlex Crichton use cranelift_srcgen::{Formatter, Language, error};
547d1640eSMichael McLoughlin use shared::Definitions;
647d1640eSMichael McLoughlin 
7747ad3c4Slazypassion #[macro_use]
8747ad3c4Slazypassion mod cdsl;
9747ad3c4Slazypassion 
10747ad3c4Slazypassion pub mod isa;
114b9f53a9SMichael McLoughlin pub mod isle;
12747ad3c4Slazypassion 
13bce7f205SAndrew Brown mod gen_asm;
14b5595aadSBenjamin Bouvier mod gen_inst;
1547d1640eSMichael McLoughlin mod gen_isle;
1625fdda61SBenjamin Bouvier mod gen_settings;
1725fdda61SBenjamin Bouvier mod gen_types;
1825fdda61SBenjamin Bouvier 
1991d4f369Sbjorn3 mod constant_hash;
20f78a61b9SBenjamin Bouvier mod shared;
21747ad3c4Slazypassion mod unique_table;
2225fdda61SBenjamin Bouvier 
23c6658769SAlex Crichton #[cfg(feature = "pulley")]
24c6658769SAlex Crichton mod pulley;
25c6658769SAlex Crichton 
26f1945664SAndrew Brown /// Generate an ISA from an architecture string (e.g. "x86_64").
isa_from_arch(arch: &str) -> Result<isa::Isa, String>27a45b814dSBenjamin Bouvier pub fn isa_from_arch(arch: &str) -> Result<isa::Isa, String> {
28a0442ea0SHamir Mahal     isa::Isa::from_arch(arch).ok_or_else(|| format!("no supported isa found for arch `{arch}`"))
2925fdda61SBenjamin Bouvier }
3025fdda61SBenjamin Bouvier 
3125fdda61SBenjamin Bouvier /// Generates all the Rust source files used in Cranelift from the meta-language.
generate_rust(isas: &[isa::Isa], out_dir: &std::path::Path) -> Result<(), error::Error>3247d1640eSMichael McLoughlin pub fn generate_rust(isas: &[isa::Isa], out_dir: &std::path::Path) -> Result<(), error::Error> {
337e66ed24Sbjorn3     let shared_defs = shared::define();
3447d1640eSMichael McLoughlin     generate_rust_for_shared_defs(&shared_defs, isas, out_dir)
3547d1640eSMichael McLoughlin }
3625fdda61SBenjamin Bouvier 
generate_rust_for_shared_defs( shared_defs: &Definitions, isas: &[isa::Isa], out_dir: &std::path::Path, ) -> Result<(), error::Error>3747d1640eSMichael McLoughlin fn generate_rust_for_shared_defs(
3847d1640eSMichael McLoughlin     shared_defs: &Definitions,
3947d1640eSMichael McLoughlin     isas: &[isa::Isa],
4047d1640eSMichael McLoughlin     out_dir: &std::path::Path,
4147d1640eSMichael McLoughlin ) -> Result<(), error::Error> {
42f3f449b4SBenjamin Bouvier     gen_settings::generate(
433c31eac4SBenjamin Bouvier         &shared_defs.settings,
44f3f449b4SBenjamin Bouvier         gen_settings::ParentGroup::None,
45d6059d46SBenjamin Bouvier         "settings.rs",
4685118c8cSkevaundray         out_dir,
47f3f449b4SBenjamin Bouvier     )?;
4847d1640eSMichael McLoughlin 
4985118c8cSkevaundray     gen_types::generate("types.rs", out_dir)?;
5025fdda61SBenjamin Bouvier 
510243b642SBenjamin Bouvier     gen_inst::generate(
527e66ed24Sbjorn3         &shared_defs.all_formats,
530243b642SBenjamin Bouvier         &shared_defs.all_instructions,
540243b642SBenjamin Bouvier         "opcodes.rs",
550243b642SBenjamin Bouvier         "inst_builder.rs",
5685118c8cSkevaundray         out_dir,
570243b642SBenjamin Bouvier     )?;
58b5595aadSBenjamin Bouvier 
597e66ed24Sbjorn3     // Per ISA definitions.
607e66ed24Sbjorn3     for isa in isa::define(isas) {
61f3f449b4SBenjamin Bouvier         gen_settings::generate(
62f3f449b4SBenjamin Bouvier             &isa.settings,
63f3f449b4SBenjamin Bouvier             gen_settings::ParentGroup::Shared,
64d6059d46SBenjamin Bouvier             &format!("settings-{}.rs", isa.name),
6585118c8cSkevaundray             out_dir,
66f3f449b4SBenjamin Bouvier         )?;
6725fdda61SBenjamin Bouvier     }
6825fdda61SBenjamin Bouvier 
69c6658769SAlex Crichton     #[cfg(feature = "pulley")]
70c6658769SAlex Crichton     if isas.contains(&isa::Isa::Pulley32) || isas.contains(&isa::Isa::Pulley64) {
71c6658769SAlex Crichton         pulley::generate_rust("pulley_inst_gen.rs", out_dir)?;
72c6658769SAlex Crichton     }
73c6658769SAlex Crichton 
7425fdda61SBenjamin Bouvier     Ok(())
7525fdda61SBenjamin Bouvier }
7647d1640eSMichael McLoughlin 
7747d1640eSMichael McLoughlin /// Generates all the ISLE source files used in Cranelift from the meta-language.
generate_isle(isle_dir: &std::path::Path) -> Result<(), error::Error>7847d1640eSMichael McLoughlin pub fn generate_isle(isle_dir: &std::path::Path) -> Result<(), error::Error> {
7947d1640eSMichael McLoughlin     let shared_defs = shared::define();
8047d1640eSMichael McLoughlin     generate_isle_for_shared_defs(&shared_defs, isle_dir)
8147d1640eSMichael McLoughlin }
8247d1640eSMichael McLoughlin 
generate_isle_for_shared_defs( shared_defs: &Definitions, isle_dir: &std::path::Path, ) -> Result<(), error::Error>8347d1640eSMichael McLoughlin fn generate_isle_for_shared_defs(
8447d1640eSMichael McLoughlin     shared_defs: &Definitions,
8547d1640eSMichael McLoughlin     isle_dir: &std::path::Path,
8647d1640eSMichael McLoughlin ) -> Result<(), error::Error> {
8747d1640eSMichael McLoughlin     gen_isle::generate(
8847d1640eSMichael McLoughlin         &shared_defs.all_formats,
8947d1640eSMichael McLoughlin         &shared_defs.all_instructions,
90*cfe17cb1SNick Fitzgerald         "numerics.isle",
91*cfe17cb1SNick Fitzgerald         "isle_numerics.rs",
9247d1640eSMichael McLoughlin         "clif_opt.isle",
9347d1640eSMichael McLoughlin         "clif_lower.isle",
9447d1640eSMichael McLoughlin         isle_dir,
95c6658769SAlex Crichton     )?;
96c6658769SAlex Crichton 
97c6658769SAlex Crichton     #[cfg(feature = "pulley")]
98c6658769SAlex Crichton     pulley::generate_isle("pulley_gen.isle", isle_dir)?;
99c6658769SAlex Crichton 
100c6658769SAlex Crichton     Ok(())
10147d1640eSMichael McLoughlin }
10247d1640eSMichael McLoughlin 
103bce7f205SAndrew Brown /// Generate the ISLE definitions; this provides ISLE glue to access the
104bce7f205SAndrew Brown /// assembler instructions in [cranelift_assembler_x64_meta].
generate_isle_for_assembler( insts: &[cranelift_assembler_x64_meta::dsl::Inst], isle_dir: &std::path::Path, ) -> Result<(), error::Error>105bce7f205SAndrew Brown fn generate_isle_for_assembler(
106bce7f205SAndrew Brown     insts: &[cranelift_assembler_x64_meta::dsl::Inst],
107bce7f205SAndrew Brown     isle_dir: &std::path::Path,
108bce7f205SAndrew Brown ) -> Result<(), error::Error> {
109bce7f205SAndrew Brown     let mut fmt = Formatter::new(Language::Isle);
110bce7f205SAndrew Brown     gen_asm::generate_isle(&mut fmt, insts);
111bce7f205SAndrew Brown     fmt.write("assembler.isle", isle_dir)
112bce7f205SAndrew Brown }
113bce7f205SAndrew Brown 
114bce7f205SAndrew Brown /// Generate a macro containing builder functions for the assembler's ISLE
115bce7f205SAndrew Brown /// constructors; this provides Rust implementations backing up the ISLE
116bce7f205SAndrew Brown /// definitions in [generate_isle_for_assembler].
generate_rust_macro_for_assembler( insts: &[cranelift_assembler_x64_meta::dsl::Inst], out_dir: &std::path::Path, ) -> Result<(), error::Error>117bce7f205SAndrew Brown fn generate_rust_macro_for_assembler(
118bce7f205SAndrew Brown     insts: &[cranelift_assembler_x64_meta::dsl::Inst],
119bce7f205SAndrew Brown     out_dir: &std::path::Path,
120bce7f205SAndrew Brown ) -> Result<(), error::Error> {
121bce7f205SAndrew Brown     let mut fmt = Formatter::new(Language::Rust);
122bce7f205SAndrew Brown     gen_asm::generate_rust_macro(&mut fmt, insts);
123bce7f205SAndrew Brown     fmt.write("assembler-isle-macro.rs", out_dir)
124bce7f205SAndrew Brown }
125bce7f205SAndrew Brown 
12647d1640eSMichael McLoughlin /// Generates all the source files used in Cranelift from the meta-language.
generate( isas: &[isa::Isa], out_dir: &std::path::Path, isle_dir: &std::path::Path, ) -> Result<(), error::Error>12747d1640eSMichael McLoughlin pub fn generate(
12847d1640eSMichael McLoughlin     isas: &[isa::Isa],
12947d1640eSMichael McLoughlin     out_dir: &std::path::Path,
13047d1640eSMichael McLoughlin     isle_dir: &std::path::Path,
13147d1640eSMichael McLoughlin ) -> Result<(), error::Error> {
13247d1640eSMichael McLoughlin     let shared_defs = shared::define();
13347d1640eSMichael McLoughlin     generate_rust_for_shared_defs(&shared_defs, isas, out_dir)?;
13447d1640eSMichael McLoughlin     generate_isle_for_shared_defs(&shared_defs, isle_dir)?;
135bce7f205SAndrew Brown 
136bce7f205SAndrew Brown     let insts = cranelift_assembler_x64_meta::instructions::list();
137bce7f205SAndrew Brown     generate_isle_for_assembler(&insts, isle_dir)?;
138bce7f205SAndrew Brown     generate_rust_macro_for_assembler(&insts, out_dir)?;
139bce7f205SAndrew Brown 
14047d1640eSMichael McLoughlin     Ok(())
14147d1640eSMichael McLoughlin }
142