Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/codegen/meta/src/shared/mod.rs
1693 views
1
//! Shared definitions for the Cranelift intermediate language.
2
3
pub mod entities;
4
pub mod formats;
5
pub mod immediates;
6
pub mod instructions;
7
pub mod settings;
8
pub mod types;
9
10
use crate::cdsl::formats::{FormatStructure, InstructionFormat};
11
use crate::cdsl::instructions::AllInstructions;
12
use crate::cdsl::settings::SettingGroup;
13
14
use crate::shared::entities::EntityRefs;
15
use crate::shared::formats::Formats;
16
use crate::shared::immediates::Immediates;
17
18
use std::collections::HashMap;
19
use std::rc::Rc;
20
21
pub(crate) struct Definitions {
22
pub settings: SettingGroup,
23
pub all_instructions: AllInstructions,
24
pub all_formats: Vec<Rc<InstructionFormat>>,
25
}
26
27
pub(crate) fn define() -> Definitions {
28
let mut all_instructions = AllInstructions::new();
29
30
let immediates = Immediates::new();
31
let entities = EntityRefs::new();
32
let formats = Formats::new(&immediates, &entities);
33
instructions::define(&mut all_instructions, &formats, &immediates, &entities);
34
let all_formats = verify_instruction_formats(&all_instructions);
35
36
Definitions {
37
settings: settings::define(),
38
all_instructions,
39
all_formats,
40
}
41
}
42
43
/// Verifies certain properties of formats.
44
///
45
/// - Formats must be uniquely named: if two formats have the same name, they must refer to the
46
/// same data. Otherwise, two format variants in the codegen crate would have the same name.
47
/// - Formats must be structurally different from each other. Otherwise, this would lead to
48
/// code duplicate in the codegen crate.
49
///
50
/// Returns a list of all the instruction formats effectively used.
51
fn verify_instruction_formats(all_instructions: &AllInstructions) -> Vec<Rc<InstructionFormat>> {
52
let mut format_names: HashMap<&'static str, &Rc<InstructionFormat>> = HashMap::new();
53
54
// A structure is: number of input value operands / whether there's varargs or not / names
55
// of immediate fields.
56
let mut format_structures: HashMap<FormatStructure, Rc<InstructionFormat>> = HashMap::new();
57
58
for inst in all_instructions {
59
// Check name.
60
if let Some(existing_format) = format_names.get(&inst.format.name) {
61
assert!(
62
Rc::ptr_eq(existing_format, &inst.format),
63
"formats must uniquely named; there's a\
64
conflict on the name '{}', please make sure it is used only once.",
65
existing_format.name
66
);
67
} else {
68
format_names.insert(inst.format.name, &inst.format);
69
}
70
71
// Check structure.
72
let key = inst.format.structure();
73
if let Some(existing_format) = format_structures.get(&key) {
74
assert_eq!(
75
existing_format.name, inst.format.name,
76
"duplicate instruction formats {} and {}; please remove one.",
77
existing_format.name, inst.format.name
78
);
79
} else {
80
format_structures.insert(key, inst.format.clone());
81
}
82
}
83
84
let mut result = Vec::from_iter(format_structures.into_values());
85
result.sort_by_key(|format| format.name);
86
result
87
}
88
89