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 cpucfg1: usize;
21 let cpucfg2: usize;
22 let cpucfg3: usize;
23 unsafe {
24 asm!(
25 "cpucfg {}, {}",
26 "cpucfg {}, {}",
27 "cpucfg {}, {}",
28 out(reg) cpucfg1, in(reg) 1,
29 out(reg) cpucfg2, in(reg) 2,
30 out(reg) cpucfg3, in(reg) 3,
31 options(pure, nomem, preserves_flags, nostack)
32 );
33 }
34 enable_feature(&mut value, Feature::_32s, bit::test(cpucfg1, 0) || bit::test(cpucfg1, 1));
35 enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25));
36 enable_feature(&mut value, Feature::div32, bit::test(cpucfg2, 26));
37 enable_feature(&mut value, Feature::lam_bh, bit::test(cpucfg2, 27));
38 enable_feature(&mut value, Feature::lamcas, bit::test(cpucfg2, 28));
39 enable_feature(&mut value, Feature::scq, bit::test(cpucfg2, 30));
40 enable_feature(&mut value, Feature::ld_seq_sa, bit::test(cpucfg3, 23));
41
42 if let Ok(auxv) = auxvec::auxv() {
46 enable_feature(&mut value, Feature::f, bit::test(cpucfg2, 1) && bit::test(auxv.hwcap, 3));
47 enable_feature(&mut value, Feature::d, bit::test(cpucfg2, 2) && bit::test(auxv.hwcap, 3));
48 enable_feature(&mut value, Feature::lsx, bit::test(auxv.hwcap, 4));
49 enable_feature(&mut value, Feature::lasx, bit::test(auxv.hwcap, 5));
50 enable_feature(
51 &mut value,
52 Feature::lbt,
53 bit::test(auxv.hwcap, 10) && bit::test(auxv.hwcap, 11) && bit::test(auxv.hwcap, 12),
54 );
55 enable_feature(&mut value, Feature::lvz, bit::test(auxv.hwcap, 9));
56 enable_feature(&mut value, Feature::ual, bit::test(auxv.hwcap, 2));
57 return value;
58 }
59 value
60}