refactor no_std components into the coresimd crate

This commit is contained in:
gnzlbg 2017-11-20 16:58:31 +01:00 committed by gnzlbg
parent dc9f076480
commit 14d0903309
62 changed files with 471 additions and 192 deletions

View file

@ -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

View file

@ -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:

View file

@ -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" ]

View file

@ -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 \

View file

@ -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

View 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 = []

View file

@ -0,0 +1 @@
../LICENSE-APACHE

View file

@ -0,0 +1 @@
../LICENSE-MIT

View file

@ -0,0 +1 @@
../README.md

View file

@ -0,0 +1 @@
../rustfmt.toml

View 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;

View 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
}

View 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)
}

View 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"));
}
}

View 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)
}

View file

@ -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);

View file

@ -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;

View file

@ -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))]

View file

@ -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") {

View file

@ -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;

View file

@ -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;

View file

@ -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() {

View file

@ -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);

View file

@ -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") {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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),

View file

@ -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;

View file

@ -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"));
}