|
10 | 10 |
|
11 | 11 | //! SIMD vectors.
|
12 | 12 | //!
|
13 |
| -//! These types can be used for accessing basic SIMD operations. Each of them |
14 |
| -//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div, |
15 |
| -//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently |
| 13 | +//! These types can be used for accessing basic SIMD operations. Currently |
16 | 14 | //! comparison operators are not implemented. To use SSE3+, you must enable
|
17 | 15 | //! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
|
18 | 16 | //! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
|
19 | 17 | //! provided beyond this module.
|
20 | 18 | //!
|
21 |
| -//! ```rust |
22 |
| -//! #![feature(core_simd)] |
23 |
| -//! |
24 |
| -//! fn main() { |
25 |
| -//! use std::simd::f32x4; |
26 |
| -//! let a = f32x4(40.0, 41.0, 42.0, 43.0); |
27 |
| -//! let b = f32x4(1.0, 1.1, 3.4, 9.8); |
28 |
| -//! println!("{:?}", a + b); |
29 |
| -//! } |
30 |
| -//! ``` |
31 |
| -//! |
32 | 19 | //! # Stability Note
|
33 | 20 | //!
|
34 | 21 | //! These are all experimental. The interface may change entirely, without
|
|
44 | 31 | #![allow(missing_docs)]
|
45 | 32 | #![allow(deprecated)]
|
46 | 33 |
|
| 34 | +use ops::{Add, Sub, Mul, Div, Shl, Shr, BitAnd, BitOr, BitXor}; |
| 35 | + |
| 36 | +// FIXME(stage0): the contents of macro can be inlined. |
| 37 | +// ABIs are verified as valid as soon as they are parsed, i.e. before |
| 38 | +// `cfg` stripping. The `platform-intrinsic` ABI is new, so stage0 |
| 39 | +// doesn't know about it, but it still errors out when it hits it |
| 40 | +// (despite this being in a `cfg(not(stage0))` module). |
| 41 | +macro_rules! argh { |
| 42 | + () => { |
| 43 | + extern "platform-intrinsic" { |
| 44 | + fn simd_add<T>(x: T, y: T) -> T; |
| 45 | + fn simd_sub<T>(x: T, y: T) -> T; |
| 46 | + fn simd_mul<T>(x: T, y: T) -> T; |
| 47 | + fn simd_div<T>(x: T, y: T) -> T; |
| 48 | + fn simd_shl<T>(x: T, y: T) -> T; |
| 49 | + fn simd_shr<T>(x: T, y: T) -> T; |
| 50 | + fn simd_and<T>(x: T, y: T) -> T; |
| 51 | + fn simd_or<T>(x: T, y: T) -> T; |
| 52 | + fn simd_xor<T>(x: T, y: T) -> T; |
| 53 | + } |
| 54 | + } |
| 55 | +} |
| 56 | +argh!(); |
| 57 | + |
47 | 58 | #[repr(simd)]
|
48 | 59 | #[derive(Copy, Clone, Debug)]
|
49 | 60 | #[repr(C)]
|
@@ -101,3 +112,32 @@ pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
101 | 112 | #[derive(Copy, Clone, Debug)]
|
102 | 113 | #[repr(C)]
|
103 | 114 | pub struct f64x2(pub f64, pub f64);
|
| 115 | + |
| 116 | +macro_rules! impl_traits { |
| 117 | + ($($trayt: ident, $method: ident, $func: ident: $($ty: ty),*;)*) => { |
| 118 | + $($( |
| 119 | + impl $trayt<$ty> for $ty { |
| 120 | + type Output = Self; |
| 121 | + fn $method(self, other: Self) -> Self { |
| 122 | + unsafe { |
| 123 | + $func(self, other) |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | + )*)* |
| 128 | + } |
| 129 | +} |
| 130 | + |
| 131 | +impl_traits! { |
| 132 | + Add, add, simd_add: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; |
| 133 | + Sub, sub, simd_sub: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; |
| 134 | + Mul, mul, simd_mul: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; |
| 135 | + |
| 136 | + Div, div, simd_div: f32x4, f64x2; |
| 137 | + |
| 138 | + Shl, shl, simd_shl: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; |
| 139 | + Shr, shr, simd_shr: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; |
| 140 | + BitAnd, bitand, simd_and: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; |
| 141 | + BitOr, bitor, simd_or: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; |
| 142 | + BitXor, bitxor, simd_xor: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; |
| 143 | +} |
0 commit comments