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