Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/assembler-x64/meta/src/generate/features.rs
1693 views
1
//! Generate feature-related Rust code.
2
3
use super::{Formatter, fmtln};
4
use crate::dsl;
5
6
impl dsl::Feature {
7
/// `macro_rules! for_each_feature { ... }`
8
///
9
/// This function generates a macro to allow generating code for each CPU
10
/// feature.
11
pub(crate) fn generate_macro(f: &mut Formatter) {
12
fmtln!(f, "#[doc(hidden)]");
13
fmtln!(f, "#[macro_export]");
14
f.add_block("macro_rules! for_each_feature", |f| {
15
f.add_block("($m:ident) =>", |f| {
16
f.add_block("$m!", |f| {
17
for feature in dsl::ALL_FEATURES {
18
fmtln!(f, "{feature}");
19
}
20
});
21
});
22
});
23
}
24
}
25
26
impl dsl::Features {
27
/// E.g., `features.is_sse2() && features.is_64b()`
28
///
29
/// Generate a boolean expression that checks if the features are available.
30
pub(crate) fn generate_boolean_expr(&self, name: &str) -> String {
31
use dsl::Features::*;
32
match self {
33
And(lhs, rhs) => {
34
let lhs = lhs.generate_inner_boolean_expr(name);
35
let rhs = rhs.generate_inner_boolean_expr(name);
36
format!("{lhs} && {rhs}")
37
}
38
Or(lhs, rhs) => {
39
let lhs = lhs.generate_inner_boolean_expr(name);
40
let rhs = rhs.generate_inner_boolean_expr(name);
41
format!("{lhs} || {rhs}")
42
}
43
Feature(feature) => {
44
format!("{name}.{feature}()")
45
}
46
}
47
}
48
49
// This adds parentheses for inner terms.
50
fn generate_inner_boolean_expr(&self, name: &str) -> String {
51
use dsl::Features::*;
52
match self {
53
And(lhs, rhs) => {
54
let lhs = lhs.generate_inner_boolean_expr(name);
55
let rhs = rhs.generate_inner_boolean_expr(name);
56
format!("({lhs} && {rhs})")
57
}
58
Or(lhs, rhs) => {
59
let lhs = lhs.generate_inner_boolean_expr(name);
60
let rhs = rhs.generate_inner_boolean_expr(name);
61
format!("({lhs} || {rhs})")
62
}
63
Feature(feature) => format!("{name}.{feature}()"),
64
}
65
}
66
67
/// E.g., `Features::Or(Features::Feature(compat), Features::Feature(64b))`
68
///
69
/// Generate a Rust constructor expression that contains the feature
70
/// boolean term.
71
pub(crate) fn generate_constructor_expr(&self, f: &mut Formatter) {
72
let mut index = 0;
73
let name = self.generate_inner_constructor_expr(f, &mut index);
74
fmtln!(f, "{name}");
75
}
76
77
fn generate_inner_constructor_expr(&self, f: &mut Formatter, index: &mut u32) -> String {
78
use dsl::Features::*;
79
80
let name = format!("F{index}");
81
*index += 1;
82
83
let const_expr = format!("const {name}: &'static Features");
84
match self {
85
And(lhs, rhs) => {
86
let lhs = lhs.generate_inner_constructor_expr(f, index);
87
let rhs = rhs.generate_inner_constructor_expr(f, index);
88
fmtln!(f, "{const_expr} = &Features::And({lhs}, {rhs});");
89
}
90
Or(lhs, rhs) => {
91
let lhs = lhs.generate_inner_constructor_expr(f, index);
92
let rhs = rhs.generate_inner_constructor_expr(f, index);
93
fmtln!(f, "{const_expr} = &Features::Or({lhs}, {rhs});");
94
}
95
Feature(feature) => {
96
fmtln!(f, "{const_expr} = &Features::Feature(Feature::{feature});");
97
}
98
}
99
name
100
}
101
}
102
103