summaryrefslogtreecommitdiffstats
path: root/rust/vendor/cpufeatures/src/loongarch64.rs
blob: 51398d74eea472a2bfbcb3a7555ba127a9447b35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//! LoongArch64 CPU feature detection support.
//!
//! This implementation relies on OS-specific APIs for feature detection.

// Evaluate the given `$body` expression any of the supplied target features
// are not enabled. Otherwise returns true.
#[macro_export]
#[doc(hidden)]
macro_rules! __unless_target_features {
    ($($tf:tt),+ => $body:expr ) => {
        {
            #[cfg(not(all($(target_feature=$tf,)*)))]
            $body

            #[cfg(all($(target_feature=$tf,)*))]
            true
        }
    };
}

// Linux runtime detection of target CPU features using `getauxval`.
#[cfg(target_os = "linux")]
#[macro_export]
#[doc(hidden)]
macro_rules! __detect_target_features {
    ($($tf:tt),+) => {{
        let hwcaps = $crate::loongarch64::getauxval_hwcap();
        $($crate::check!(hwcaps, $tf) & )+ true
    }};
}

/// Linux helper function for calling `getauxval` to get `AT_HWCAP`.
#[cfg(target_os = "linux")]
pub fn getauxval_hwcap() -> u64 {
    unsafe { libc::getauxval(libc::AT_HWCAP) }
}

// Linux `expand_check_macro`
#[cfg(target_os = "linux")]
macro_rules! __expand_check_macro {
    ($(($name:tt, $hwcap:ident)),* $(,)?) => {
        #[macro_export]
        #[doc(hidden)]
        macro_rules! check {
            $(
                ($hwcaps:expr, $name) => {
                    (($hwcaps & $crate::loongarch64::hwcaps::$hwcap) != 0)
                };
            )*
        }
    };
}

// Linux `expand_check_macro`
#[cfg(target_os = "linux")]
__expand_check_macro! {
    ("cpucfg",   CPUCFG),   // Enable CPUCFG support.
    ("lam",      LAM),      // Enable LAM support.
    ("ual",      UAL),      // Enable UAL support.
    ("fpu",      FPU),      // Enable FPU support.
    ("lsx",      LSX),      // Enable LSX support.
    ("lasx",     LASX),     // Enable LASX support.
    ("crc32",    CRC32),    // Enable CRC32 support.
    ("complex",  COMPLEX),  // Enable COMPLEX support.
    ("crypto",   CRYPTO),   // Enable CRYPTO support.
    ("lvz",      LVZ),      // Enable LVZ support.
    ("lbt.x86",  LBT_X86),  // Enable LBT_X86 support.
    ("lbt.arm",  LBT_ARM),  // Enable LBT_ARM support.
    ("lbt.mips", LBT_MIPS), // Enable LBT_MIPS support.
    ("ptw",      PTW),      // Enable PTW support.
}

/// Linux hardware capabilities mapped to target features.
///
/// Note that LLVM target features are coarser grained than what Linux supports
/// and imply more capabilities under each feature. This module attempts to
/// provide that mapping accordingly.
#[cfg(target_os = "linux")]
pub mod hwcaps {
    use libc::c_ulong;

    pub const CPUCFG: c_ulong = libc::HWCAP_CPUCFG;
    pub const LAM: c_ulong = libc::HWCAP_LAM;
    pub const UAL: c_ulong = libc::HWCAP_UAL;
    pub const FPU: c_ulong = libc::HWCAP_FPU;
    pub const LSX: c_ulong = libc::HWCAP_LSX;
    pub const LASX: c_ulong = libc::HWCAP_LASX;
    pub const CRC32: c_ulong = libc::HWCAP_CRC32;
    pub const COMPLEX: c_ulong = libc::HWCAP_COMPLEX;
    pub const CRYPTO: c_ulong = libc::HWCAP_CRYPTO;
    pub const LVZ: c_ulong = libc::HWCAP_LVZ;
    pub const LBT_X86: c_ulong = libc::HWCAP_LBT_X86;
    pub const LBT_ARM: c_ulong = libc::HWCAP_LBT_ARM;
    pub const LBT_MIPS: c_ulong = libc::HWCAP_LBT_MIPS;
    pub const PTW: c_ulong = libc::HWCAP_PTW;
}

// On other targets, runtime CPU feature detection is unavailable
#[cfg(not(target_os = "linux"))]
#[macro_export]
#[doc(hidden)]
macro_rules! __detect_target_features {
    ($($tf:tt),+) => {
        false
    };
}