//! SIMD vectors.
//!
-//! These types can be used for accessing basic SIMD operations. Each of them
-//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div,
-//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently
+//! These types can be used for accessing basic SIMD operations. Currently
//! comparison operators are not implemented. To use SSE3+, you must enable
//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
//! provided beyond this module.
//!
-//! ```rust
-//! #![feature(core_simd)]
-//!
-//! fn main() {
-//! use std::simd::f32x4;
-//! let a = f32x4(40.0, 41.0, 42.0, 43.0);
-//! let b = f32x4(1.0, 1.1, 3.4, 9.8);
-//! println!("{:?}", a + b);
-//! }
-//! ```
-//!
//! # Stability Note
//!
//! These are all experimental. The interface may change entirely, without
#![allow(missing_docs)]
#![allow(deprecated)]
+use ops::{Add, Sub, Mul, Div, Shl, Shr, BitAnd, BitOr, BitXor};
+
+// FIXME(stage0): the contents of macro can be inlined.
+// ABIs are verified as valid as soon as they are parsed, i.e. before
+// `cfg` stripping. The `platform-intrinsic` ABI is new, so stage0
+// doesn't know about it, but it still errors out when it hits it
+// (despite this being in a `cfg(not(stage0))` module).
+macro_rules! argh {
+ () => {
+ extern "platform-intrinsic" {
+ fn simd_add<T>(x: T, y: T) -> T;
+ fn simd_sub<T>(x: T, y: T) -> T;
+ fn simd_mul<T>(x: T, y: T) -> T;
+ fn simd_div<T>(x: T, y: T) -> T;
+ fn simd_shl<T>(x: T, y: T) -> T;
+ fn simd_shr<T>(x: T, y: T) -> T;
+ fn simd_and<T>(x: T, y: T) -> T;
+ fn simd_or<T>(x: T, y: T) -> T;
+ fn simd_xor<T>(x: T, y: T) -> T;
+ }
+ }
+}
+argh!();
+
#[repr(simd)]
#[derive(Copy, Clone, Debug)]
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct f64x2(pub f64, pub f64);
+
+macro_rules! impl_traits {
+ ($($trayt: ident, $method: ident, $func: ident: $($ty: ty),*;)*) => {
+ $($(
+ impl $trayt<$ty> for $ty {
+ type Output = Self;
+ fn $method(self, other: Self) -> Self {
+ unsafe {
+ $func(self, other)
+ }
+ }
+ }
+ )*)*
+ }
+}
+
+impl_traits! {
+ Add, add, simd_add: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
+ Sub, sub, simd_sub: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
+ Mul, mul, simd_mul: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
+
+ Div, div, simd_div: f32x4, f64x2;
+
+ Shl, shl, simd_shl: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
+ Shr, shr, simd_shr: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
+ BitAnd, bitand, simd_and: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
+ BitOr, bitor, simd_or: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
+ BitXor, bitxor, simd_xor: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
+}