std_detect/detect/os/linux/
loongarch.rs1use core::arch::asm;
4
5use super::auxvec;
6use crate::detect::{Feature, bit, cache};
7
8pub(crate) fn detect_features() -> cache::Initializer {
10 let mut value = cache::Initializer::default();
11 let enable_feature = |value: &mut cache::Initializer, feature, enable| {
12 if enable {
13 value.set(feature as u32);
14 }
15 };
16
17 let cpucfg2: usize;
21 unsafe {
22 asm!(
23 "cpucfg {}, {}",
24 out(reg) cpucfg2, in(reg) 2,
25 options(pure, nomem, preserves_flags, nostack)
26 );
27 }
28 let cpucfg3: usize;
29 unsafe {
30 asm!(
31 "cpucfg {}, {}",
32 out(reg) cpucfg3, in(reg) 3,
33 options(pure, nomem, preserves_flags, nostack)
34 );
35 }
36 enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25));
37 enable_feature(&mut value, Feature::div32, bit::test(cpucfg2, 26));
38 enable_feature(&mut value, Feature::lam_bh, bit::test(cpucfg2, 27));
39 enable_feature(&mut value, Feature::lamcas, bit::test(cpucfg2, 28));
40 enable_feature(&mut value, Feature::scq, bit::test(cpucfg2, 30));
41 enable_feature(&mut value, Feature::ld_seq_sa, bit::test(cpucfg3, 23));
42
43 if let Ok(auxv) = auxvec::auxv() {
47 enable_feature(&mut value, Feature::f, bit::test(cpucfg2, 1) && bit::test(auxv.hwcap, 3));
48 enable_feature(&mut value, Feature::d, bit::test(cpucfg2, 2) && bit::test(auxv.hwcap, 3));
49 enable_feature(&mut value, Feature::lsx, bit::test(auxv.hwcap, 4));
50 enable_feature(&mut value, Feature::lasx, bit::test(auxv.hwcap, 5));
51 enable_feature(
52 &mut value,
53 Feature::lbt,
54 bit::test(auxv.hwcap, 10) && bit::test(auxv.hwcap, 11) && bit::test(auxv.hwcap, 12),
55 );
56 enable_feature(&mut value, Feature::lvz, bit::test(auxv.hwcap, 9));
57 enable_feature(&mut value, Feature::ual, bit::test(auxv.hwcap, 2));
58 return value;
59 }
60 value
61}