diff --git a/library/stdarch/.gitignore b/library/stdarch/.gitignore new file mode 100644 index 000000000000..9b9f5ddcdc1c --- /dev/null +++ b/library/stdarch/.gitignore @@ -0,0 +1,3 @@ +Cargo.lock +.*.swp +/target diff --git a/library/stdarch/Cargo.toml b/library/stdarch/Cargo.toml index 1b19b574db68..b45b4009b8e6 100644 --- a/library/stdarch/Cargo.toml +++ b/library/stdarch/Cargo.toml @@ -9,3 +9,6 @@ repository = "https://github.com/BurntSushi/stdsimd" readme = "README.md" keywords = ["std", "simd", "intrinsics", "sse", "avx"] license = "MIT" + +[profile.release] +debug = true diff --git a/library/stdarch/examples/play.rs b/library/stdarch/examples/play.rs new file mode 100644 index 000000000000..5a3bf6ec8f08 --- /dev/null +++ b/library/stdarch/examples/play.rs @@ -0,0 +1,28 @@ +extern crate stdsimd; + +use std::env; +use std::io::Write; + +use stdsimd as s; + +fn main() { + let arg1: f64 = env::args().nth(1).unwrap().parse().unwrap(); + let arg2: f64 = env::args().nth(2).unwrap().parse().unwrap(); + let arg3: f64 = env::args().nth(3).unwrap().parse().unwrap(); + let arg4: f64 = env::args().nth(4).unwrap().parse().unwrap(); + unsafe { + let a1 = s::_mm_load_pd(&(arg1, arg2) as *const _ as *const f64); + let b1 = s::_mm_load_pd(&(arg3, arg4) as *const _ as *const f64); + // println!("{:?}, {:?}", a, b); + let r1 = s::_mm_add_sd(a1, b1); + // println!("{:?}", r1); + let mut r2: (f64, f64) = (0.0, 0.0); + s::_mm_store_pd(&mut r2 as *mut _ as *mut f64, r1); + if r2 == (4.0, 2.0) { + ::std::io::stdout().write_all(b"yes\n").unwrap(); + } else { + ::std::io::stdout().write_all(b"NO\n").unwrap(); + } + // println!("{:?}", r2); + } +} diff --git a/library/stdarch/src/lib.rs b/library/stdarch/src/lib.rs index e69de29bb2d1..3752456fa08c 100644 --- a/library/stdarch/src/lib.rs +++ b/library/stdarch/src/lib.rs @@ -0,0 +1,36 @@ +#![allow(dead_code)] +#![feature(platform_intrinsics, repr_simd)] + +pub use x86::*; + +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod x86; + +extern "platform-intrinsic" { + fn simd_eq(x: T, y: T) -> U; + fn simd_ne(x: T, y: T) -> U; + fn simd_lt(x: T, y: T) -> U; + fn simd_le(x: T, y: T) -> U; + fn simd_gt(x: T, y: T) -> U; + fn simd_ge(x: T, y: T) -> U; + + fn simd_shuffle2(x: T, y: T, idx: [u32; 2]) -> U; + fn simd_shuffle4(x: T, y: T, idx: [u32; 4]) -> U; + fn simd_shuffle8(x: T, y: T, idx: [u32; 8]) -> U; + fn simd_shuffle16(x: T, y: T, idx: [u32; 16]) -> U; + + fn simd_insert(x: T, idx: u32, val: U) -> T; + fn simd_extract(x: T, idx: u32) -> U; + + fn simd_cast(x: T) -> U; + + fn simd_add(x: T, y: T) -> T; + fn simd_sub(x: T, y: T) -> T; + fn simd_mul(x: T, y: T) -> T; + fn simd_div(x: T, y: T) -> T; + fn simd_shl(x: T, y: T) -> T; + fn simd_shr(x: T, y: T) -> T; + fn simd_and(x: T, y: T) -> T; + fn simd_or(x: T, y: T) -> T; + fn simd_xor(x: T, y: T) -> T; +} diff --git a/library/stdarch/src/x86/mod.rs b/library/stdarch/src/x86/mod.rs new file mode 100644 index 000000000000..0e91ade7deee --- /dev/null +++ b/library/stdarch/src/x86/mod.rs @@ -0,0 +1,29 @@ +pub use self::sse2::*; + +mod sse; +mod sse2; + +#[repr(simd)] +#[derive(Clone, Copy, Debug)] +#[allow(non_camel_case_types)] +pub struct __m128(f32, f32, f32, f32); + +#[repr(simd)] +#[derive(Clone, Copy, Debug)] +#[allow(non_camel_case_types)] +pub struct __m128d(f64, f64); + +#[repr(simd)] +#[derive(Clone, Copy, Debug)] +#[allow(non_camel_case_types)] +pub struct __m128i(u64, u64); + +#[repr(simd)] +#[derive(Clone, Copy, Debug)] +#[allow(non_camel_case_types)] +pub struct f64x2(f64, f64); + +#[repr(simd)] +#[derive(Clone, Copy, Debug)] +#[allow(non_camel_case_types)] +struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8); diff --git a/library/stdarch/src/x86/sse.rs b/library/stdarch/src/x86/sse.rs new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/library/stdarch/src/x86/sse2.rs b/library/stdarch/src/x86/sse2.rs new file mode 100644 index 000000000000..d21e0733e3a6 --- /dev/null +++ b/library/stdarch/src/x86/sse2.rs @@ -0,0 +1,26 @@ +use std::mem::transmute; + +use super::{__m128d, __m128i, f64x2, u8x16}; +use {simd_add, simd_extract, simd_insert}; + +pub unsafe fn _mm_add_epi8(a: __m128i, b: __m128i) -> __m128i { + transmute(simd_add::(transmute(a), transmute(b))) +} + +pub unsafe fn _mm_add_sd(a: __m128d, b: __m128d) -> __m128d { + let alow = simd_extract::(transmute(a), 0); + let blow = simd_extract::(transmute(b), 0); + transmute(simd_insert::(transmute(a), 0, alow + blow)) +} + +pub unsafe fn _mm_add_pd(a: __m128d, b: __m128d) -> __m128d { + transmute(simd_add::(transmute(a), transmute(b))) +} + +pub unsafe fn _mm_load_pd(mem_addr: *const f64) -> __m128d { + *(mem_addr as *const __m128d) +} + +pub unsafe fn _mm_store_pd(mem_addr: *mut f64, a: __m128d) { + *(mem_addr as *mut __m128d) = a; +}