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_binemit; 11 mod gen_encodings; 12 mod gen_inst; 13 mod gen_legalizer; 14 mod gen_registers; 15 mod gen_settings; 16 mod gen_types; 17 18 mod default_map; 19 mod shared; 20 mod unique_table; 21 22 /// Generate an ISA from an architecture string (e.g. "x86_64"). 23 pub fn isa_from_arch(arch: &str) -> Result<isa::Isa, String> { 24 isa::Isa::from_arch(arch).ok_or_else(|| format!("no supported isa found for arch `{}`", arch)) 25 } 26 27 /// Generates all the Rust source files used in Cranelift from the meta-language. 28 pub fn generate( 29 old_backend_isas: &[isa::Isa], 30 new_backend_isas: &[isa::Isa], 31 out_dir: &str, 32 ) -> Result<(), error::Error> { 33 // Create all the definitions: 34 // - common definitions. 35 let mut shared_defs = shared::define(); 36 37 gen_settings::generate( 38 &shared_defs.settings, 39 gen_settings::ParentGroup::None, 40 "settings.rs", 41 &out_dir, 42 )?; 43 gen_types::generate("types.rs", &out_dir)?; 44 45 // - per ISA definitions. 46 let target_isas = isa::define(old_backend_isas, &mut shared_defs); 47 48 // At this point, all definitions are done. 49 let all_formats = shared_defs.verify_instruction_formats(); 50 51 // Generate all the code. 52 gen_inst::generate( 53 all_formats, 54 &shared_defs.all_instructions, 55 "opcodes.rs", 56 "inst_builder.rs", 57 &out_dir, 58 )?; 59 60 let extra_legalization_groups: &[&'static str] = if !new_backend_isas.is_empty() { 61 // The new backend only requires the "expand" legalization group. 62 &["expand"] 63 } else { 64 &[] 65 }; 66 67 gen_legalizer::generate( 68 &target_isas, 69 &shared_defs.transform_groups, 70 extra_legalization_groups, 71 "legalize", 72 &out_dir, 73 )?; 74 75 for isa in target_isas { 76 gen_registers::generate(&isa, &format!("registers-{}.rs", isa.name), &out_dir)?; 77 78 gen_settings::generate( 79 &isa.settings, 80 gen_settings::ParentGroup::Shared, 81 &format!("settings-{}.rs", isa.name), 82 &out_dir, 83 )?; 84 85 gen_encodings::generate( 86 &shared_defs, 87 &isa, 88 &format!("encoding-{}.rs", isa.name), 89 &out_dir, 90 )?; 91 92 gen_binemit::generate( 93 &isa.name, 94 &isa.recipes, 95 &format!("binemit-{}.rs", isa.name), 96 &out_dir, 97 )?; 98 } 99 100 for isa in new_backend_isas { 101 match isa { 102 isa::Isa::X86 => { 103 // If the old backend ISAs contained x86, this file has already been generated. 104 if old_backend_isas.iter().any(|isa| *isa == isa::Isa::X86) { 105 continue; 106 } 107 108 let settings = crate::isa::x86::settings::define(&shared_defs.settings); 109 gen_settings::generate( 110 &settings, 111 gen_settings::ParentGroup::Shared, 112 "settings-x86.rs", 113 &out_dir, 114 )?; 115 } 116 isa::Isa::Arm64 => { 117 // aarch64 doesn't have platform-specific settings. 118 } 119 isa::Isa::S390x => { 120 // s390x doesn't have platform-specific settings. 121 } 122 isa::Isa::Arm32 | isa::Isa::Riscv => todo!(), 123 } 124 } 125 126 Ok(()) 127 } 128