Path: blob/main/cranelift/codegen/meta/src/shared/mod.rs
1693 views
//! Shared definitions for the Cranelift intermediate language.12pub mod entities;3pub mod formats;4pub mod immediates;5pub mod instructions;6pub mod settings;7pub mod types;89use crate::cdsl::formats::{FormatStructure, InstructionFormat};10use crate::cdsl::instructions::AllInstructions;11use crate::cdsl::settings::SettingGroup;1213use crate::shared::entities::EntityRefs;14use crate::shared::formats::Formats;15use crate::shared::immediates::Immediates;1617use std::collections::HashMap;18use std::rc::Rc;1920pub(crate) struct Definitions {21pub settings: SettingGroup,22pub all_instructions: AllInstructions,23pub all_formats: Vec<Rc<InstructionFormat>>,24}2526pub(crate) fn define() -> Definitions {27let mut all_instructions = AllInstructions::new();2829let immediates = Immediates::new();30let entities = EntityRefs::new();31let formats = Formats::new(&immediates, &entities);32instructions::define(&mut all_instructions, &formats, &immediates, &entities);33let all_formats = verify_instruction_formats(&all_instructions);3435Definitions {36settings: settings::define(),37all_instructions,38all_formats,39}40}4142/// Verifies certain properties of formats.43///44/// - Formats must be uniquely named: if two formats have the same name, they must refer to the45/// same data. Otherwise, two format variants in the codegen crate would have the same name.46/// - Formats must be structurally different from each other. Otherwise, this would lead to47/// code duplicate in the codegen crate.48///49/// Returns a list of all the instruction formats effectively used.50fn verify_instruction_formats(all_instructions: &AllInstructions) -> Vec<Rc<InstructionFormat>> {51let mut format_names: HashMap<&'static str, &Rc<InstructionFormat>> = HashMap::new();5253// A structure is: number of input value operands / whether there's varargs or not / names54// of immediate fields.55let mut format_structures: HashMap<FormatStructure, Rc<InstructionFormat>> = HashMap::new();5657for inst in all_instructions {58// Check name.59if let Some(existing_format) = format_names.get(&inst.format.name) {60assert!(61Rc::ptr_eq(existing_format, &inst.format),62"formats must uniquely named; there's a\63conflict on the name '{}', please make sure it is used only once.",64existing_format.name65);66} else {67format_names.insert(inst.format.name, &inst.format);68}6970// Check structure.71let key = inst.format.structure();72if let Some(existing_format) = format_structures.get(&key) {73assert_eq!(74existing_format.name, inst.format.name,75"duplicate instruction formats {} and {}; please remove one.",76existing_format.name, inst.format.name77);78} else {79format_structures.insert(key, inst.format.clone());80}81}8283let mut result = Vec::from_iter(format_structures.into_values());84result.sort_by_key(|format| format.name);85result86}878889