1#[macro_export]
12#[doc(hidden)]
13macro_rules! __unless_target_features {
14 ($($tf:tt),+ => $body:expr ) => {{
15 #[cfg(not(all($(target_feature=$tf,)*)))]
16 {
17 #[cfg(not(target_env = "sgx"))]
18 $body
19
20 #[cfg(target_env = "sgx")]
22 false
23 }
24
25 #[cfg(all($(target_feature=$tf,)*))]
26 true
27 }};
28}
29
30#[macro_export]
32#[doc(hidden)]
33macro_rules! __detect_target_features {
34 ($($tf:tt),+) => {{
35 #[cfg(target_arch = "x86")]
36 use core::arch::x86::{__cpuid, __cpuid_count};
37 #[cfg(target_arch = "x86_64")]
38 use core::arch::x86_64::{__cpuid, __cpuid_count};
39
40 let cr = unsafe {
41 [__cpuid(1), __cpuid_count(7, 0)]
42 };
43
44 $($crate::check!(cr, $tf) & )+ true
45 }};
46}
47
48macro_rules! __expand_check_macro {
49 ($(($name:tt, $i:expr, $reg:ident, $offset:expr)),* $(,)?) => {
50 #[macro_export]
51 #[doc(hidden)]
52 macro_rules! check {
53 $(
54 ($cr:expr, $name) => { ($cr[$i].$reg & (1 << $offset) != 0) };
55 )*
56 }
57 };
58}
59
60__expand_check_macro! {
61 ("mmx", 0, edx, 23),
62 ("sse", 0, edx, 25),
63 ("sse2", 0, edx, 26),
64 ("sse3", 0, ecx, 0),
65 ("pclmulqdq", 0, ecx, 1),
66 ("ssse3", 0, ecx, 9),
67 ("fma", 0, ecx, 12),
68 ("sse4.1", 0, ecx, 19),
69 ("sse4.2", 0, ecx, 20),
70 ("popcnt", 0, ecx, 23),
71 ("aes", 0, ecx, 25),
72 ("avx", 0, ecx, 28),
73 ("rdrand", 0, ecx, 30),
74 ("sgx", 1, ebx, 2),
75 ("bmi1", 1, ebx, 3),
76 ("avx2", 1, ebx, 5),
77 ("bmi2", 1, ebx, 8),
78 ("rdseed", 1, ebx, 18),
79 ("adx", 1, ebx, 19),
80 ("sha", 1, ebx, 29),
81}