|
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