cranelift_codegen_meta/
gen_types.rs

1//! Generate sources with type info.
2//!
3//! This generates a `types.rs` file which is included in
4//! `cranelift-codegen/ir/types.rs`. The file provides constant definitions for the
5//! most commonly used types, including all of the scalar types.
6//!
7//! This ensures that the metaprogram and the generated program see the same
8//! type numbering.
9
10use crate::cdsl::types as cdsl_types;
11use crate::error;
12use crate::srcgen;
13
14/// Emit a constant definition of a single value type.
15fn emit_type(ty: &cdsl_types::ValueType, fmt: &mut srcgen::Formatter) {
16    let name = ty.to_string().to_uppercase();
17    let number = ty.number();
18
19    fmt.doc_comment(&ty.doc());
20    fmtln!(fmt, "pub const {}: Type = Type({:#x});\n", name, number);
21}
22
23/// Emit definition for all vector types with `bits` total size.
24fn emit_vectors(bits: u64, fmt: &mut srcgen::Formatter) {
25    let vec_size: u64 = bits / 8;
26    for vec in cdsl_types::ValueType::all_lane_types()
27        .map(|ty| (ty, cdsl_types::ValueType::from(ty).membytes()))
28        .filter(|&(_, lane_size)| lane_size != 0 && lane_size < vec_size)
29        .map(|(ty, lane_size)| (ty, vec_size / lane_size))
30        .map(|(ty, lanes)| cdsl_types::VectorType::new(ty, lanes))
31    {
32        emit_type(&cdsl_types::ValueType::from(vec), fmt);
33    }
34}
35
36/// Emit definition for all dynamic vector types with `bits` total size.
37fn emit_dynamic_vectors(bits: u64, fmt: &mut srcgen::Formatter) {
38    let vec_size: u64 = bits / 8;
39    for vec in cdsl_types::ValueType::all_lane_types()
40        .map(|ty| (ty, cdsl_types::ValueType::from(ty).membytes()))
41        .filter(|&(_, lane_size)| lane_size != 0 && lane_size < vec_size)
42        .map(|(ty, lane_size)| (ty, vec_size / lane_size))
43        .map(|(ty, lanes)| cdsl_types::DynamicVectorType::new(ty, lanes))
44    {
45        emit_type(&cdsl_types::ValueType::from(vec), fmt);
46    }
47}
48
49/// Emit types using the given formatter object.
50fn emit_types(fmt: &mut srcgen::Formatter) {
51    // Emit all of the lane types, such integers, floats, and booleans.
52    for ty in cdsl_types::ValueType::all_lane_types().map(cdsl_types::ValueType::from) {
53        emit_type(&ty, fmt);
54    }
55
56    // Emit vector definitions for common SIMD sizes.
57    // Emit dynamic vector definitions.
58    for vec_size in &[16_u64, 32, 64, 128, 256, 512] {
59        emit_vectors(*vec_size, fmt);
60        emit_dynamic_vectors(*vec_size, fmt);
61    }
62}
63
64/// Generate the types file.
65pub(crate) fn generate(filename: &str, out_dir: &std::path::Path) -> Result<(), error::Error> {
66    let mut fmt = srcgen::Formatter::new();
67    emit_types(&mut fmt);
68    fmt.update_file(filename, out_dir)?;
69    Ok(())
70}