Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,203 changes: 851 additions & 352 deletions crates/core_arch/src/x86/avx512bf16.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions crates/std_detect/src/detect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ cfg_if! {
// On x86/x86_64 no OS specific functionality is required.
#[path = "os/x86.rs"]
mod os;
} else if #[cfg(all(target_os = "linux", feature = "use_std"))] {
} else if #[cfg(all(target_os = "linux", feature = "libc"))] {
#[path = "os/linux/mod.rs"]
mod os;
} else if #[cfg(all(target_os = "freebsd", feature = "use_std"))] {
} else if #[cfg(all(target_os = "freebsd", feature = "libc"))] {
#[cfg(target_arch = "aarch64")]
#[path = "os/aarch64.rs"]
mod aarch64;
Expand Down
12 changes: 6 additions & 6 deletions crates/std_detect/src/detect/os/freebsd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ mod auxvec;
cfg_if::cfg_if! {
if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::check_for;
pub(crate) use self::aarch64::detect_features;
} else if #[cfg(target_arch = "arm")] {
mod arm;
pub use self::arm::check_for;
pub(crate) use self::arm::detect_features;
} else if #[cfg(target_arch = "powerpc64")] {
mod powerpc;
pub use self::powerpc::check_for;
pub(crate) use self::powerpc::detect_features;
} else {
use crate::arch::detect::Feature;
use crate::detect::cache;
/// Performs run-time feature detection.
pub fn check_for(_x: Feature) -> bool {
false
pub(crate) fn detect_features() -> cache::Initializer {
cache::Initializer::default()
}
}
}
10 changes: 6 additions & 4 deletions crates/std_detect/src/detect/os/linux/aarch64.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Run-time feature detection for Aarch64 on Linux.

use super::{auxvec, cpuinfo};
use super::auxvec;
use crate::detect::{bit, cache, Feature};

/// Try to read the features from the auxiliary vector, and if that fails, try
Expand All @@ -10,7 +10,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
let hwcap: AtHwcap = auxv.into();
return hwcap.cache();
}
if let Ok(c) = cpuinfo::CpuInfo::new() {
#[cfg(feature = "std_detect_file_io")]
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
let hwcap: AtHwcap = c.into();
return hwcap.cache();
}
Expand Down Expand Up @@ -77,9 +78,10 @@ impl From<auxvec::AuxVec> for AtHwcap {
}
}

impl From<cpuinfo::CpuInfo> for AtHwcap {
#[cfg(feature = "std_detect_file_io")]
impl From<super::cpuinfo::CpuInfo> for AtHwcap {
/// Reads AtHwcap from /proc/cpuinfo .
fn from(c: cpuinfo::CpuInfo) -> Self {
fn from(c: super::cpuinfo::CpuInfo) -> Self {
let f = &c.field("Features");
AtHwcap {
// 64-bit names. FIXME: In 32-bit compatibility mode /proc/cpuinfo will
Expand Down
8 changes: 5 additions & 3 deletions crates/std_detect/src/detect/os/linux/arm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Run-time feature detection for ARM on Linux.

use super::{auxvec, cpuinfo};
use super::auxvec;
use crate::detect::{bit, cache, Feature};

/// Try to read the features from the auxiliary vector, and if that fails, try
Expand Down Expand Up @@ -31,7 +31,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
return value;
}

if let Ok(c) = cpuinfo::CpuInfo::new() {
#[cfg(feature = "std_detect_file_io")]
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
enable_feature(
&mut value,
Feature::neon,
Expand All @@ -55,7 +56,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
/// Is the CPU known to have a broken NEON unit?
///
/// See https://crbug.com/341598.
fn has_broken_neon(cpuinfo: &cpuinfo::CpuInfo) -> bool {
#[cfg(feature = "std_detect_file_io")]
fn has_broken_neon(cpuinfo: &super::cpuinfo::CpuInfo) -> bool {
cpuinfo.field("CPU implementer") == "0x51"
&& cpuinfo.field("CPU architecture") == "7"
&& cpuinfo.field("CPU variant") == "0x1"
Expand Down
89 changes: 66 additions & 23 deletions crates/std_detect/src/detect/os/linux/auxvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ use crate::{fs::File, io::Read};
/// Key to access the CPU Hardware capabilities bitfield.
pub(crate) const AT_HWCAP: usize = 16;
/// Key to access the CPU Hardware capabilities 2 bitfield.
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
pub(crate) const AT_HWCAP2: usize = 26;

/// Cache HWCAP bitfields of the ELF Auxiliary Vector.
Expand All @@ -17,7 +21,11 @@ pub(crate) const AT_HWCAP2: usize = 26;
#[derive(Debug, Copy, Clone)]
pub(crate) struct AuxVec {
pub hwcap: usize,
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
pub hwcap2: usize,
}

Expand Down Expand Up @@ -64,7 +72,11 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
}

// Targets with AT_HWCAP and AT_HWCAP2:
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
{
if let Ok(hwcap2) = getauxval(AT_HWCAP2) {
if hwcap != 0 && hwcap2 != 0 {
Expand All @@ -74,21 +86,11 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
}
drop(hwcap);
}
#[cfg(feature = "std_detect_file_io")]
{
// If calling getauxval fails, try to read the auxiliary vector from
// its file:
auxv_from_file("/proc/self/auxv")
}
#[cfg(not(feature = "std_detect_file_io"))]
{
Err(())
}
}

#[cfg(not(feature = "std_detect_dlsym_getauxval"))]
{
let hwcap = unsafe { ffi_getauxval(AT_HWCAP) };
let hwcap = unsafe { libc::getauxval(AT_HWCAP) };

// Targets with only AT_HWCAP:
#[cfg(any(target_arch = "aarch64", target_arch = "mips", target_arch = "mips64"))]
Expand All @@ -99,14 +101,29 @@ pub(crate) fn auxv() -> Result<AuxVec, ()> {
}

// Targets with AT_HWCAP and AT_HWCAP2:
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
{
let hwcap2 = unsafe { ffi_getauxval(AT_HWCAP2) };
let hwcap2 = unsafe { libc::getauxval(AT_HWCAP2) };
if hwcap != 0 && hwcap2 != 0 {
return Ok(AuxVec { hwcap, hwcap2 });
}
}
}

#[cfg(feature = "std_detect_file_io")]
{
// If calling getauxval fails, try to read the auxiliary vector from
// its file:
auxv_from_file("/proc/self/auxv")
}
#[cfg(not(feature = "std_detect_file_io"))]
{
Err(())
}
}

/// Tries to read the `key` from the auxiliary vector by calling the
Expand All @@ -122,7 +139,7 @@ fn getauxval(key: usize) -> Result<usize, ()> {
return Err(());
}

let ffi_getauxval: F = mem::transmute(ptr);
let ffi_getauxval: F = crate::mem::transmute(ptr);
Ok(ffi_getauxval(key))
}
}
Expand All @@ -140,7 +157,8 @@ fn auxv_from_file(file: &str) -> Result<AuxVec, ()> {
// 2*32 `usize` elements is enough to read the whole vector.
let mut buf = [0_usize; 64];
{
let raw: &mut [u8; 64 * mem::size_of::<usize>()] = unsafe { mem::transmute(&mut buf) };
let raw: &mut [u8; 64 * crate::mem::size_of::<usize>()] =
unsafe { crate::mem::transmute(&mut buf) };
file.read(raw).map_err(|_| ())?;
}
auxv_from_buf(&buf)
Expand All @@ -161,7 +179,11 @@ fn auxv_from_buf(buf: &[usize; 64]) -> Result<AuxVec, ()> {
}
}
// Targets with AT_HWCAP and AT_HWCAP2:
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
{
let mut hwcap = None;
let mut hwcap2 = None;
Expand Down Expand Up @@ -214,7 +236,12 @@ mod tests {

// FIXME: on mips/mips64 getauxval returns 0, and /proc/self/auxv
// does not always contain the AT_HWCAP key under qemu.
#[cfg(not(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc")))]
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
#[test]
fn auxv_crate() {
let v = auxv();
Expand All @@ -224,7 +251,11 @@ mod tests {
}

// Targets with AT_HWCAP and AT_HWCAP2:
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
{
if let Some(hwcap2) = auxv_crate_getauxval(AT_HWCAP2) {
let rt_hwcap2 = v.expect("failed to find hwcap2 key").hwcap2;
Expand All @@ -243,7 +274,7 @@ mod tests {
}

#[cfg(feature = "std_detect_file_io")]
cfg_if! {
cfg_if::cfg_if! {
if #[cfg(target_arch = "arm")] {
#[test]
fn linux_rpi3() {
Expand All @@ -264,6 +295,7 @@ mod tests {
// want to fall back to /proc/cpuinfo in this case, so
// reading should fail. assert_eq!(v.hwcap, 126614527);
// assert_eq!(v.hwcap2, 0);
let _ = v;
}
} else if #[cfg(target_arch = "aarch64")] {
#[test]
Expand All @@ -286,15 +318,26 @@ mod tests {
}
}

#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
#[test]
#[cfg(feature = "std_detect_file_io")]
fn auxv_crate_procfs() {
let v = auxv();
if let Some(hwcap) = auxv_crate_getprocfs(AT_HWCAP) {
assert_eq!(v.unwrap().hwcap, hwcap);
}

// Targets with AT_HWCAP and AT_HWCAP2:
#[cfg(any(target_arch = "arm", target_arch = "powerpc64"))]
#[cfg(any(
target_arch = "arm",
target_arch = "powerpc",
target_arch = "powerpc64"
))]
{
if let Some(hwcap2) = auxv_crate_getprocfs(AT_HWCAP2) {
assert_eq!(v.unwrap().hwcap2, hwcap2);
Expand Down
16 changes: 8 additions & 8 deletions crates/std_detect/src/detect/os/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ mod auxvec;
#[cfg(feature = "std_detect_file_io")]
mod cpuinfo;

cfg_if! {
cfg_if::cfg_if! {
if #[cfg(target_arch = "aarch64")] {
mod aarch64;
pub use self::aarch64::check_for;
pub(crate) use self::aarch64::detect_features;
} else if #[cfg(target_arch = "arm")] {
mod arm;
pub use self::arm::check_for;
pub(crate) use self::arm::detect_features;
} else if #[cfg(any(target_arch = "mips", target_arch = "mips64"))] {
mod mips;
pub use self::mips::check_for;
pub(crate) use self::mips::detect_features;
} else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] {
mod powerpc;
pub use self::powerpc::check_for;
pub(crate) use self::powerpc::detect_features;
} else {
use crate::detect::Feature;
use crate::detect::cache;
/// Performs run-time feature detection.
pub fn check_for(_x: Feature) -> bool {
false
pub(crate) fn detect_features() -> cache::Initializer {
cache::Initializer::default()
}
}
}
5 changes: 3 additions & 2 deletions crates/std_detect/src/detect/os/linux/powerpc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Run-time feature detection for PowerPC on Linux.

use super::{auxvec, cpuinfo};
use super::auxvec;
use crate::detect::{cache, Feature};

/// Try to read the features from the auxiliary vector, and if that fails, try
Expand All @@ -27,7 +27,8 @@ pub(crate) fn detect_features() -> cache::Initializer {

// PowerPC's /proc/cpuinfo lacks a proper Feature field,
// but `altivec` support is indicated in the `cpu` field.
if let Ok(c) = cpuinfo::CpuInfo::new() {
#[cfg(feature = "std_detect_file_io")]
if let Ok(c) = super::cpuinfo::CpuInfo::new() {
enable_feature(&mut value, Feature::altivec, c.field("cpu").has("altivec"));
return value;
}
Expand Down