]> git.proxmox.com Git - rustc.git/blob - src/stdsimd/crates/core_arch/src/x86/avx512f.rs
New upstream version 1.37.0+dfsg1
[rustc.git] / src / stdsimd / crates / core_arch / src / x86 / avx512f.rs
1 use crate::{
2 core_arch::{simd::*, simd_llvm::*, x86::*},
3 mem::{self, transmute},
4 };
5
6 #[cfg(test)]
7 use stdsimd_test::assert_instr;
8
9 /// Computes the absolute values of packed 32-bit integers in `a`.
10 ///
11 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33&text=_mm512_abs_epi32)
12 #[inline]
13 #[target_feature(enable = "avx512f")]
14 #[cfg_attr(test, assert_instr(vpabsd))]
15 pub unsafe fn _mm512_abs_epi32(a: __m512i) -> __m512i {
16 let a = a.as_i32x16();
17 // all-0 is a properly initialized i32x16
18 let zero: i32x16 = mem::zeroed();
19 let sub = simd_sub(zero, a);
20 let cmp: i32x16 = simd_gt(a, zero);
21 transmute(simd_select(cmp, a, sub))
22 }
23
24 /// Computes the absolute value of packed 32-bit integers in `a`, and store the
25 /// unsigned results in `dst` using writemask `k` (elements are copied from
26 /// `src` when the corresponding mask bit is not set).
27 ///
28 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33&text=_mm512_abs_epi32)
29 #[inline]
30 #[target_feature(enable = "avx512f")]
31 #[cfg_attr(test, assert_instr(vpabsd))]
32 pub unsafe fn _mm512_mask_abs_epi32(src: __m512i, k: __mmask16, a: __m512i) -> __m512i {
33 let abs = _mm512_abs_epi32(a).as_i32x16();
34 transmute(simd_select_bitmask(k, abs, src.as_i32x16()))
35 }
36
37 /// Computes the absolute value of packed 32-bit integers in `a`, and store the
38 /// unsigned results in `dst` using zeromask `k` (elements are zeroed out when
39 /// the corresponding mask bit is not set).
40 ///
41 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990,33,34,35,35&text=_mm512_maskz_abs_epi32)
42 #[inline]
43 #[target_feature(enable = "avx512f")]
44 #[cfg_attr(test, assert_instr(vpabsd))]
45 pub unsafe fn _mm512_maskz_abs_epi32(k: __mmask16, a: __m512i) -> __m512i {
46 let abs = _mm512_abs_epi32(a).as_i32x16();
47 let zero = _mm512_setzero_si512().as_i32x16();
48 transmute(simd_select_bitmask(k, abs, zero))
49 }
50
51 /// Returns vector of type `__m512i` with all elements set to zero.
52 ///
53 /// [Intel's documentation](https://software.intel.com/sites/landingpage/IntrinsicsGuide/#avx512techs=AVX512F&expand=33,34,4990&text=_mm512_setzero_si512)
54 #[inline]
55 #[target_feature(enable = "avx512f")]
56 #[cfg_attr(test, assert_instr(vxorps))]
57 pub unsafe fn _mm512_setzero_si512() -> __m512i {
58 // All-0 is a properly initialized __m512i
59 mem::zeroed()
60 }
61
62 /// Sets packed 32-bit integers in `dst` with the supplied values in reverse
63 /// order.
64 #[inline]
65 #[target_feature(enable = "avx512f")]
66 pub unsafe fn _mm512_setr_epi32(
67 e15: i32,
68 e14: i32,
69 e13: i32,
70 e12: i32,
71 e11: i32,
72 e10: i32,
73 e9: i32,
74 e8: i32,
75 e7: i32,
76 e6: i32,
77 e5: i32,
78 e4: i32,
79 e3: i32,
80 e2: i32,
81 e1: i32,
82 e0: i32,
83 ) -> __m512i {
84 let r = i32x16(
85 e15, e14, e13, e12, e11, e10, e9, e8, e7, e6, e5, e4, e3, e2, e1, e0,
86 );
87 transmute(r)
88 }
89
90 /// Broadcast 64-bit integer `a` to all elements of `dst`.
91 #[inline]
92 #[target_feature(enable = "avx512f")]
93 pub unsafe fn _mm512_set1_epi64(a: i64) -> __m512i {
94 transmute(i64x8::splat(a))
95 }
96
97 #[cfg(test)]
98 mod tests {
99 use std;
100 use stdsimd_test::simd_test;
101
102 use crate::core_arch::x86::*;
103
104 #[simd_test(enable = "avx512f")]
105 unsafe fn test_mm512_abs_epi32() {
106 #[rustfmt::skip]
107 let a = _mm512_setr_epi32(
108 0, 1, -1, std::i32::MAX,
109 std::i32::MIN, 100, -100, -32,
110 0, 1, -1, std::i32::MAX,
111 std::i32::MIN, 100, -100, -32,
112 );
113 let r = _mm512_abs_epi32(a);
114 let e = _mm512_setr_epi32(
115 0,
116 1,
117 1,
118 std::i32::MAX,
119 std::i32::MAX.wrapping_add(1),
120 100,
121 100,
122 32,
123 0,
124 1,
125 1,
126 std::i32::MAX,
127 std::i32::MAX.wrapping_add(1),
128 100,
129 100,
130 32,
131 );
132 assert_eq_m512i(r, e);
133 }
134
135 #[simd_test(enable = "avx512f")]
136 unsafe fn test_mm512_mask_abs_epi32() {
137 #[rustfmt::skip]
138 let a = _mm512_setr_epi32(
139 0, 1, -1, std::i32::MAX,
140 std::i32::MIN, 100, -100, -32,
141 0, 1, -1, std::i32::MAX,
142 std::i32::MIN, 100, -100, -32,
143 );
144 let r = _mm512_mask_abs_epi32(a, 0, a);
145 assert_eq_m512i(r, a);
146 let r = _mm512_mask_abs_epi32(a, 0b11111111, a);
147 let e = _mm512_setr_epi32(
148 0,
149 1,
150 1,
151 std::i32::MAX,
152 std::i32::MAX.wrapping_add(1),
153 100,
154 100,
155 32,
156 0,
157 1,
158 -1,
159 std::i32::MAX,
160 std::i32::MIN,
161 100,
162 -100,
163 -32,
164 );
165 assert_eq_m512i(r, e);
166 }
167
168 #[simd_test(enable = "avx512f")]
169 unsafe fn test_mm512_maskz_abs_epi32() {
170 #[rustfmt::skip]
171 let a = _mm512_setr_epi32(
172 0, 1, -1, std::i32::MAX,
173 std::i32::MIN, 100, -100, -32,
174 0, 1, -1, std::i32::MAX,
175 std::i32::MIN, 100, -100, -32,
176 );
177 let r = _mm512_maskz_abs_epi32(0, a);
178 assert_eq_m512i(r, _mm512_setzero_si512());
179 let r = _mm512_maskz_abs_epi32(0b11111111, a);
180 let e = _mm512_setr_epi32(
181 0,
182 1,
183 1,
184 std::i32::MAX,
185 std::i32::MAX.wrapping_add(1),
186 100,
187 100,
188 32,
189 0,
190 0,
191 0,
192 0,
193 0,
194 0,
195 0,
196 0,
197 );
198 assert_eq_m512i(r, e);
199 }
200 }