std_detect: Add support for LoongArch

Co-authored-by: WANG Rui <wangrui@loongson.cn>
This commit is contained in:
ZHAI Xiang 2023-10-25 15:09:45 +08:00 committed by Amanieu d'Antras
parent 3b2a5e2866
commit 5625c8bf49
8 changed files with 96 additions and 2 deletions

View file

@ -53,7 +53,7 @@ crate from working on applications in which `std` is not available.
[`cupid`](https://crates.io/crates/cupid) crate.
* Linux/Android:
* `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `riscv{32,64}`: `std_detect`
* `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `riscv{32,64}`, `loongarch64`: `std_detect`
supports these on Linux by querying ELF auxiliary vectors (using `getauxval`
when available), and if that fails, by querying `/proc/cpuinfo`.
* `arm64`: partial support for doing run-time feature detection by directly

View file

@ -0,0 +1,48 @@
//! Run-time feature detection on LoongArch.
features! {
@TARGET: loongarch;
@CFG: target_arch = "loongarch64";
@MACRO_NAME: is_loongarch_feature_detected;
@MACRO_ATTRS:
/// Checks if `loongarch` feature is enabled.
/// Supported arguments are:
///
/// * `"lam"`
/// * `"ual"`
/// * `"fpu"`
/// * `"lsx"`
/// * `"lasx"`
/// * `"crc32"`
/// * `"complex"`
/// * `"crypto"`
/// * `"lvz"`
/// * `"lbtx86"`
/// * `"lbtarm"`
/// * `"lbtmips"`
#[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")]
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lam: "lam";
/// LAM
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] ual: "ual";
/// UAL
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] fpu: "fpu";
/// FPU
@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")] crc32: "crc32";
/// FPU
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] complex: "complex";
/// Complex
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] crypto: "crypto";
/// Crypto
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lvz: "lvz";
/// LVZ
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lbtx86: "lbtx86";
/// LBT.X86
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lbtarm: "lbtarm";
/// LBT.ARM
@FEATURE: #[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")] lbtmips: "lbtmips";
/// LBT.MIPS
}

View file

@ -19,6 +19,8 @@ mod powerpc64;
mod mips;
#[macro_use]
mod mips64;
#[macro_use]
mod loongarch;
cfg_if! {
if #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] {
@ -45,6 +47,9 @@ cfg_if! {
} else if #[cfg(target_arch = "mips64")] {
#[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")]
pub use mips64::*;
} else if #[cfg(target_arch = "loongarch64")] {
#[unstable(feature = "stdarch_loongarch_feature_detection", issue = "117425")]
pub use loongarch::*;
} else {
// Unimplemented architecture:
#[doc(hidden)]

View file

@ -96,6 +96,7 @@ pub fn features() -> impl Iterator<Item = (&'static str, bool)> {
target_arch = "powerpc64",
target_arch = "mips",
target_arch = "mips64",
target_arch = "loongarch64",
))] {
(0_u8..Feature::_last as u8).map(|discriminant: u8| {
#[allow(bindings_with_variant_name)] // RISC-V has Feature::f

View file

@ -129,7 +129,8 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "mips",
target_arch = "mips64"
target_arch = "mips64",
target_arch = "loongarch64",
))]
{
let hwcap = unsafe { libc::getauxval(AT_HWCAP as libc::c_ulong) as usize };
@ -225,6 +226,7 @@ fn auxv_from_buf(buf: &[usize]) -> Result<AuxVec, ()> {
target_arch = "riscv64",
target_arch = "mips",
target_arch = "mips64",
target_arch = "loongarch64",
))]
{
for el in buf.chunks(2) {

View file

@ -0,0 +1,34 @@
//! Run-time feature detection for LoongArch on Linux.
use super::auxvec;
use crate::detect::{bit, cache, Feature};
/// Try to read the features from the auxiliary vector.
pub(crate) fn detect_features() -> cache::Initializer {
let mut value = cache::Initializer::default();
let enable_feature = |value: &mut cache::Initializer, feature, enable| {
if enable {
value.set(feature as u32);
}
};
// 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::lam, bit::test(auxv.hwcap, 1));
enable_feature(&mut value, Feature::ual, bit::test(auxv.hwcap, 2));
enable_feature(&mut value, Feature::fpu, 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::crc32, bit::test(auxv.hwcap, 6));
enable_feature(&mut value, Feature::complex, bit::test(auxv.hwcap, 7));
enable_feature(&mut value, Feature::crypto, bit::test(auxv.hwcap, 8));
enable_feature(&mut value, Feature::lvz, bit::test(auxv.hwcap, 9));
enable_feature(&mut value, Feature::lbtx86, bit::test(auxv.hwcap, 10));
enable_feature(&mut value, Feature::lbtarm, bit::test(auxv.hwcap, 11));
enable_feature(&mut value, Feature::lbtmips, bit::test(auxv.hwcap, 12));
return value;
}
value
}

View file

@ -54,6 +54,9 @@ cfg_if::cfg_if! {
} else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] {
mod powerpc;
pub(crate) use self::powerpc::detect_features;
} else if #[cfg(target_arch = "loongarch64")] {
mod loongarch;
pub(crate) use self::loongarch::detect_features;
} else {
use crate::detect::cache;
/// Performs run-time feature detection.

View file

@ -11,6 +11,7 @@
//! * `mips64`: [`is_mips64_feature_detected`]
//! * `powerpc`: [`is_powerpc_feature_detected`]
//! * `powerpc64`: [`is_powerpc64_feature_detected`]
//! * `loongarch`: [`is_loongarch_feature_detected`]
#![stable(feature = "stdsimd", since = "1.27.0")]
#![feature(staged_api, doc_cfg, allow_internal_unstable)]