std_detect: loongarch: Add runtime detectable features from LLVM

* f
* d
* frecipe
* lbt
This commit is contained in:
WANG Rui 2024-03-07 16:11:35 +08:00 committed by Amanieu d'Antras
parent 5fd2d04ef7
commit 1fbe4dddec
2 changed files with 45 additions and 4 deletions

View file

@ -8,17 +8,29 @@ features! {
/// Checks if `loongarch` feature is enabled.
/// Supported arguments are:
///
/// * `"ual"`
/// * `"f"`
/// * `"d"`
/// * `"frecipe"`
/// * `"lsx"`
/// * `"lasx"`
/// * `"lbt"`
/// * `"lvz"`
/// * `"ual"`
#[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")]
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] ual: "ual";
/// UAL
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] f: "f";
/// F
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] d: "d";
/// D
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] frecipe: "frecipe";
/// Frecipe
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lsx: "lsx";
/// LSX
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lasx: "lasx";
/// LASX
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lbt: "lbt";
/// LBT
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lvz: "lvz";
/// LVZ
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] ual: "ual";
/// UAL
}

View file

@ -2,6 +2,7 @@
use super::auxvec;
use crate::detect::{bit, cache, Feature};
use core::arch::asm;
/// Try to read the features from the auxiliary vector.
pub(crate) fn detect_features() -> cache::Initializer {
@ -12,14 +13,42 @@ pub(crate) fn detect_features() -> cache::Initializer {
}
};
// The values are part of the platform-specific [cpucfg]
//
// [cpucfg]: LoongArch Reference Manual Volume 1: Basic Architecture v1.1
let cpucfg2: usize;
unsafe {
asm!(
"cpucfg {}, {}",
out(reg) cpucfg2, in(reg) 2,
options(pure, nomem, preserves_flags, nostack)
);
}
enable_feature(&mut value, Feature::frecipe, bit::test(cpucfg2, 25));
// The values are part of the platform-specific [asm/hwcap.h][hwcap]
//
// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
if let Ok(auxv) = auxvec::auxv() {
enable_feature(&mut value, Feature::ual, bit::test(auxv.hwcap, 2));
enable_feature(
&mut value,
Feature::f,
bit::test(cpucfg2, 1) && bit::test(auxv.hwcap, 3),
);
enable_feature(
&mut value,
Feature::d,
bit::test(cpucfg2, 2) && bit::test(auxv.hwcap, 3),
);
enable_feature(&mut value, Feature::lsx, bit::test(auxv.hwcap, 4));
enable_feature(&mut value, Feature::lasx, bit::test(auxv.hwcap, 5));
enable_feature(
&mut value,
Feature::lbt,
bit::test(auxv.hwcap, 10) && bit::test(auxv.hwcap, 11) && bit::test(auxv.hwcap, 12),
);
enable_feature(&mut value, Feature::lvz, bit::test(auxv.hwcap, 9));
enable_feature(&mut value, Feature::ual, bit::test(auxv.hwcap, 2));
return value;
}
value