Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/assembler-x64/src/features.rs
1692 views
1
//! CPU features.
2
//!
3
//! Across generations, CPUs add features that include new instructions, e.g.,
4
//! [`Feature::sse`], [`Feature::avx`], etc. x64 instructions are governed by
5
//! boolean terms of these CPU features: e.g., `(_64b | compat) & ssse3`. These
6
//! terms are defined per instruction in the `meta` crate and are exposed to
7
//! users in two ways:
8
//! - via the [`Inst::is_available`] function, which uses the
9
//! [`AvailableFeatures`] trait below to query "is this instruction currently
10
//! allowed?"; use this for fast checks during compilation
11
//! - via the [`Inst::features`] function, which returns a fully-constructed
12
//! [`Features`] term; use this for time-insensitive analysis or
13
//! pretty-printing.
14
//!
15
//! ```rust
16
//! # use cranelift_assembler_x64::{Registers, inst};
17
//! # pub struct Regs;
18
//! # impl Registers for Regs {
19
//! # type ReadGpr = u8;
20
//! # type ReadWriteGpr = u8;
21
//! # type WriteGpr = u8;
22
//! # type ReadXmm = u8;
23
//! # type ReadWriteXmm = u8;
24
//! # type WriteXmm = u8;
25
//! # }
26
//! let xmm0: u8 = 0;
27
//! let andps = inst::andps_a::<Regs>::new(xmm0, xmm0);
28
//! assert_eq!(andps.features().to_string(), "((_64b | compat) & sse)");
29
//! ```
30
//!
31
//! [`Inst::is_available`]: crate::inst::Inst::is_available
32
//! [`Inst::features`]: crate::inst::Inst::features
33
34
use crate::inst::for_each_feature;
35
use std::fmt;
36
37
// Helpfully generate `enum Feature`.
38
macro_rules! create_feature_enum {
39
($($f:ident)+) => {
40
/// A CPU feature.
41
///
42
/// IA-32e mode is the typical mode of operation for modern 64-bit x86
43
/// processors. It consists of two sub-modes:
44
/// - __64-bit mode__: uses the full 64-bit address space
45
/// - __compatibility mode__: allows use of legacy 32-bit code
46
///
47
/// Other features listed here should match the __CPUID Feature Flags__
48
/// column of the instruction tables of the x64 reference manual.
49
///
50
/// This is generated from the `dsl::Feature` enumeration defined in the
51
/// `meta` crate; see [`for_each_feature`].
52
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
53
pub enum Feature {
54
$($f,)+
55
}
56
};
57
}
58
for_each_feature!(create_feature_enum);
59
60
// Helpfully generate trait functions in `AvailableFeatures`.
61
macro_rules! add_func {
62
($($f:ident)+) => {
63
$(fn $f(&self) -> bool;)+
64
};
65
}
66
67
/// A trait for querying CPU features.
68
///
69
/// This is generated from the `dsl::Feature` enumeration defined in the `meta`
70
/// crate. It allows querying the CPUID features required by an instruction; see
71
/// [`Inst::is_available`] and [`for_each_feature`].
72
///
73
/// [`Inst::is_available`]: crate::inst::Inst::is_available
74
pub trait AvailableFeatures {
75
for_each_feature!(add_func);
76
}
77
78
/// A boolean term of CPU features.
79
///
80
/// An instruction is valid when the boolean term (a recursive tree of `AND` and
81
/// `OR` terms) is satisfied; see [`Inst::features`].
82
///
83
/// [`Inst::features`]: crate::inst::Inst::features
84
pub enum Features {
85
And(&'static Features, &'static Features),
86
Or(&'static Features, &'static Features),
87
Feature(Feature),
88
}
89
90
impl fmt::Display for Features {
91
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92
match self {
93
Features::And(lhs, rhs) => write!(f, "({lhs} & {rhs})"),
94
Features::Or(lhs, rhs) => write!(f, "({lhs} | {rhs})"),
95
Features::Feature(feature) => write!(f, "{feature:#?}"),
96
}
97
}
98
}
99
100