|
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 |
|
37 | 24 | #![unstable(feature = "core_simd", |
38 | 25 | reason = "needs an RFC to flesh out the design", |
39 | 26 | issue = "27731")] |
| 27 | +#![deprecated(since = "1.3.0", |
| 28 | + reason = "use the external `simd` crate instead")] |
40 | 29 |
|
41 | 30 | #![allow(non_camel_case_types)] |
42 | 31 | #![allow(missing_docs)] |
| 32 | +#![allow(deprecated)] |
| 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!(); |
43 | 57 |
|
44 | | -#[simd] |
| 58 | +#[repr(simd)] |
45 | 59 | #[derive(Copy, Clone, Debug)] |
46 | 60 | #[repr(C)] |
47 | 61 | pub struct i8x16(pub i8, pub i8, pub i8, pub i8, |
48 | 62 | pub i8, pub i8, pub i8, pub i8, |
49 | 63 | pub i8, pub i8, pub i8, pub i8, |
50 | 64 | pub i8, pub i8, pub i8, pub i8); |
51 | 65 |
|
52 | | -#[simd] |
| 66 | +#[repr(simd)] |
53 | 67 | #[derive(Copy, Clone, Debug)] |
54 | 68 | #[repr(C)] |
55 | 69 | pub struct i16x8(pub i16, pub i16, pub i16, pub i16, |
56 | 70 | pub i16, pub i16, pub i16, pub i16); |
57 | 71 |
|
58 | | -#[simd] |
| 72 | +#[repr(simd)] |
59 | 73 | #[derive(Copy, Clone, Debug)] |
60 | 74 | #[repr(C)] |
61 | 75 | pub struct i32x4(pub i32, pub i32, pub i32, pub i32); |
62 | 76 |
|
63 | | -#[simd] |
| 77 | +#[repr(simd)] |
64 | 78 | #[derive(Copy, Clone, Debug)] |
65 | 79 | #[repr(C)] |
66 | 80 | pub struct i64x2(pub i64, pub i64); |
67 | 81 |
|
68 | | -#[simd] |
| 82 | +#[repr(simd)] |
69 | 83 | #[derive(Copy, Clone, Debug)] |
70 | 84 | #[repr(C)] |
71 | 85 | pub struct u8x16(pub u8, pub u8, pub u8, pub u8, |
72 | 86 | pub u8, pub u8, pub u8, pub u8, |
73 | 87 | pub u8, pub u8, pub u8, pub u8, |
74 | 88 | pub u8, pub u8, pub u8, pub u8); |
75 | 89 |
|
76 | | -#[simd] |
| 90 | +#[repr(simd)] |
77 | 91 | #[derive(Copy, Clone, Debug)] |
78 | 92 | #[repr(C)] |
79 | 93 | pub struct u16x8(pub u16, pub u16, pub u16, pub u16, |
80 | 94 | pub u16, pub u16, pub u16, pub u16); |
81 | 95 |
|
82 | | -#[simd] |
| 96 | +#[repr(simd)] |
83 | 97 | #[derive(Copy, Clone, Debug)] |
84 | 98 | #[repr(C)] |
85 | 99 | pub struct u32x4(pub u32, pub u32, pub u32, pub u32); |
86 | 100 |
|
87 | | -#[simd] |
| 101 | +#[repr(simd)] |
88 | 102 | #[derive(Copy, Clone, Debug)] |
89 | 103 | #[repr(C)] |
90 | 104 | pub struct u64x2(pub u64, pub u64); |
91 | 105 |
|
92 | | -#[simd] |
| 106 | +#[repr(simd)] |
93 | 107 | #[derive(Copy, Clone, Debug)] |
94 | 108 | #[repr(C)] |
95 | 109 | pub struct f32x4(pub f32, pub f32, pub f32, pub f32); |
96 | 110 |
|
97 | | -#[simd] |
| 111 | +#[repr(simd)] |
98 | 112 | #[derive(Copy, Clone, Debug)] |
99 | 113 | #[repr(C)] |
100 | 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