]> git.proxmox.com Git - rustc.git/blame - src/stdsimd/coresimd/ppsv/api/minimal.rs
New upstream version 1.27.1+dfsg1
[rustc.git] / src / stdsimd / coresimd / ppsv / api / minimal.rs
CommitLineData
83c7162d
XL
1//! Minimal portable vector types API.
2#![allow(unused)]
0531ce1d
XL
3
4/// Minimal interface: all packed SIMD vector types implement this.
5macro_rules! impl_minimal {
6 ($id:ident, $elem_ty:ident, $elem_count:expr, $($elem_name:ident),+) => {
83c7162d 7 impl super::api::Lanes<[u32; $elem_count]> for $id {}
0531ce1d
XL
8
9 impl $id {
10 /// Creates a new instance with each vector elements initialized
11 /// with the provided values.
12 #[inline]
13 pub const fn new($($elem_name: $elem_ty),*) -> Self {
14 $id($($elem_name),*)
15 }
16
17 /// Returns the number of vector lanes.
18 #[inline]
19 pub const fn lanes() -> usize {
20 $elem_count
21 }
22
23 /// Constructs a new instance with each element initialized to
24 /// `value`.
25 #[inline]
26 pub const fn splat(value: $elem_ty) -> Self {
27 $id($({
28 #[allow(non_camel_case_types, dead_code)]
29 struct $elem_name;
30 value
31 }),*)
32 }
33
34 /// Extracts the value at `index`.
35 ///
36 /// # Panics
37 ///
38 /// If `index >= Self::lanes()`.
39 #[inline]
40 pub fn extract(self, index: usize) -> $elem_ty {
41 assert!(index < $elem_count);
42 unsafe { self.extract_unchecked(index) }
43 }
44
45 /// Extracts the value at `index`.
46 ///
83c7162d
XL
47 /// # Precondition
48 ///
0531ce1d
XL
49 /// If `index >= Self::lanes()` the behavior is undefined.
50 #[inline]
51 pub unsafe fn extract_unchecked(self, index: usize) -> $elem_ty {
83c7162d 52 use coresimd::simd_llvm::simd_extract;
0531ce1d
XL
53 simd_extract(self, index as u32)
54 }
55
56 /// Returns a new vector where the value at `index` is replaced by `new_value`.
57 ///
58 /// # Panics
59 ///
60 /// If `index >= Self::lanes()`.
61 #[inline]
62 #[must_use = "replace does not modify the original value - it returns a new vector with the value at `index` replaced by `new_value`d"]
63 pub fn replace(self, index: usize, new_value: $elem_ty) -> Self {
64 assert!(index < $elem_count);
65 unsafe { self.replace_unchecked(index, new_value) }
66 }
67
68 /// Returns a new vector where the value at `index` is replaced by `new_value`.
69 ///
83c7162d 70 /// # Precondition
0531ce1d 71 ///
83c7162d 72 /// If `index >= Self::lanes()` the behavior is undefined.
0531ce1d
XL
73 #[inline]
74 #[must_use = "replace_unchecked does not modify the original value - it returns a new vector with the value at `index` replaced by `new_value`d"]
75 pub unsafe fn replace_unchecked(
76 self,
77 index: usize,
78 new_value: $elem_ty,
79 ) -> Self {
83c7162d 80 use coresimd::simd_llvm::simd_insert;
0531ce1d
XL
81 simd_insert(self, index as u32, new_value)
82 }
83 }
84 }
85}
86
87#[cfg(test)]
88macro_rules! test_minimal {
89 ($id:ident, $elem_ty:ident, $elem_count:expr) => {
90 #[test]
91 fn minimal() {
83c7162d 92 use coresimd::simd::$id;
0531ce1d
XL
93 // TODO: test new
94
95 // lanes:
96 assert_eq!($elem_count, $id::lanes());
97
98 // splat and extract / extract_unchecked:
99 const VAL: $elem_ty = 7 as $elem_ty;
100 const VEC: $id = $id::splat(VAL);
101 for i in 0..$id::lanes() {
102 assert_eq!(VAL, VEC.extract(i));
103 assert_eq!(VAL, unsafe { VEC.extract_unchecked(i) });
104 }
105
106 // replace / replace_unchecked
107 let new_vec = VEC.replace(1, 42 as $elem_ty);
108 for i in 0..$id::lanes() {
109 if i == 1 {
110 assert_eq!(42 as $elem_ty, new_vec.extract(i));
111 } else {
112 assert_eq!(VAL, new_vec.extract(i));
113 }
114 }
115 let new_vec = unsafe { VEC.replace_unchecked(1, 42 as $elem_ty) };
116 for i in 0..$id::lanes() {
117 if i == 1 {
118 assert_eq!(42 as $elem_ty, new_vec.extract(i));
119 } else {
120 assert_eq!(VAL, new_vec.extract(i));
121 }
122 }
123 }
124 #[test]
125 #[should_panic]
126 fn minimal_extract_panic_on_out_of_bounds() {
83c7162d 127 use coresimd::simd::$id;
0531ce1d
XL
128 const VAL: $elem_ty = 7 as $elem_ty;
129 const VEC: $id = $id::splat(VAL);
130 let _ = VEC.extract($id::lanes());
131 }
132 #[test]
133 #[should_panic]
134 fn minimal_replace_panic_on_out_of_bounds() {
83c7162d 135 use coresimd::simd::$id;
0531ce1d
XL
136 const VAL: $elem_ty = 7 as $elem_ty;
137 const VEC: $id = $id::splat(VAL);
138 let _ = VEC.replace($id::lanes(), 42 as $elem_ty);
139 }
83c7162d 140 };
0531ce1d 141}