generic_simd/arch/
mod.rs

1//! Architecture-specific types.
2
3/// Indicates support for a particular CPU feature.
4///
5/// # Safety
6/// Implementing `Token` for a type indicates that the type is only constructible when the
7/// associated CPU features are supported.
8pub unsafe trait Token: Copy + From<Self> + Into<Self> {
9    /// Detects whether the required CPU features are supported.
10    fn new() -> Option<Self>;
11
12    /// Creates the token without detecting if the CPU features are supported.
13    ///
14    /// # Safety
15    /// Calling this function causes undefined behavior if the required CPU features are not
16    /// supported.
17    unsafe fn new_unchecked() -> Self;
18}
19
20#[allow(unused_macros)]
21macro_rules! impl_token {
22    { $name:ident => $($features:tt),+ } => {
23        unsafe impl $crate::arch::Token for $name {
24            #[inline]
25            fn new() -> Option<Self> {
26                if multiversion::are_cpu_features_detected!($($features),*) {
27                    Some(Self(()))
28                } else {
29                    None
30                }
31            }
32
33            #[inline]
34            unsafe fn new_unchecked() -> Self {
35                Self(())
36            }
37        }
38
39        impl core::convert::From<$name> for $crate::arch::generic::Generic {
40            #[inline]
41            fn from(_: $name) -> Self {
42                Self
43            }
44        }
45    }
46}
47
48pub mod generic;
49
50#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
51pub mod x86;
52
53#[cfg(all(feature = "nightly", target_arch = "aarch64"))]
54pub mod arm;
55
56#[cfg(all(
57    target_arch = "wasm32",
58    target_feature = "simd128",
59    feature = "nightly",
60))]
61pub mod wasm;
62
63/// Invokes a macro with the supported token types.
64///
65/// Invokes the macro with the list of [`Token`] types as arguments in priority order, delimited
66/// by commas (including a trailing comma).
67///
68/// The following example creates a `SupportedScalar` supertrait that implements [`ScalarExt`] for
69/// each token:
70/// ```
71/// use generic_simd::{call_macro_with_tokens, scalar::ScalarExt};
72///
73/// macro_rules! supported_scalars {
74///     { $($token:ty,)+ } => {
75///         trait SupportedScalar: Copy $(+ ScalarExt<$token>)* {}
76///     }
77/// }
78///
79/// call_macro_with_tokens!{ supported_scalars }
80/// ```
81///
82/// [`Token`]: arch/trait.Token.html
83/// [`ScalarExt`]: scalar/trait.ScalarExt.html
84#[macro_export]
85macro_rules! call_macro_with_tokens {
86    { $mac:ident } => { $crate::call_macro_with_tokens_impl! { $mac } }
87}
88
89#[cfg(not(any(
90    target_arch = "x86",
91    target_arch = "x86_64",
92    all(target_arch = "aarch64", feature = "nightly"),
93    all(
94        target_arch = "wasm32",
95        target_feature = "simd128",
96        feature = "nightly",
97    ),
98)))]
99#[doc(hidden)]
100#[macro_export]
101macro_rules! call_macro_with_tokens_impl {
102    { $mac:ident } => {
103        $mac! {
104            $crate::arch::generic::Generic,
105        }
106    }
107}
108
109#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
110#[doc(hidden)]
111#[macro_export]
112macro_rules! call_macro_with_tokens_impl {
113    { $mac:ident } => {
114        $mac! {
115            $crate::arch::x86::Avx,
116            $crate::arch::x86::Sse,
117            $crate::arch::generic::Generic,
118        }
119    }
120}
121
122#[cfg(all(feature = "nightly", target_arch = "aarch64"))]
123#[doc(hidden)]
124#[macro_export]
125macro_rules! call_macro_with_tokens_impl {
126    { $mac:ident } => {
127        $mac! {
128            $crate::arch::arm::Neon,
129            $crate::arch::generic::Generic,
130        }
131    }
132}
133
134#[cfg(all(
135    target_arch = "wasm32",
136    target_feature = "simd128",
137    feature = "nightly",
138))]
139#[doc(hidden)]
140#[macro_export]
141macro_rules! call_macro_with_tokens_impl {
142    { $mac:ident } => {
143        $mac! {
144            $crate::arch::wasm::Simd128,
145            $crate::arch::generic::Generic,
146        }
147    }
148}