refactor no_std components into the coresimd crate
This commit is contained in:
parent
dc9f076480
commit
14d0903309
62 changed files with 471 additions and 192 deletions
4
library/stdarch/.gitignore
vendored
4
library/stdarch/.gitignore
vendored
|
|
@ -2,3 +2,7 @@ Cargo.lock
|
|||
.*.swp
|
||||
/target
|
||||
tags
|
||||
/coresimd/target
|
||||
/stdsimd-test/target
|
||||
/stdsimd-test/assert-instr-macro/target
|
||||
/stdsimd-test/simd-test-macro/target
|
||||
|
|
@ -25,6 +25,8 @@ matrix:
|
|||
script: |
|
||||
cargo install clippy
|
||||
cargo clippy --all -- -D clippy-pedantic
|
||||
cd coresimd
|
||||
cargo clippy --all -- -D clippy-pedantic
|
||||
allow_failures:
|
||||
- env: RUSTFMT=On TARGET=x86_64-unknown-linux-gnu NO_ADD=1
|
||||
- env: CLIPPY=On TARGET=x86_64-unknown-linux-gnu NO_ADD=1
|
||||
|
|
@ -32,7 +34,6 @@ install:
|
|||
- if [ "$NO_ADD" == "" ]; then rustup target add $TARGET; fi
|
||||
|
||||
script:
|
||||
- cargo generate-lockfile
|
||||
- ci/run-docker.sh $TARGET $FEATURES
|
||||
|
||||
notifications:
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
name = "stdsimd"
|
||||
version = "0.0.3"
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = "Experiments for adding SIMD support to Rust's standard library."
|
||||
description = "SIMD support in Rust's standard library."
|
||||
documentation = "https://docs.rs/stdsimd"
|
||||
homepage = "https://github.com/BurntSushi/stdsimd"
|
||||
repository = "https://github.com/BurntSushi/stdsimd"
|
||||
readme = "README.md"
|
||||
keywords = ["std", "simd", "intrinsics"]
|
||||
categories = ["hardware-support", "no-std"]
|
||||
categories = ["hardware-support"]
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
[badges]
|
||||
|
|
@ -18,6 +18,9 @@ is-it-maintained-issue-resolution = { repository = "BurntSushi/stdsimd" }
|
|||
is-it-maintained-open-issues = { repository = "BurntSushi/stdsimd" }
|
||||
maintenance = { status = "experimental" }
|
||||
|
||||
[dependencies]
|
||||
coresimd = { version = "0.0.3", path = "coresimd/" }
|
||||
|
||||
[profile.release]
|
||||
debug = true
|
||||
opt-level = 3
|
||||
|
|
@ -31,10 +34,8 @@ stdsimd-test = { version = "0.*", path = "stdsimd-test" }
|
|||
cupid = "0.5.0"
|
||||
|
||||
[features]
|
||||
std = []
|
||||
|
||||
# Internal-only: denies all warnings.
|
||||
strict = []
|
||||
# Internal-only: enables only those intrinsics supported by Intel's
|
||||
# Internal-usage only: denies all warnings.
|
||||
strict = [ "coresimd/strict" ]
|
||||
# Internal-usage only: enables only those intrinsics supported by Intel's
|
||||
# Software Development Environment (SDE).
|
||||
intel_sde = []
|
||||
intel_sde = [ "coresimd/intel_sde" ]
|
||||
|
|
@ -19,7 +19,7 @@ run() {
|
|||
--env TARGET=$target \
|
||||
--env FEATURES=$2 \
|
||||
--env STDSIMD_TEST_EVERYTHING \
|
||||
--volume `pwd`:/checkout:ro \
|
||||
--volume `pwd`:/checkout \
|
||||
--volume `pwd`/target:/checkout/target \
|
||||
--workdir /checkout \
|
||||
--privileged \
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ case ${TARGET} in
|
|||
esac
|
||||
|
||||
FEATURES="strict,$FEATURES"
|
||||
FEATURES_STD="$std,${FEATURES}"
|
||||
|
||||
echo "RUSTFLAGS=${RUSTFLAGS}"
|
||||
echo "FEATURES=${FEATURES}"
|
||||
echo "OBJDUMP=${OBJDUMP}"
|
||||
|
||||
cargo test --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
cargo test --release --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
|
||||
cargo test --target $TARGET --features $FEATURES_STD --verbose -- --nocapture
|
||||
cargo test --release --target $TARGET --features $FEATURES_STD --verbose -- --nocapture
|
||||
cd coresimd
|
||||
cargo test --all --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
cargo test --all --release --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
cd ..
|
||||
cargo test --all --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
cargo test --all --release --target $TARGET --features $FEATURES --verbose -- --nocapture
|
||||
|
|
|
|||
29
library/stdarch/coresimd/Cargo.toml
Normal file
29
library/stdarch/coresimd/Cargo.toml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
[package]
|
||||
name = "coresimd"
|
||||
version = "0.0.3"
|
||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
||||
description = "SIMD support in Rust's core library."
|
||||
documentation = "https://docs.rs/stdsimd"
|
||||
homepage = "https://github.com/BurntSushi/stdsimd"
|
||||
repository = "https://github.com/BurntSushi/stdsimd"
|
||||
readme = "README.md"
|
||||
keywords = ["core", "simd", "intrinsics"]
|
||||
categories = ["hardware-support", "no-std"]
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "BurntSushi/stdsimd" }
|
||||
appveyor = { repository = "BurntSushi/stdsimd" }
|
||||
is-it-maintained-issue-resolution = { repository = "BurntSushi/stdsimd" }
|
||||
is-it-maintained-open-issues = { repository = "BurntSushi/stdsimd" }
|
||||
maintenance = { status = "experimental" }
|
||||
|
||||
[dev-dependencies]
|
||||
stdsimd-test = { version = "0.*", path = "../stdsimd-test" }
|
||||
|
||||
[features]
|
||||
# Internal-usage only: denies all warnings.
|
||||
strict = []
|
||||
# Internal-usage only: enables only those intrinsics supported by Intel's
|
||||
# Software Development Environment (SDE).
|
||||
intel_sde = []
|
||||
1
library/stdarch/coresimd/LICENSE-APACHE
Symbolic link
1
library/stdarch/coresimd/LICENSE-APACHE
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../LICENSE-APACHE
|
||||
1
library/stdarch/coresimd/LICENSE-MIT
Symbolic link
1
library/stdarch/coresimd/LICENSE-MIT
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../LICENSE-MIT
|
||||
1
library/stdarch/coresimd/README.md
Symbolic link
1
library/stdarch/coresimd/README.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../README.md
|
||||
1
library/stdarch/coresimd/rustfmt.toml
Symbolic link
1
library/stdarch/coresimd/rustfmt.toml
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../rustfmt.toml
|
||||
231
library/stdarch/coresimd/src/lib.rs
Normal file
231
library/stdarch/coresimd/src/lib.rs
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
//! SIMD support
|
||||
//!
|
||||
//! This crate provides the fundamentals of supporting SIMD in Rust. This crate
|
||||
//! should compile on all platforms and provide `simd` and `vendor` modules at
|
||||
//! the top-level. The `simd` module contains *portable vector types* which
|
||||
//! should work across all platforms and be implemented in the most efficient
|
||||
//! manner possible for the platform at hand. The `vendor` module contains
|
||||
//! vendor intrinsics that operate over these SIMD types, typically
|
||||
//! corresponding to a particular CPU instruction
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate coresimd as stdsimd;
|
||||
//! use stdsimd::simd::u32x4;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let a = u32x4::new(1, 2, 3, 4);
|
||||
//! let b = u32x4::splat(10);
|
||||
//! assert_eq!(a + b, u32x4::new(11, 12, 13, 14));
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! > **Note**: This crate is *nightly only* at the moment, and requires a
|
||||
//! > nightly rust toolchain to compile.
|
||||
//!
|
||||
//! This documentation is only for one particular architecture, you can find
|
||||
//! others at:
|
||||
//!
|
||||
//! * [i686](https://rust-lang-nursery.github.io/stdsimd/i686/stdsimd/)
|
||||
//! * [`x86_64`](https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/)
|
||||
//! * [arm](https://rust-lang-nursery.github.io/stdsimd/arm/stdsimd/)
|
||||
//! * [aarch64](https://rust-lang-nursery.github.io/stdsimd/aarch64/stdsimd/)
|
||||
//!
|
||||
//! ## Portability
|
||||
//!
|
||||
//! The `simd` module and its types should be portable to all platforms. The
|
||||
//! runtime characteristics of these types may vary per platform and per CPU
|
||||
//! feature enabled, but they should always have the most optimized
|
||||
//! implementation for the target at hand.
|
||||
//!
|
||||
//! The `vendor` module provides no portability guarantees. The `vendor` module
|
||||
//! is per CPU architecture currently and provides intrinsics corresponding to
|
||||
//! functions for that particular CPU architecture. Note that the functions
|
||||
//! provided in this module are intended to correspond to CPU instructions and
|
||||
//! have no runtime support for whether you CPU actually supports the
|
||||
//! instruction.
|
||||
//!
|
||||
//! CPU target feature detection is done via the `cfg_feature_enabled!` macro
|
||||
//! at runtime. This macro will detect at runtime whether the specified feature
|
||||
//! is available or not, returning true or false depending on the current CPU.
|
||||
//!
|
||||
//! ```
|
||||
//! #![feature(cfg_target_feature)]
|
||||
//!
|
||||
//! #[macro_use]
|
||||
//! extern crate coresimd as stdsimd;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! if cfg_feature_enabled!("avx2") {
|
||||
//! println!("avx2 intrinsics will work");
|
||||
//! } else {
|
||||
//! println!("avx2 intrinsics will not work");
|
||||
//! // undefined behavior: may generate a `SIGILL`.
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! After verifying that a specified feature is available, use `target_feature`
|
||||
//! to enable a given feature and use the desired intrinsic.
|
||||
//!
|
||||
//! ```ignore
|
||||
//! # #![feature(cfg_target_feature)]
|
||||
//! # #![feature(target_feature)]
|
||||
//! # #[macro_use]
|
||||
//! # extern crate coresimd as stdsimd;
|
||||
//! # fn main() {
|
||||
//! # if cfg_feature_enabled!("avx2") {
|
||||
//! // avx2 specific code may be used in this function
|
||||
//! #[target_feature = "+avx2"]
|
||||
//! fn and_256() {
|
||||
//! // avx2 feature specific intrinsics will work here!
|
||||
//! use stdsimd::vendor::{__m256i, _mm256_and_si256};
|
||||
//!
|
||||
//! let a = __m256i::splat(5);
|
||||
//! let b = __m256i::splat(3);
|
||||
//!
|
||||
//! let got = unsafe { _mm256_and_si256(a, b) };
|
||||
//!
|
||||
//! assert_eq!(got, __m256i::splat(1));
|
||||
//! }
|
||||
//! # and_256();
|
||||
//! # }
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! # Status
|
||||
//!
|
||||
//! This crate is intended for eventual inclusion into the standard library,
|
||||
//! but some work and experimentation is needed to get there! First and
|
||||
//! foremost you can help out by kicking the tires on this crate and seeing if
|
||||
//! it works for your use case! Next up you can help us fill out the [vendor
|
||||
//! intrinsics][vendor] to ensure that we've got all the SIMD support
|
||||
//! necessary.
|
||||
//!
|
||||
//! The language support and status of SIMD is also still a little up in the
|
||||
//! air right now, you may be interested in a few issues along these lines:
|
||||
//!
|
||||
//! * [Overal tracking issue for SIMD support][simd_tracking_issue]
|
||||
//! * [`cfg_target_feature` tracking issue][cfg_target_feature_issue]
|
||||
//! * [SIMD types currently not sound][simd_soundness_bug]
|
||||
//! * [`#[target_feature]` improvements][target_feature_impr]
|
||||
//!
|
||||
//! [vendor]: https://github.com/rust-lang-nursery/stdsimd/issues/40
|
||||
//! [simd_tracking_issue]: https://github.com/rust-lang/rust/issues/27731
|
||||
//! [cfg_target_feature_issue]: https://github.com/rust-lang/rust/issues/29717
|
||||
//! [simd_soundness_bug]: https://github.com/rust-lang/rust/issues/44367
|
||||
//! [target_feature_impr]: https://github.com/rust-lang/rust/issues/44839
|
||||
|
||||
#![cfg_attr(feature = "strict", deny(warnings))]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_features)]
|
||||
#![feature(const_fn, link_llvm_intrinsics, platform_intrinsics, repr_simd,
|
||||
simd_ffi, target_feature, cfg_target_feature, i128_type, asm,
|
||||
const_atomic_usize_new, stmt_expr_attributes)]
|
||||
#![cfg_attr(test, feature(proc_macro, test, repr_align, attr_literals))]
|
||||
#![cfg_attr(feature = "cargo-clippy",
|
||||
allow(inline_always, too_many_arguments, cast_sign_loss,
|
||||
cast_lossless, cast_possible_wrap,
|
||||
cast_possible_truncation, cast_precision_loss,
|
||||
shadow_reuse, cyclomatic_complexity, similar_names,
|
||||
many_single_char_names))]
|
||||
#![no_std]
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate stdsimd_test;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
/// Platform independent SIMD vector types and operations.
|
||||
pub mod simd {
|
||||
pub use v128::*;
|
||||
pub use v256::*;
|
||||
pub use v512::*;
|
||||
pub use v64::*;
|
||||
}
|
||||
|
||||
/// Platform dependent vendor intrinsics.
|
||||
pub mod vendor {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub use x86::*;
|
||||
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
pub use arm::*;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::*;
|
||||
|
||||
// FIXME: rust does not expose the nvptx and nvptx64 targets yet
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64",
|
||||
target_arch = "arm", target_arch = "aarch64")))]
|
||||
pub use nvptx::*;
|
||||
|
||||
#[cfg(
|
||||
// x86/x86_64:
|
||||
any(target_arch = "x86", target_arch = "x86_64")
|
||||
)]
|
||||
pub use runtime::{__unstable_detect_feature, __Feature};
|
||||
}
|
||||
|
||||
#[cfg(
|
||||
// x86/x86_64:
|
||||
any(target_arch = "x86", target_arch = "x86_64")
|
||||
)]
|
||||
#[macro_use]
|
||||
mod runtime;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod simd_llvm;
|
||||
mod v128;
|
||||
mod v256;
|
||||
mod v512;
|
||||
mod v64;
|
||||
|
||||
/// 32-bit wide vector tpyes
|
||||
mod v32 {
|
||||
use simd_llvm::*;
|
||||
|
||||
define_ty! { i16x2, i16, i16 }
|
||||
define_impl! { i16x2, i16, 2, i16x2, x0, x1 }
|
||||
define_ty! { u16x2, u16, u16 }
|
||||
define_impl! { u16x2, u16, 2, i16x2, x0, x1 }
|
||||
|
||||
define_ty! { i8x4, i8, i8, i8, i8 }
|
||||
define_impl! { i8x4, i8, 4, i8x4, x0, x1, x2, x3 }
|
||||
define_ty! { u8x4, u8, u8, u8, u8 }
|
||||
define_impl! { u8x4, u8, 4, i8x4, x0, x1, x2, x3 }
|
||||
|
||||
define_casts!(
|
||||
(i16x2, i64x2, as_i64x2),
|
||||
(u16x2, i64x2, as_i64x2),
|
||||
(i8x4, i32x4, as_i32x4),
|
||||
(u8x4, i32x4, as_i32x4)
|
||||
);
|
||||
}
|
||||
|
||||
/// 16-bit wide vector tpyes
|
||||
mod v16 {
|
||||
use simd_llvm::*;
|
||||
|
||||
define_ty! { i8x2, i8, i8 }
|
||||
define_impl! { i8x2, i8, 2, i8x2, x0, x1 }
|
||||
define_ty! { u8x2, u8, u8 }
|
||||
define_impl! { u8x2, u8, 2, i8x2, x0, x1 }
|
||||
|
||||
define_casts!((i8x2, i64x2, as_i64x2), (u8x2, i64x2, as_i64x2));
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
mod x86;
|
||||
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
mod arm;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
|
||||
mod nvptx;
|
||||
11
library/stdarch/coresimd/src/runtime/bit.rs
Normal file
11
library/stdarch/coresimd/src/runtime/bit.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
//! Bit manipulation utilities
|
||||
|
||||
/// Sets the `bit` of `x`.
|
||||
pub const fn set(x: usize, bit: u32) -> usize {
|
||||
x | 1 << bit
|
||||
}
|
||||
|
||||
/// Tests the `bit` of `x`.
|
||||
pub const fn test(x: usize, bit: u32) -> bool {
|
||||
x & (1 << bit) != 0
|
||||
}
|
||||
31
library/stdarch/coresimd/src/runtime/cache.rs
Normal file
31
library/stdarch/coresimd/src/runtime/cache.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
//! Cache of run-time feature detection
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use core::usize;
|
||||
|
||||
use super::bit;
|
||||
|
||||
/// This global variable is a bitset used to cache the features supported by
|
||||
/// the
|
||||
/// CPU.
|
||||
static CACHE: AtomicUsize = AtomicUsize::new(usize::MAX);
|
||||
|
||||
/// Test the `bit` of the storage. If the storage has not been initialized,
|
||||
/// initializes it with the result of `f()`.
|
||||
///
|
||||
/// On its first invocation, it detects the CPU features and caches them in the
|
||||
/// `FEATURES` global variable as an `AtomicUsize`.
|
||||
///
|
||||
/// It uses the `__Feature` variant to index into this variable as a bitset. If
|
||||
/// the bit is set, the feature is enabled, and otherwise it is disabled.
|
||||
///
|
||||
/// PLEASE: do not use this, it is an implementation detail subject to change.
|
||||
pub fn test<F>(bit: u32, f: F) -> bool
|
||||
where
|
||||
F: FnOnce() -> usize,
|
||||
{
|
||||
if CACHE.load(Ordering::Relaxed) == usize::MAX {
|
||||
CACHE.store(f(), Ordering::Relaxed);
|
||||
}
|
||||
bit::test(CACHE.load(Ordering::Relaxed), bit)
|
||||
}
|
||||
39
library/stdarch/coresimd/src/runtime/macros.rs
Normal file
39
library/stdarch/coresimd/src/runtime/macros.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//! Run-time feature detection macros.
|
||||
|
||||
/// Is a feature supported by the host CPU?
|
||||
///
|
||||
/// This macro performs run-time feature detection. It returns true if the host
|
||||
/// CPU in which the binary is running on supports a particular feature.
|
||||
#[macro_export]
|
||||
macro_rules! cfg_feature_enabled {
|
||||
($name:tt) => (
|
||||
{
|
||||
#[cfg(target_feature = $name)]
|
||||
{
|
||||
true
|
||||
}
|
||||
#[cfg(not(target_feature = $name))]
|
||||
{
|
||||
__unstable_detect_feature!($name)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// In all unsupported architectures using the macro is an error
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64",
|
||||
target_arch = "arm", target_arch = "aarch64")))]
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __unstable_detect_feature {
|
||||
($t:tt) => { compile_error!(concat!("unknown target feature: ", $t)) };
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[test]
|
||||
fn test_macros() {
|
||||
assert!(cfg_feature_enabled!("sse"));
|
||||
}
|
||||
}
|
||||
20
library/stdarch/coresimd/src/runtime/mod.rs
Normal file
20
library/stdarch/coresimd/src/runtime/mod.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
//! Run-time feature detection
|
||||
mod cache;
|
||||
mod bit;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[macro_use]
|
||||
mod x86;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub use self::x86::__Feature;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use self::x86::detect_features;
|
||||
|
||||
/// Performs run-time feature detection.
|
||||
#[doc(hidden)]
|
||||
pub fn __unstable_detect_feature(x: __Feature) -> bool {
|
||||
cache::test(x as u32, detect_features)
|
||||
}
|
||||
|
|
@ -364,8 +364,8 @@ pub fn detect_features() -> usize {
|
|||
enable(extended_features_ebx, 5, __Feature::avx2);
|
||||
|
||||
// For AVX-512 the OS also needs to support saving/restoring
|
||||
// the
|
||||
// extended state, only then we enable AVX-512 support:
|
||||
// the extended state, only then we enable
|
||||
// AVX-512 support:
|
||||
if os_avx512_support {
|
||||
enable(extended_features_ebx, 16, __Feature::avx512f);
|
||||
enable(extended_features_ebx, 17, __Feature::avx512dq);
|
||||
|
|
@ -15,8 +15,7 @@
|
|||
//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
|
||||
//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
|
||||
//! [wikipedia_bmi]:
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.
|
||||
//! 28Advanced_Bit_Manipulation.29
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29
|
||||
|
||||
#[cfg(test)]
|
||||
use stdsimd_test::assert_instr;
|
||||
|
|
@ -326,9 +326,9 @@ pub unsafe fn _mm256_div_pd(a: f64x4, b: f64x4) -> f64x4 {
|
|||
/// - `0x02`: Round up, toward positive infinity.
|
||||
/// - `0x03`: Truncate the values.
|
||||
///
|
||||
/// For a complete list of options, check the LLVM docs:
|
||||
/// For a complete list of options, check [the LLVM docs][llvm_docs].
|
||||
///
|
||||
/// https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382
|
||||
/// [llvm_docs]: https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382
|
||||
#[inline(always)]
|
||||
#[target_feature = "+avx"]
|
||||
#[cfg_attr(test, assert_instr(vroundpd, b = 0x3))]
|
||||
|
|
@ -1578,7 +1578,7 @@ pub unsafe fn _mm256_shuffle_epi8(a: u8x32, b: u8x32) -> u8x32 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2015,7 +2015,7 @@ pub unsafe fn _mm256_subs_epu8(a: u8x32, b: u8x32) -> u8x32 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2064,7 +2064,7 @@ pub unsafe fn _mm256_unpackhi_epi8(a: i8x32, b: i8x32) -> i8x32 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2112,7 +2112,7 @@ pub unsafe fn _mm256_unpacklo_epi8(a: i8x32, b: i8x32) -> i8x32 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2156,7 +2156,7 @@ pub unsafe fn _mm256_unpackhi_epi16(a: i16x16, b: i16x16) -> i16x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2200,7 +2200,7 @@ pub unsafe fn _mm256_unpacklo_epi16(a: i16x16, b: i16x16) -> i16x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2239,7 +2239,7 @@ pub unsafe fn _mm256_unpackhi_epi32(a: i32x8, b: i32x8) -> i32x8 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2278,7 +2278,7 @@ pub unsafe fn _mm256_unpacklo_epi32(a: i32x8, b: i32x8) -> i32x8 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -2317,7 +2317,7 @@ pub unsafe fn _mm256_unpackhi_epi64(a: i64x4, b: i64x4) -> i64x4 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("avx2") {
|
||||
|
|
@ -7,10 +7,7 @@
|
|||
//! available.
|
||||
//!
|
||||
//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
|
||||
//! [wikipedia_bmi]:
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.
|
||||
//! 28Advanced_Bit_Manipulation.29
|
||||
|
||||
//! [wikipedia_bmi]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29
|
||||
|
||||
#[cfg(test)]
|
||||
use stdsimd_test::assert_instr;
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
//!
|
||||
//! [intel64_ref]: http://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
|
||||
//! [wikipedia_bmi]:
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.
|
||||
//! 28Advanced_Bit_Manipulation.29
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29
|
||||
|
||||
#[cfg(test)]
|
||||
use stdsimd_test::assert_instr;
|
||||
|
|
@ -885,7 +885,7 @@ pub unsafe fn _mm_movemask_ps(a: f32x4) -> i32 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # // The real main function
|
||||
/// # fn main() {
|
||||
|
|
@ -937,7 +937,7 @@ pub unsafe fn _mm_loadh_pi(a: f32x4, p: *const f32) -> f32x4 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # // The real main function
|
||||
/// # fn main() {
|
||||
|
|
@ -504,7 +504,7 @@ pub unsafe fn _mm_ceil_ss(a: f32x4, b: f32x4) -> f32x4 {
|
|||
/// Rounding is done according to the rounding parameter, which can be one of:
|
||||
///
|
||||
/// ```
|
||||
/// use stdsimd::vendor;
|
||||
/// use coresimd::vendor;
|
||||
///
|
||||
/// // round to nearest, and suppress exceptions:
|
||||
/// (vendor::_MM_FROUND_TO_NEAREST_INT |vendor::_MM_FROUND_NO_EXC);
|
||||
|
|
@ -533,7 +533,7 @@ pub unsafe fn _mm_round_pd(a: f64x2, rounding: i32) -> f64x2 {
|
|||
/// Rounding is done according to the rounding parameter, which can be one of:
|
||||
///
|
||||
/// ```
|
||||
/// use stdsimd::vendor;
|
||||
/// use coresimd::vendor;
|
||||
///
|
||||
/// // round to nearest, and suppress exceptions:
|
||||
/// (vendor::_MM_FROUND_TO_NEAREST_INT |vendor::_MM_FROUND_NO_EXC);
|
||||
|
|
@ -564,7 +564,7 @@ pub unsafe fn _mm_round_ps(a: f32x4, rounding: i32) -> f32x4 {
|
|||
/// Rounding is done according to the rounding parameter, which can be one of:
|
||||
///
|
||||
/// ```
|
||||
/// use stdsimd::vendor;
|
||||
/// use coresimd::vendor;
|
||||
///
|
||||
/// // round to nearest, and suppress exceptions:
|
||||
/// (vendor::_MM_FROUND_TO_NEAREST_INT |vendor::_MM_FROUND_NO_EXC);
|
||||
|
|
@ -595,7 +595,7 @@ pub unsafe fn _mm_round_sd(a: f64x2, b: f64x2, rounding: i32) -> f64x2 {
|
|||
/// Rounding is done according to the rounding parameter, which can be one of:
|
||||
///
|
||||
/// ```
|
||||
/// use stdsimd::vendor;
|
||||
/// use coresimd::vendor;
|
||||
///
|
||||
/// // round to nearest, and suppress exceptions:
|
||||
/// (vendor::_MM_FROUND_TO_NEAREST_INT |vendor::_MM_FROUND_NO_EXC);
|
||||
|
|
@ -96,7 +96,7 @@ pub unsafe fn _mm_cmpistrm(a: __m128i, b: __m128i, imm8: i8) -> u8x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
|
|
@ -139,7 +139,7 @@ pub unsafe fn _mm_cmpistrm(a: __m128i, b: __m128i, imm8: i8) -> u8x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
|
|
@ -180,7 +180,7 @@ pub unsafe fn _mm_cmpistrm(a: __m128i, b: __m128i, imm8: i8) -> u8x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
|
|
@ -219,7 +219,7 @@ pub unsafe fn _mm_cmpistrm(a: __m128i, b: __m128i, imm8: i8) -> u8x16 {
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
|
|
@ -392,7 +392,7 @@ pub unsafe fn _mm_cmpestrm(
|
|||
/// # #![feature(cfg_target_feature)]
|
||||
/// # #![feature(target_feature)]
|
||||
/// #
|
||||
/// # #[macro_use] extern crate stdsimd;
|
||||
/// # #[macro_use] extern crate coresimd as stdsimd;
|
||||
/// #
|
||||
/// # fn main() {
|
||||
/// # if cfg_feature_enabled!("sse4.2") {
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
//!
|
||||
//! [amd64_ref]: http://support.amd.com/TechDocs/24594.pdf
|
||||
//! [wikipedia_bmi]:
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.
|
||||
//! 28Advanced_Bit_Manipulation.29
|
||||
//! https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#ABM_.28Advanced_Bit_Manipulation.29
|
||||
|
||||
#[cfg(test)]
|
||||
use stdsimd_test::assert_instr;
|
||||
|
|
@ -104,139 +104,41 @@
|
|||
//! The language support and status of SIMD is also still a little up in the
|
||||
//! air right now, you may be interested in a few issues along these lines:
|
||||
//!
|
||||
//! * [Overal tracking issue for SIMD support]
|
||||
//! (https://github.com/rust-lang/rust/issues/27731)
|
||||
//! * [`cfg_target_feature` tracking issue]
|
||||
//! (https://github.com/rust-lang/rust/issues/29717)
|
||||
//! * [SIMD types currently not sound]
|
||||
//! (https://github.com/rust-lang/rust/issues/44367)
|
||||
//! * [`#[target_feature]` improvements]
|
||||
//! (https://github.com/rust-lang/rust/issues/44839)
|
||||
//! * [Overal tracking issue for SIMD support][simd_tracking_issue]
|
||||
//! * [`cfg_target_feature` tracking issue][cfg_target_feature_issue]
|
||||
//! * [SIMD types currently not sound][simd_soundness_bug]
|
||||
//! * [`#[target_feature]` improvements][target_feature_impr]
|
||||
//!
|
||||
//! [vendor]: https://github.com/rust-lang-nursery/stdsimd/issues/40
|
||||
//! [simd_tracking_issue]: https://github.com/rust-lang/rust/issues/27731
|
||||
//! [cfg_target_feature_issue]: https://github.com/rust-lang/rust/issues/29717
|
||||
//! [simd_soundness_bug]: https://github.com/rust-lang/rust/issues/44367
|
||||
//! [target_feature_impr]: https://github.com/rust-lang/rust/issues/44839
|
||||
|
||||
#![cfg_attr(feature = "strict", deny(warnings))]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_features)]
|
||||
#![feature(const_fn, link_llvm_intrinsics, platform_intrinsics, repr_simd,
|
||||
simd_ffi, target_feature, cfg_target_feature, i128_type, asm,
|
||||
const_atomic_usize_new, stmt_expr_attributes)]
|
||||
#![cfg_attr(test, feature(proc_macro, test, repr_align, attr_literals))]
|
||||
#![cfg_attr(feature = "cargo-clippy",
|
||||
allow(inline_always, too_many_arguments, cast_sign_loss,
|
||||
cast_lossless, cast_possible_wrap,
|
||||
cast_possible_truncation, cast_precision_loss,
|
||||
shadow_reuse, cyclomatic_complexity, similar_names,
|
||||
doc_markdown, many_single_char_names))]
|
||||
#![no_std]
|
||||
#![feature(macro_reexport, const_fn, const_atomic_usize_new)]
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
/// We re-export run-time feature detection for those architectures that have
|
||||
/// suport for it in `core`:
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[macro_reexport(cfg_feature_enabled, __unstable_detect_feature)]
|
||||
extern crate coresimd;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate stdsimd_test;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
/// Platform independent SIMD vector types and operations.
|
||||
pub mod simd {
|
||||
pub use v128::*;
|
||||
pub use v256::*;
|
||||
pub use v512::*;
|
||||
pub use v64::*;
|
||||
}
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
extern crate coresimd;
|
||||
|
||||
/// Platform dependent vendor intrinsics.
|
||||
pub mod vendor {
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub use x86::*;
|
||||
pub use coresimd::vendor::*;
|
||||
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
pub use arm::*;
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
pub use aarch64::*;
|
||||
|
||||
// FIXME: rust does not expose the nvptx and nvptx64 targets yet
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64",
|
||||
target_arch = "arm", target_arch = "aarch64")))]
|
||||
pub use nvptx::*;
|
||||
|
||||
#[cfg(any(
|
||||
// x86/x86_64:
|
||||
any(target_arch = "x86", target_arch = "x86_64"),
|
||||
// linux + std + (arm|aarch64):
|
||||
all(target_os = "linux",
|
||||
feature = "std",
|
||||
any(target_arch = "arm", target_arch = "aarch64"))
|
||||
))]
|
||||
pub use runtime::{__unstable_detect_feature, __Feature};
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
pub use super::runtime::{__unstable_detect_feature, __Feature};
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
// x86/x86_64:
|
||||
any(target_arch = "x86", target_arch = "x86_64"),
|
||||
// linux + std + (arm|aarch64):
|
||||
all(target_os = "linux",
|
||||
feature = "std",
|
||||
any(target_arch = "arm", target_arch = "aarch64"))
|
||||
))]
|
||||
/// Platform independent SIMD vector types and operations.
|
||||
pub mod simd {
|
||||
pub use coresimd::simd::*;
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
#[macro_use]
|
||||
mod runtime;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod simd_llvm;
|
||||
mod v128;
|
||||
mod v256;
|
||||
mod v512;
|
||||
mod v64;
|
||||
|
||||
/// 32-bit wide vector tpyes
|
||||
mod v32 {
|
||||
use simd_llvm::*;
|
||||
|
||||
define_ty! { i16x2, i16, i16 }
|
||||
define_impl! { i16x2, i16, 2, i16x2, x0, x1 }
|
||||
define_ty! { u16x2, u16, u16 }
|
||||
define_impl! { u16x2, u16, 2, i16x2, x0, x1 }
|
||||
|
||||
define_ty! { i8x4, i8, i8, i8, i8 }
|
||||
define_impl! { i8x4, i8, 4, i8x4, x0, x1, x2, x3 }
|
||||
define_ty! { u8x4, u8, u8, u8, u8 }
|
||||
define_impl! { u8x4, u8, 4, i8x4, x0, x1, x2, x3 }
|
||||
|
||||
define_casts!(
|
||||
(i16x2, i64x2, as_i64x2),
|
||||
(u16x2, i64x2, as_i64x2),
|
||||
(i8x4, i32x4, as_i32x4),
|
||||
(u8x4, i32x4, as_i32x4)
|
||||
);
|
||||
}
|
||||
|
||||
/// 16-bit wide vector tpyes
|
||||
mod v16 {
|
||||
use simd_llvm::*;
|
||||
|
||||
define_ty! { i8x2, i8, i8 }
|
||||
define_impl! { i8x2, i8, 2, i8x2, x0, x1 }
|
||||
define_ty! { u8x2, u8, u8 }
|
||||
define_impl! { u8x2, u8, 2, i8x2, x0, x1 }
|
||||
|
||||
define_casts!((i8x2, i64x2, as_i64x2), (u8x2, i64x2, as_i64x2));
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
mod x86;
|
||||
|
||||
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||
mod arm;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
mod aarch64;
|
||||
|
||||
// FIXME: rust does not expose the nvptx and nvptx64 targets yet
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64",
|
||||
target_arch = "arm", target_arch = "aarch64")))]
|
||||
mod nvptx;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Cache of run-time feature detection
|
||||
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use core::usize;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::usize;
|
||||
|
||||
use super::bit;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ impl<'a> CpuInfoField<'a> {
|
|||
}
|
||||
}
|
||||
/// Does the field exist?
|
||||
#[cfg(test)]
|
||||
pub fn exists(&self) -> bool {
|
||||
self.0.is_some()
|
||||
}
|
||||
|
|
@ -61,17 +62,19 @@ impl CpuInfo {
|
|||
pub fn field(&self, field: &str) -> CpuInfoField {
|
||||
for l in self.raw.lines() {
|
||||
if l.trim().starts_with(field) {
|
||||
return CpuInfoField(l.split(": ").skip(1).next());
|
||||
return CpuInfoField::new(l.split(": ").skip(1).next());
|
||||
}
|
||||
}
|
||||
CpuInfoField(None)
|
||||
}
|
||||
|
||||
/// Returns the `raw` contents of `/proc/cpuinfo`
|
||||
#[cfg(test)]
|
||||
fn raw(&self) -> &String {
|
||||
&self.raw
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn from_str(other: &str) -> Result<CpuInfo, ::std::io::Error> {
|
||||
Ok(CpuInfo {
|
||||
raw: String::from(other),
|
||||
|
|
|
|||
|
|
@ -5,31 +5,23 @@ mod bit;
|
|||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
#[macro_use]
|
||||
mod x86;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
pub use self::x86::__Feature;
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use self::x86::detect_features;
|
||||
|
||||
#[cfg(all(target_arch = "arm", target_os = "linux", feature = "std"))]
|
||||
#[cfg(all(target_arch = "arm", target_os = "linux"))]
|
||||
#[macro_use]
|
||||
mod arm;
|
||||
#[cfg(all(target_arch = "arm", target_os = "linux", feature = "std"))]
|
||||
#[cfg(all(target_arch = "arm", target_os = "linux"))]
|
||||
pub use self::arm::__Feature;
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux", feature = "std"))]
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
#[macro_use]
|
||||
mod aarch64;
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux", feature = "std"))]
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
pub use self::aarch64::__Feature;
|
||||
|
||||
#[cfg(all(feature = "std", target_os = "linux",
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "arm", target_arch = "aarch64")))]
|
||||
mod linux;
|
||||
|
||||
#[cfg(all(feature = "std", target_os = "linux",
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "arm", target_arch = "aarch64")))]
|
||||
pub use self::linux::detect_features;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,17 @@
|
|||
#![cfg_attr(feature = "strict", deny(warnings))]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(option_unwrap_used))]
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
extern crate cupid;
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "arm",
|
||||
target_arch = "aarch64"))]
|
||||
#[macro_use]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
extern crate stdsimd;
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn works() {
|
||||
fn x86() {
|
||||
let information = cupid::master().unwrap();
|
||||
assert_eq!(cfg_feature_enabled!("sse"), information.sse());
|
||||
assert_eq!(cfg_feature_enabled!("sse2"), information.sse2());
|
||||
|
|
@ -52,3 +54,18 @@ fn works() {
|
|||
information.xsaves_xrstors_and_ia32_xss()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(target_arch = "arm", target_os = "linux"))]
|
||||
fn arm_linux() {
|
||||
println!("neon: {}", cfg_feature_enabled!("neon"));
|
||||
println!("pmull: {}", cfg_feature_enabled!("pmull"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
fn aarch64_linux() {
|
||||
println!("neon: {}", cfg_feature_enabled!("neon"));
|
||||
println!("asimd: {}", cfg_feature_enabled!("asimd"));
|
||||
println!("pmull: {}", cfg_feature_enabled!("pmull"));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue