Reformat std_detect
This commit is contained in:
@@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
#![allow(dead_code)] // not used on all platforms
|
#![allow(dead_code)] // not used on all platforms
|
||||||
|
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use core::sync::atomic::AtomicUsize;
|
|
||||||
|
|
||||||
/// Sets the `bit` of `x`.
|
/// Sets the `bit` of `x`.
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -40,20 +38,14 @@ impl Initializer {
|
|||||||
/// Tests the `bit` of the cache.
|
/// Tests the `bit` of the cache.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn test(self, bit: u32) -> bool {
|
pub(crate) fn test(self, bit: u32) -> bool {
|
||||||
debug_assert!(
|
debug_assert!(bit < CACHE_CAPACITY, "too many features, time to increase the cache size!");
|
||||||
bit < CACHE_CAPACITY,
|
|
||||||
"too many features, time to increase the cache size!"
|
|
||||||
);
|
|
||||||
test_bit(self.0, bit)
|
test_bit(self.0, bit)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the `bit` of the cache.
|
/// Sets the `bit` of the cache.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn set(&mut self, bit: u32) {
|
pub(crate) fn set(&mut self, bit: u32) {
|
||||||
debug_assert!(
|
debug_assert!(bit < CACHE_CAPACITY, "too many features, time to increase the cache size!");
|
||||||
bit < CACHE_CAPACITY,
|
|
||||||
"too many features, time to increase the cache size!"
|
|
||||||
);
|
|
||||||
let v = self.0;
|
let v = self.0;
|
||||||
self.0 = set_bit(v, bit);
|
self.0 = set_bit(v, bit);
|
||||||
}
|
}
|
||||||
@@ -61,10 +53,7 @@ impl Initializer {
|
|||||||
/// Unsets the `bit` of the cache.
|
/// Unsets the `bit` of the cache.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn unset(&mut self, bit: u32) {
|
pub(crate) fn unset(&mut self, bit: u32) {
|
||||||
debug_assert!(
|
debug_assert!(bit < CACHE_CAPACITY, "too many features, time to increase the cache size!");
|
||||||
bit < CACHE_CAPACITY,
|
|
||||||
"too many features, time to increase the cache size!"
|
|
||||||
);
|
|
||||||
let v = self.0;
|
let v = self.0;
|
||||||
self.0 = unset_bit(v, bit);
|
self.0 = unset_bit(v, bit);
|
||||||
}
|
}
|
||||||
@@ -73,11 +62,7 @@ impl Initializer {
|
|||||||
/// This global variable is a cache of the features supported by the CPU.
|
/// This global variable is a cache of the features supported by the CPU.
|
||||||
// Note: the third slot is only used in x86
|
// Note: the third slot is only used in x86
|
||||||
// Another Slot can be added if needed without any change to `Initializer`
|
// Another Slot can be added if needed without any change to `Initializer`
|
||||||
static CACHE: [Cache; 3] = [
|
static CACHE: [Cache; 3] = [Cache::uninitialized(), Cache::uninitialized(), Cache::uninitialized()];
|
||||||
Cache::uninitialized(),
|
|
||||||
Cache::uninitialized(),
|
|
||||||
Cache::uninitialized(),
|
|
||||||
];
|
|
||||||
|
|
||||||
/// Feature cache with capacity for `size_of::<usize>() * 8 - 1` features.
|
/// Feature cache with capacity for `size_of::<usize>() * 8 - 1` features.
|
||||||
///
|
///
|
||||||
@@ -104,19 +89,14 @@ impl Cache {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn test(&self, bit: u32) -> Option<bool> {
|
pub(crate) fn test(&self, bit: u32) -> Option<bool> {
|
||||||
let cached = self.0.load(Ordering::Relaxed);
|
let cached = self.0.load(Ordering::Relaxed);
|
||||||
if cached == 0 {
|
if cached == 0 { None } else { Some(test_bit(cached as u128, bit)) }
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(test_bit(cached as u128, bit))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the cache.
|
/// Initializes the cache.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn initialize(&self, value: usize) -> usize {
|
fn initialize(&self, value: usize) -> usize {
|
||||||
debug_assert_eq!((value & !Cache::MASK), 0);
|
debug_assert_eq!((value & !Cache::MASK), 0);
|
||||||
self.0
|
self.0.store(value | Cache::INITIALIZED_BIT, Ordering::Relaxed);
|
||||||
.store(value | Cache::INITIALIZED_BIT, Ordering::Relaxed);
|
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,7 +197,5 @@ pub(crate) fn test(bit: u32) -> bool {
|
|||||||
} else {
|
} else {
|
||||||
(bit - 2 * Cache::CAPACITY, 2)
|
(bit - 2 * Cache::CAPACITY, 2)
|
||||||
};
|
};
|
||||||
CACHE[idx]
|
CACHE[idx].test(relative_bit).unwrap_or_else(|| detect_and_initialize().test(bit))
|
||||||
.test(relative_bit)
|
|
||||||
.unwrap_or_else(|| detect_and_initialize().test(bit))
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ mod arch;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[unstable(feature = "stdarch_internal", issue = "none")]
|
#[unstable(feature = "stdarch_internal", issue = "none")]
|
||||||
pub use self::arch::__is_feature_detected;
|
pub use self::arch::__is_feature_detected;
|
||||||
|
|
||||||
pub(crate) use self::arch::Feature;
|
pub(crate) use self::arch::Feature;
|
||||||
|
|
||||||
mod bit;
|
mod bit;
|
||||||
|
|||||||
@@ -17,9 +17,10 @@
|
|||||||
//! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt)
|
//! - [Linux documentation](https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt)
|
||||||
//! - [ARM documentation](https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers?lang=en)
|
//! - [ARM documentation](https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers?lang=en)
|
||||||
|
|
||||||
use crate::detect::{Feature, cache};
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
|
use crate::detect::{Feature, cache};
|
||||||
|
|
||||||
/// Try to read the features from the system registers.
|
/// Try to read the features from the system registers.
|
||||||
///
|
///
|
||||||
/// This will cause SIGILL if the current OS is not trapping the mrs instruction.
|
/// This will cause SIGILL if the current OS is not trapping the mrs instruction.
|
||||||
@@ -104,10 +105,7 @@ pub(crate) fn parse_system_registers(
|
|||||||
let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
|
let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
|
||||||
enable_feature(Feature::sha2, asimd && sha1 && sha2);
|
enable_feature(Feature::sha2, asimd && sha1 && sha2);
|
||||||
enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
|
enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
|
||||||
enable_feature(
|
enable_feature(Feature::dotprod, asimd && bits_shift(aa64isar0, 47, 44) >= 1);
|
||||||
Feature::dotprod,
|
|
||||||
asimd && bits_shift(aa64isar0, 47, 44) >= 1,
|
|
||||||
);
|
|
||||||
enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
|
enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
//!
|
//!
|
||||||
//! <https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics>
|
//! <https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics>
|
||||||
|
|
||||||
use crate::detect::{Feature, cache};
|
|
||||||
use core::ffi::CStr;
|
use core::ffi::CStr;
|
||||||
|
|
||||||
|
use crate::detect::{Feature, cache};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn _sysctlbyname(name: &CStr) -> bool {
|
fn _sysctlbyname(name: &CStr) -> bool {
|
||||||
use libc;
|
use libc;
|
||||||
@@ -14,13 +15,7 @@ fn _sysctlbyname(name: &CStr) -> bool {
|
|||||||
let enabled_ptr = &mut enabled as *mut i32 as *mut libc::c_void;
|
let enabled_ptr = &mut enabled as *mut i32 as *mut libc::c_void;
|
||||||
|
|
||||||
let ret = unsafe {
|
let ret = unsafe {
|
||||||
libc::sysctlbyname(
|
libc::sysctlbyname(name.as_ptr(), enabled_ptr, &mut enabled_len, core::ptr::null_mut(), 0)
|
||||||
name.as_ptr(),
|
|
||||||
enabled_ptr,
|
|
||||||
&mut enabled_len,
|
|
||||||
core::ptr::null_mut(),
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match ret {
|
match ret {
|
||||||
|
|||||||
@@ -54,11 +54,8 @@ fn archauxv(key: libc::c_int) -> usize {
|
|||||||
// https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h
|
// https://github.com/freebsd/freebsd-src/blob/release/11.4.0/sys/sys/auxv.h
|
||||||
// FreeBSD 11 support in std has been removed in Rust 1.75 (https://github.com/rust-lang/rust/pull/114521),
|
// FreeBSD 11 support in std has been removed in Rust 1.75 (https://github.com/rust-lang/rust/pull/114521),
|
||||||
// so we can safely use this function.
|
// so we can safely use this function.
|
||||||
let res = libc::elf_aux_info(
|
let res =
|
||||||
key,
|
libc::elf_aux_info(key, &mut out as *mut libc::c_ulong as *mut libc::c_void, OUT_LEN);
|
||||||
&mut out as *mut libc::c_ulong as *mut libc::c_void,
|
|
||||||
OUT_LEN,
|
|
||||||
);
|
|
||||||
// If elf_aux_info fails, `out` will be left at zero (which is the proper default value).
|
// If elf_aux_info fails, `out` will be left at zero (which is the proper default value).
|
||||||
debug_assert!(res == 0 || out == 0);
|
debug_assert!(res == 0 || out == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,14 +343,8 @@ impl AtHwcap {
|
|||||||
enable_feature(Feature::sve2, sve2);
|
enable_feature(Feature::sve2, sve2);
|
||||||
enable_feature(Feature::sve2p1, self.sve2p1 && sve2);
|
enable_feature(Feature::sve2p1, self.sve2p1 && sve2);
|
||||||
// SVE2 extensions require SVE2 and crypto features
|
// SVE2 extensions require SVE2 and crypto features
|
||||||
enable_feature(
|
enable_feature(Feature::sve2_aes, self.sveaes && self.svepmull && sve2 && self.aes);
|
||||||
Feature::sve2_aes,
|
enable_feature(Feature::sve2_sm4, self.svesm4 && sve2 && self.sm3 && self.sm4);
|
||||||
self.sveaes && self.svepmull && sve2 && self.aes,
|
|
||||||
);
|
|
||||||
enable_feature(
|
|
||||||
Feature::sve2_sm4,
|
|
||||||
self.svesm4 && sve2 && self.sm3 && self.sm4,
|
|
||||||
);
|
|
||||||
enable_feature(
|
enable_feature(
|
||||||
Feature::sve2_sha3,
|
Feature::sve2_sha3,
|
||||||
self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2,
|
self.svesha3 && sve2 && self.sha512 && self.sha3 && self.sha1 && self.sha2,
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
//! Run-time feature detection for LoongArch on Linux.
|
//! Run-time feature detection for LoongArch on Linux.
|
||||||
|
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
use super::auxvec;
|
use super::auxvec;
|
||||||
use crate::detect::{Feature, bit, cache};
|
use crate::detect::{Feature, bit, cache};
|
||||||
use core::arch::asm;
|
|
||||||
|
|
||||||
/// Try to read the features from the auxiliary vector.
|
/// Try to read the features from the auxiliary vector.
|
||||||
pub(crate) fn detect_features() -> cache::Initializer {
|
pub(crate) fn detect_features() -> cache::Initializer {
|
||||||
@@ -43,16 +44,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
//
|
//
|
||||||
// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
|
// [hwcap]: https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
|
||||||
if let Ok(auxv) = auxvec::auxv() {
|
if let Ok(auxv) = auxvec::auxv() {
|
||||||
enable_feature(
|
enable_feature(&mut value, Feature::f, bit::test(cpucfg2, 1) && bit::test(auxv.hwcap, 3));
|
||||||
&mut value,
|
enable_feature(&mut value, Feature::d, bit::test(cpucfg2, 2) && bit::test(auxv.hwcap, 3));
|
||||||
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::lsx, bit::test(auxv.hwcap, 4));
|
||||||
enable_feature(&mut value, Feature::lasx, bit::test(auxv.hwcap, 5));
|
enable_feature(&mut value, Feature::lasx, bit::test(auxv.hwcap, 5));
|
||||||
enable_feature(
|
enable_feature(
|
||||||
|
|||||||
@@ -119,16 +119,7 @@ fn _riscv_hwprobe(out: &mut [riscv_hwprobe]) -> bool {
|
|||||||
cpus: *mut libc::c_ulong,
|
cpus: *mut libc::c_ulong,
|
||||||
flags: libc::c_uint,
|
flags: libc::c_uint,
|
||||||
) -> libc::c_long {
|
) -> libc::c_long {
|
||||||
unsafe {
|
unsafe { libc::syscall(__NR_riscv_hwprobe, pairs, pair_count, cpu_set_size, cpus, flags) }
|
||||||
libc::syscall(
|
|
||||||
__NR_riscv_hwprobe,
|
|
||||||
pairs,
|
|
||||||
pair_count,
|
|
||||||
cpu_set_size,
|
|
||||||
cpus,
|
|
||||||
flags,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { __riscv_hwprobe(out.as_mut_ptr(), out.len(), 0, ptr::null_mut(), 0) == 0 }
|
unsafe { __riscv_hwprobe(out.as_mut_ptr(), out.len(), 0, ptr::null_mut(), 0) == 0 }
|
||||||
|
|||||||
@@ -4,8 +4,10 @@
|
|||||||
//! https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8
|
//! https://github.com/openbsd/src/commit/d335af936b9d7dd9cf655cae1ce19560c45de6c8
|
||||||
//! https://github.com/golang/go/commit/cd54ef1f61945459486e9eea2f016d99ef1da925
|
//! https://github.com/golang/go/commit/cd54ef1f61945459486e9eea2f016d99ef1da925
|
||||||
|
|
||||||
|
use core::mem::MaybeUninit;
|
||||||
|
use core::ptr;
|
||||||
|
|
||||||
use crate::detect::cache;
|
use crate::detect::cache;
|
||||||
use core::{mem::MaybeUninit, ptr};
|
|
||||||
|
|
||||||
// Defined in machine/cpu.h.
|
// Defined in machine/cpu.h.
|
||||||
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/arch/arm64/include/cpu.h#L25-L40
|
// https://github.com/openbsd/src/blob/72ccc03bd11da614f31f7ff76e3f6fce99bc1c79/sys/arch/arm64/include/cpu.h#L25-L40
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
use core::arch::x86::*;
|
use core::arch::x86::*;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use core::arch::x86_64::*;
|
use core::arch::x86_64::*;
|
||||||
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
use crate::detect::{Feature, bit, cache};
|
use crate::detect::{Feature, bit, cache};
|
||||||
@@ -42,12 +41,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
// 0x8000_0000]. - The vendor ID is stored in 12 u8 ascii chars,
|
// 0x8000_0000]. - The vendor ID is stored in 12 u8 ascii chars,
|
||||||
// returned in EBX, EDX, and ECX (in that order):
|
// returned in EBX, EDX, and ECX (in that order):
|
||||||
let (max_basic_leaf, vendor_id) = unsafe {
|
let (max_basic_leaf, vendor_id) = unsafe {
|
||||||
let CpuidResult {
|
let CpuidResult { eax: max_basic_leaf, ebx, ecx, edx } = __cpuid(0);
|
||||||
eax: max_basic_leaf,
|
|
||||||
ebx,
|
|
||||||
ecx,
|
|
||||||
edx,
|
|
||||||
} = __cpuid(0);
|
|
||||||
let vendor_id: [[u8; 4]; 3] = [ebx.to_ne_bytes(), edx.to_ne_bytes(), ecx.to_ne_bytes()];
|
let vendor_id: [[u8; 4]; 3] = [ebx.to_ne_bytes(), edx.to_ne_bytes(), ecx.to_ne_bytes()];
|
||||||
let vendor_id: [u8; 12] = mem::transmute(vendor_id);
|
let vendor_id: [u8; 12] = mem::transmute(vendor_id);
|
||||||
(max_basic_leaf, vendor_id)
|
(max_basic_leaf, vendor_id)
|
||||||
@@ -60,11 +54,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
|
|
||||||
// EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits";
|
// EAX = 1, ECX = 0: Queries "Processor Info and Feature Bits";
|
||||||
// Contains information about most x86 features.
|
// Contains information about most x86 features.
|
||||||
let CpuidResult {
|
let CpuidResult { ecx: proc_info_ecx, edx: proc_info_edx, .. } =
|
||||||
ecx: proc_info_ecx,
|
unsafe { __cpuid(0x0000_0001_u32) };
|
||||||
edx: proc_info_edx,
|
|
||||||
..
|
|
||||||
} = unsafe { __cpuid(0x0000_0001_u32) };
|
|
||||||
|
|
||||||
// EAX = 7: Queries "Extended Features";
|
// EAX = 7: Queries "Extended Features";
|
||||||
// Contains information about bmi,bmi2, and avx2 support.
|
// Contains information about bmi,bmi2, and avx2 support.
|
||||||
@@ -76,11 +67,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
extended_features_edx_leaf_1,
|
extended_features_edx_leaf_1,
|
||||||
) = if max_basic_leaf >= 7 {
|
) = if max_basic_leaf >= 7 {
|
||||||
let CpuidResult { ebx, ecx, edx, .. } = unsafe { __cpuid(0x0000_0007_u32) };
|
let CpuidResult { ebx, ecx, edx, .. } = unsafe { __cpuid(0x0000_0007_u32) };
|
||||||
let CpuidResult {
|
let CpuidResult { eax: eax_1, edx: edx_1, .. } =
|
||||||
eax: eax_1,
|
unsafe { __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32) };
|
||||||
edx: edx_1,
|
|
||||||
..
|
|
||||||
} = unsafe { __cpuid_count(0x0000_0007_u32, 0x0000_0001_u32) };
|
|
||||||
(ebx, ecx, edx, eax_1, edx_1)
|
(ebx, ecx, edx, eax_1, edx_1)
|
||||||
} else {
|
} else {
|
||||||
(0, 0, 0, 0, 0) // CPUID does not support "Extended Features"
|
(0, 0, 0, 0, 0) // CPUID does not support "Extended Features"
|
||||||
@@ -89,10 +77,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
// EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported
|
// EAX = 0x8000_0000, ECX = 0: Get Highest Extended Function Supported
|
||||||
// - EAX returns the max leaf value for extended information, that is,
|
// - EAX returns the max leaf value for extended information, that is,
|
||||||
// `cpuid` calls in range [0x8000_0000; u32::MAX]:
|
// `cpuid` calls in range [0x8000_0000; u32::MAX]:
|
||||||
let CpuidResult {
|
let CpuidResult { eax: extended_max_basic_leaf, .. } = unsafe { __cpuid(0x8000_0000_u32) };
|
||||||
eax: extended_max_basic_leaf,
|
|
||||||
..
|
|
||||||
} = unsafe { __cpuid(0x8000_0000_u32) };
|
|
||||||
|
|
||||||
// EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature
|
// EAX = 0x8000_0001, ECX=0: Queries "Extended Processor Info and Feature
|
||||||
// Bits"
|
// Bits"
|
||||||
@@ -208,10 +193,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
// Processor Extended State Enumeration Sub-leaf (EAX = 0DH,
|
// Processor Extended State Enumeration Sub-leaf (EAX = 0DH,
|
||||||
// ECX = 1):
|
// ECX = 1):
|
||||||
if max_basic_leaf >= 0xd {
|
if max_basic_leaf >= 0xd {
|
||||||
let CpuidResult {
|
let CpuidResult { eax: proc_extended_state1_eax, .. } =
|
||||||
eax: proc_extended_state1_eax,
|
unsafe { __cpuid_count(0xd_u32, 1) };
|
||||||
..
|
|
||||||
} = unsafe { __cpuid_count(0xd_u32, 1) };
|
|
||||||
enable(proc_extended_state1_eax, 0, Feature::xsaveopt);
|
enable(proc_extended_state1_eax, 0, Feature::xsaveopt);
|
||||||
enable(proc_extended_state1_eax, 1, Feature::xsavec);
|
enable(proc_extended_state1_eax, 1, Feature::xsavec);
|
||||||
enable(proc_extended_state1_eax, 3, Feature::xsaves);
|
enable(proc_extended_state1_eax, 3, Feature::xsaves);
|
||||||
@@ -269,10 +252,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||||||
enable(extended_features_edx_leaf_1, 8, Feature::amx_complex);
|
enable(extended_features_edx_leaf_1, 8, Feature::amx_complex);
|
||||||
|
|
||||||
if max_basic_leaf >= 0x1e {
|
if max_basic_leaf >= 0x1e {
|
||||||
let CpuidResult {
|
let CpuidResult { eax: amx_feature_flags_eax, .. } =
|
||||||
eax: amx_feature_flags_eax,
|
unsafe { __cpuid_count(0x1e_u32, 1) };
|
||||||
..
|
|
||||||
} = unsafe { __cpuid_count(0x1e_u32, 1) };
|
|
||||||
|
|
||||||
enable(amx_feature_flags_eax, 4, Feature::amx_fp8);
|
enable(amx_feature_flags_eax, 4, Feature::amx_fp8);
|
||||||
enable(amx_feature_flags_eax, 5, Feature::amx_transpose);
|
enable(amx_feature_flags_eax, 5, Feature::amx_transpose);
|
||||||
|
|||||||
@@ -59,10 +59,7 @@ fn arm_linux() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(all(
|
#[cfg(all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")))]
|
||||||
target_arch = "aarch64",
|
|
||||||
any(target_os = "linux", target_os = "android")
|
|
||||||
))]
|
|
||||||
fn aarch64_linux() {
|
fn aarch64_linux() {
|
||||||
println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
|
println!("asimd: {}", is_aarch64_feature_detected!("asimd"));
|
||||||
println!("neon: {}", is_aarch64_feature_detected!("neon"));
|
println!("neon: {}", is_aarch64_feature_detected!("neon"));
|
||||||
@@ -97,10 +94,7 @@ fn aarch64_linux() {
|
|||||||
println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
|
println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
|
||||||
println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
|
println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
|
||||||
println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
|
println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
|
||||||
println!(
|
println!("sve2-bitperm: {}", is_aarch64_feature_detected!("sve2-bitperm"));
|
||||||
"sve2-bitperm: {}",
|
|
||||||
is_aarch64_feature_detected!("sve2-bitperm")
|
|
||||||
);
|
|
||||||
println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
|
println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
|
||||||
println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
|
println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
|
||||||
println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
|
println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
|
||||||
@@ -138,25 +132,13 @@ fn aarch64_linux() {
|
|||||||
println!("sme-lutv2: {}", is_aarch64_feature_detected!("sme-lutv2"));
|
println!("sme-lutv2: {}", is_aarch64_feature_detected!("sme-lutv2"));
|
||||||
println!("sme-f8f16: {}", is_aarch64_feature_detected!("sme-f8f16"));
|
println!("sme-f8f16: {}", is_aarch64_feature_detected!("sme-f8f16"));
|
||||||
println!("sme-f8f32: {}", is_aarch64_feature_detected!("sme-f8f32"));
|
println!("sme-f8f32: {}", is_aarch64_feature_detected!("sme-f8f32"));
|
||||||
println!(
|
println!("ssve-fp8fma: {}", is_aarch64_feature_detected!("ssve-fp8fma"));
|
||||||
"ssve-fp8fma: {}",
|
println!("ssve-fp8dot4: {}", is_aarch64_feature_detected!("ssve-fp8dot4"));
|
||||||
is_aarch64_feature_detected!("ssve-fp8fma")
|
println!("ssve-fp8dot2: {}", is_aarch64_feature_detected!("ssve-fp8dot2"));
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"ssve-fp8dot4: {}",
|
|
||||||
is_aarch64_feature_detected!("ssve-fp8dot4")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"ssve-fp8dot2: {}",
|
|
||||||
is_aarch64_feature_detected!("ssve-fp8dot2")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(all(
|
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_os = "windows"))]
|
||||||
any(target_arch = "aarch64", target_arch = "arm64ec"),
|
|
||||||
target_os = "windows"
|
|
||||||
))]
|
|
||||||
fn aarch64_windows() {
|
fn aarch64_windows() {
|
||||||
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
|
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
|
||||||
println!("fp: {:?}", is_aarch64_feature_detected!("fp"));
|
println!("fp: {:?}", is_aarch64_feature_detected!("fp"));
|
||||||
@@ -171,10 +153,7 @@ fn aarch64_windows() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(all(
|
#[cfg(all(target_arch = "aarch64", any(target_os = "freebsd", target_os = "openbsd")))]
|
||||||
target_arch = "aarch64",
|
|
||||||
any(target_os = "freebsd", target_os = "openbsd")
|
|
||||||
))]
|
|
||||||
fn aarch64_bsd() {
|
fn aarch64_bsd() {
|
||||||
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
|
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
|
||||||
println!("pmull: {:?}", is_aarch64_feature_detected!("pmull"));
|
println!("pmull: {:?}", is_aarch64_feature_detected!("pmull"));
|
||||||
@@ -236,14 +215,8 @@ fn riscv_linux() {
|
|||||||
println!("rv32e: {}", is_riscv_feature_detected!("rv32e"));
|
println!("rv32e: {}", is_riscv_feature_detected!("rv32e"));
|
||||||
println!("rv64i: {}", is_riscv_feature_detected!("rv64i"));
|
println!("rv64i: {}", is_riscv_feature_detected!("rv64i"));
|
||||||
println!("rv128i: {}", is_riscv_feature_detected!("rv128i"));
|
println!("rv128i: {}", is_riscv_feature_detected!("rv128i"));
|
||||||
println!(
|
println!("unaligned-scalar-mem: {}", is_riscv_feature_detected!("unaligned-scalar-mem"));
|
||||||
"unaligned-scalar-mem: {}",
|
println!("unaligned-vector-mem: {}", is_riscv_feature_detected!("unaligned-vector-mem"));
|
||||||
is_riscv_feature_detected!("unaligned-scalar-mem")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"unaligned-vector-mem: {}",
|
|
||||||
is_riscv_feature_detected!("unaligned-vector-mem")
|
|
||||||
);
|
|
||||||
println!("zicsr: {}", is_riscv_feature_detected!("zicsr"));
|
println!("zicsr: {}", is_riscv_feature_detected!("zicsr"));
|
||||||
println!("zicntr: {}", is_riscv_feature_detected!("zicntr"));
|
println!("zicntr: {}", is_riscv_feature_detected!("zicntr"));
|
||||||
println!("zihpm: {}", is_riscv_feature_detected!("zihpm"));
|
println!("zihpm: {}", is_riscv_feature_detected!("zihpm"));
|
||||||
@@ -336,10 +309,7 @@ fn powerpc_linux() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(all(
|
#[cfg(all(target_arch = "powerpc64", any(target_os = "linux", target_os = "freebsd"),))]
|
||||||
target_arch = "powerpc64",
|
|
||||||
any(target_os = "linux", target_os = "freebsd"),
|
|
||||||
))]
|
|
||||||
fn powerpc64_linux_or_freebsd() {
|
fn powerpc64_linux_or_freebsd() {
|
||||||
println!("altivec: {}", is_powerpc64_feature_detected!("altivec"));
|
println!("altivec: {}", is_powerpc64_feature_detected!("altivec"));
|
||||||
println!("vsx: {}", is_powerpc64_feature_detected!("vsx"));
|
println!("vsx: {}", is_powerpc64_feature_detected!("vsx"));
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(
|
#![feature(stdarch_internal, x86_amx_intrinsics, xop_target_feature, movrs_target_feature)]
|
||||||
stdarch_internal,
|
|
||||||
x86_amx_intrinsics,
|
|
||||||
xop_target_feature,
|
|
||||||
movrs_target_feature
|
|
||||||
)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate std_detect;
|
extern crate std_detect;
|
||||||
@@ -40,24 +35,15 @@ fn dump() {
|
|||||||
println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));
|
println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));
|
||||||
println!("avx512_ifma: {:?}", is_x86_feature_detected!("avx512ifma"));
|
println!("avx512_ifma: {:?}", is_x86_feature_detected!("avx512ifma"));
|
||||||
println!("avx512vbmi {:?}", is_x86_feature_detected!("avx512vbmi"));
|
println!("avx512vbmi {:?}", is_x86_feature_detected!("avx512vbmi"));
|
||||||
println!(
|
println!("avx512_vpopcntdq: {:?}", is_x86_feature_detected!("avx512vpopcntdq"));
|
||||||
"avx512_vpopcntdq: {:?}",
|
|
||||||
is_x86_feature_detected!("avx512vpopcntdq")
|
|
||||||
);
|
|
||||||
println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2"));
|
println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2"));
|
||||||
println!("gfni: {:?}", is_x86_feature_detected!("gfni"));
|
println!("gfni: {:?}", is_x86_feature_detected!("gfni"));
|
||||||
println!("vaes: {:?}", is_x86_feature_detected!("vaes"));
|
println!("vaes: {:?}", is_x86_feature_detected!("vaes"));
|
||||||
println!("vpclmulqdq: {:?}", is_x86_feature_detected!("vpclmulqdq"));
|
println!("vpclmulqdq: {:?}", is_x86_feature_detected!("vpclmulqdq"));
|
||||||
println!("avx512vnni: {:?}", is_x86_feature_detected!("avx512vnni"));
|
println!("avx512vnni: {:?}", is_x86_feature_detected!("avx512vnni"));
|
||||||
println!(
|
println!("avx512bitalg: {:?}", is_x86_feature_detected!("avx512bitalg"));
|
||||||
"avx512bitalg: {:?}",
|
|
||||||
is_x86_feature_detected!("avx512bitalg")
|
|
||||||
);
|
|
||||||
println!("avx512bf16: {:?}", is_x86_feature_detected!("avx512bf16"));
|
println!("avx512bf16: {:?}", is_x86_feature_detected!("avx512bf16"));
|
||||||
println!(
|
println!("avx512vp2intersect: {:?}", is_x86_feature_detected!("avx512vp2intersect"));
|
||||||
"avx512vp2intersect: {:?}",
|
|
||||||
is_x86_feature_detected!("avx512vp2intersect")
|
|
||||||
);
|
|
||||||
println!("avx512fp16: {:?}", is_x86_feature_detected!("avx512fp16"));
|
println!("avx512fp16: {:?}", is_x86_feature_detected!("avx512fp16"));
|
||||||
println!("fma: {:?}", is_x86_feature_detected!("fma"));
|
println!("fma: {:?}", is_x86_feature_detected!("fma"));
|
||||||
println!("abm: {:?}", is_x86_feature_detected!("abm"));
|
println!("abm: {:?}", is_x86_feature_detected!("abm"));
|
||||||
@@ -77,15 +63,9 @@ fn dump() {
|
|||||||
println!("movbe: {:?}", is_x86_feature_detected!("movbe"));
|
println!("movbe: {:?}", is_x86_feature_detected!("movbe"));
|
||||||
println!("avxvnni: {:?}", is_x86_feature_detected!("avxvnni"));
|
println!("avxvnni: {:?}", is_x86_feature_detected!("avxvnni"));
|
||||||
println!("avxvnniint8: {:?}", is_x86_feature_detected!("avxvnniint8"));
|
println!("avxvnniint8: {:?}", is_x86_feature_detected!("avxvnniint8"));
|
||||||
println!(
|
println!("avxneconvert: {:?}", is_x86_feature_detected!("avxneconvert"));
|
||||||
"avxneconvert: {:?}",
|
|
||||||
is_x86_feature_detected!("avxneconvert")
|
|
||||||
);
|
|
||||||
println!("avxifma: {:?}", is_x86_feature_detected!("avxifma"));
|
println!("avxifma: {:?}", is_x86_feature_detected!("avxifma"));
|
||||||
println!(
|
println!("avxvnniint16: {:?}", is_x86_feature_detected!("avxvnniint16"));
|
||||||
"avxvnniint16: {:?}",
|
|
||||||
is_x86_feature_detected!("avxvnniint16")
|
|
||||||
);
|
|
||||||
println!("amx-bf16: {:?}", is_x86_feature_detected!("amx-bf16"));
|
println!("amx-bf16: {:?}", is_x86_feature_detected!("amx-bf16"));
|
||||||
println!("amx-tile: {:?}", is_x86_feature_detected!("amx-tile"));
|
println!("amx-tile: {:?}", is_x86_feature_detected!("amx-tile"));
|
||||||
println!("amx-int8: {:?}", is_x86_feature_detected!("amx-int8"));
|
println!("amx-int8: {:?}", is_x86_feature_detected!("amx-int8"));
|
||||||
@@ -96,10 +76,7 @@ fn dump() {
|
|||||||
println!("widekl: {:?}", is_x86_feature_detected!("widekl"));
|
println!("widekl: {:?}", is_x86_feature_detected!("widekl"));
|
||||||
println!("movrs: {:?}", is_x86_feature_detected!("movrs"));
|
println!("movrs: {:?}", is_x86_feature_detected!("movrs"));
|
||||||
println!("amx-fp8: {:?}", is_x86_feature_detected!("amx-fp8"));
|
println!("amx-fp8: {:?}", is_x86_feature_detected!("amx-fp8"));
|
||||||
println!(
|
println!("amx-transpose: {:?}", is_x86_feature_detected!("amx-transpose"));
|
||||||
"amx-transpose: {:?}",
|
|
||||||
is_x86_feature_detected!("amx-transpose")
|
|
||||||
);
|
|
||||||
println!("amx-tf32: {:?}", is_x86_feature_detected!("amx-tf32"));
|
println!("amx-tf32: {:?}", is_x86_feature_detected!("amx-tf32"));
|
||||||
println!("amx-avx512: {:?}", is_x86_feature_detected!("amx-avx512"));
|
println!("amx-avx512: {:?}", is_x86_feature_detected!("amx-avx512"));
|
||||||
println!("amx-movrs: {:?}", is_x86_feature_detected!("amx-movrs"));
|
println!("amx-movrs: {:?}", is_x86_feature_detected!("amx-movrs"));
|
||||||
@@ -110,8 +87,5 @@ fn dump() {
|
|||||||
fn x86_deprecated() {
|
fn x86_deprecated() {
|
||||||
println!("avx512gfni {:?}", is_x86_feature_detected!("avx512gfni"));
|
println!("avx512gfni {:?}", is_x86_feature_detected!("avx512gfni"));
|
||||||
println!("avx512vaes {:?}", is_x86_feature_detected!("avx512vaes"));
|
println!("avx512vaes {:?}", is_x86_feature_detected!("avx512vaes"));
|
||||||
println!(
|
println!("avx512vpclmulqdq {:?}", is_x86_feature_detected!("avx512vpclmulqdq"));
|
||||||
"avx512vpclmulqdq {:?}",
|
|
||||||
is_x86_feature_detected!("avx512vpclmulqdq")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user