32 #ifndef MCKL_INTERNAL_SSE2_HPP 33 #define MCKL_INTERNAL_SSE2_HPP 47 const std::array<__m128i, 2> &s, std::array<__m128i, 4> &t)
49 const __m128i m = _mm_set1_epi64x(static_cast<MCKL_INT64>(0xFFFFFFFF));
51 std::get<0>(t) = _mm_shuffle_epi32(std::get<0>(s), 0xD8);
52 std::get<2>(t) = _mm_shuffle_epi32(std::get<1>(s), 0xD8);
54 std::get<1>(t) = _mm_srli_epi64(std::get<0>(t), 32);
55 std::get<3>(t) = _mm_srli_epi64(std::get<2>(t), 32);
57 std::get<0>(t) = _mm_and_si128(std::get<0>(t), m);
58 std::get<2>(t) = _mm_and_si128(std::get<2>(t), m);
62 const std::array<__m128i, 4> &s, std::array<__m128i, 8> &t)
64 const __m128i m = _mm_set1_epi64x(static_cast<MCKL_INT64>(0xFFFFFFFF));
66 std::get<0>(t) = _mm_shuffle_epi32(std::get<0>(s), 0xD8);
67 std::get<2>(t) = _mm_shuffle_epi32(std::get<1>(s), 0xD8);
68 std::get<4>(t) = _mm_shuffle_epi32(std::get<2>(s), 0xD8);
69 std::get<6>(t) = _mm_shuffle_epi32(std::get<3>(s), 0xD8);
71 std::get<1>(t) = _mm_srli_epi64(std::get<0>(t), 32);
72 std::get<3>(t) = _mm_srli_epi64(std::get<2>(t), 32);
73 std::get<5>(t) = _mm_srli_epi64(std::get<4>(t), 32);
74 std::get<7>(t) = _mm_srli_epi64(std::get<6>(t), 32);
76 std::get<0>(t) = _mm_and_si128(std::get<0>(t), m);
77 std::get<2>(t) = _mm_and_si128(std::get<2>(t), m);
78 std::get<4>(t) = _mm_and_si128(std::get<4>(t), m);
79 std::get<6>(t) = _mm_and_si128(std::get<6>(t), m);
83 const std::array<__m128i, 8> &s, std::array<__m128i, 16> &t)
85 const __m128i m = _mm_set1_epi64x(static_cast<MCKL_INT64>(0xFFFFFFFF));
87 std::get<0x0>(t) = _mm_shuffle_epi32(std::get<0>(s), 0xD8);
88 std::get<0x2>(t) = _mm_shuffle_epi32(std::get<1>(s), 0xD8);
89 std::get<0x4>(t) = _mm_shuffle_epi32(std::get<2>(s), 0xD8);
90 std::get<0x6>(t) = _mm_shuffle_epi32(std::get<3>(s), 0xD8);
91 std::get<0x8>(t) = _mm_shuffle_epi32(std::get<4>(s), 0xD8);
92 std::get<0xA>(t) = _mm_shuffle_epi32(std::get<5>(s), 0xD8);
93 std::get<0xC>(t) = _mm_shuffle_epi32(std::get<6>(s), 0xD8);
94 std::get<0xE>(t) = _mm_shuffle_epi32(std::get<7>(s), 0xD8);
96 std::get<0x1>(t) = _mm_srli_epi64(std::get<0x0>(t), 32);
97 std::get<0x3>(t) = _mm_srli_epi64(std::get<0x2>(t), 32);
98 std::get<0x5>(t) = _mm_srli_epi64(std::get<0x4>(t), 32);
99 std::get<0x7>(t) = _mm_srli_epi64(std::get<0x6>(t), 32);
100 std::get<0x9>(t) = _mm_srli_epi64(std::get<0x8>(t), 32);
101 std::get<0xB>(t) = _mm_srli_epi64(std::get<0xA>(t), 32);
102 std::get<0xD>(t) = _mm_srli_epi64(std::get<0xC>(t), 32);
103 std::get<0xF>(t) = _mm_srli_epi64(std::get<0xE>(t), 32);
105 std::get<0x0>(t) = _mm_and_si128(std::get<0x0>(t), m);
106 std::get<0x2>(t) = _mm_and_si128(std::get<0x2>(t), m);
107 std::get<0x4>(t) = _mm_and_si128(std::get<0x4>(t), m);
108 std::get<0x6>(t) = _mm_and_si128(std::get<0x6>(t), m);
109 std::get<0x8>(t) = _mm_and_si128(std::get<0x8>(t), m);
110 std::get<0xA>(t) = _mm_and_si128(std::get<0xA>(t), m);
111 std::get<0xC>(t) = _mm_and_si128(std::get<0xC>(t), m);
112 std::get<0xE>(t) = _mm_and_si128(std::get<0xE>(t), m);
115 MCKL_INLINE inline void cvtepi32_ps(std::array<__m128i, 4> &s)
117 std::get<0>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0>(s)));
118 std::get<1>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<1>(s)));
119 std::get<2>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<2>(s)));
120 std::get<3>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<3>(s)));
123 MCKL_INLINE inline void cvtepi32_ps(std::array<__m128i, 8> &s)
125 std::get<0>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0>(s)));
126 std::get<1>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<1>(s)));
127 std::get<2>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<2>(s)));
128 std::get<3>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<3>(s)));
129 std::get<4>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<4>(s)));
130 std::get<5>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<5>(s)));
131 std::get<6>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<6>(s)));
132 std::get<7>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<7>(s)));
135 MCKL_INLINE inline void cvtepi32_ps(std::array<__m128i, 16> &s)
137 std::get<0x0>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x0>(s)));
138 std::get<0x1>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x1>(s)));
139 std::get<0x2>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x2>(s)));
140 std::get<0x3>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x3>(s)));
141 std::get<0x4>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x4>(s)));
142 std::get<0x5>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x5>(s)));
143 std::get<0x6>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x6>(s)));
144 std::get<0x7>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x7>(s)));
145 std::get<0x8>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x8>(s)));
146 std::get<0x9>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0x9>(s)));
147 std::get<0xA>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xA>(s)));
148 std::get<0xB>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xB>(s)));
149 std::get<0xC>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xC>(s)));
150 std::get<0xD>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xD>(s)));
151 std::get<0xE>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xE>(s)));
152 std::get<0xF>(s) = _mm_castps_si128(_mm_cvtepi32_ps(std::get<0xF>(s)));
155 template <std::
size_t S>
156 MCKL_INLINE inline void cvtepi64_pd(std::array<__m128i, S> &s)
158 const __m128i m32 = _mm_castpd_si128(_mm_set1_pd(Pow2<double, 32>::value));
159 const __m128i m52 = _mm_castpd_si128(_mm_set1_pd(Pow2<double, 52>::value));
160 const __m128i mask = _mm_set1_epi64x(static_cast<MCKL_INT64>(0xFFFFFFFF));
162 std::array<__m128i, S> t;
163 and_si128(s, mask, t);
173 template <std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3,
175 MCKL_INLINE inline void transpose4x32_si128(std::array<__m128i, N> &s)
177 __m128i t0 = _mm_unpacklo_epi32(std::get<I0>(s), std::get<I1>(s));
178 __m128i t1 = _mm_unpacklo_epi32(std::get<I2>(s), std::get<I3>(s));
179 __m128i t2 = _mm_unpackhi_epi32(std::get<I0>(s), std::get<I1>(s));
180 __m128i t3 = _mm_unpackhi_epi32(std::get<I2>(s), std::get<I3>(s));
181 std::get<I0>(s) = _mm_unpacklo_epi64(t0, t1);
182 std::get<I1>(s) = _mm_unpackhi_epi64(t0, t1);
183 std::get<I2>(s) = _mm_unpacklo_epi64(t2, t3);
184 std::get<I3>(s) = _mm_unpackhi_epi64(t2, t3);
187 MCKL_INLINE inline void transpose4x32_load_si128(std::array<__m128i, 4> &s)
189 transpose4x32_si128<0, 1, 2, 3>(s);
192 MCKL_INLINE inline void transpose4x32_store_si128(std::array<__m128i, 4> &s)
194 transpose4x32_si128<0, 1, 2, 3>(s);
197 MCKL_INLINE inline void transpose4x32_load_si128(std::array<__m128i, 8> &s)
199 __m128i s2 = std::get<2>(s);
200 std::get<2>(s) = std::get<1>(s);
201 std::get<1>(s) = std::get<4>(s);
204 __m128i s6 = std::get<6>(s);
205 std::get<6>(s) = std::get<3>(s);
206 std::get<3>(s) = std::get<5>(s);
209 transpose4x32_si128<0, 1, 2, 3>(s);
210 transpose4x32_si128<4, 5, 6, 7>(s);
213 MCKL_INLINE inline void transpose4x32_store_si128(std::array<__m128i, 8> &s)
215 transpose4x32_si128<0, 1, 2, 3>(s);
216 transpose4x32_si128<4, 5, 6, 7>(s);
218 __m128i s1 = std::get<1>(s);
219 std::get<1>(s) = std::get<2>(s);
220 std::get<2>(s) = std::get<4>(s);
223 __m128i s3 = std::get<3>(s);
224 std::get<3>(s) = std::get<6>(s);
225 std::get<6>(s) = std::get<5>(s);
229 MCKL_INLINE inline void transpose4x32_load_si128(std::array<__m128i, 16> &s)
231 __m128i s1 = std::get<0x1>(s);
232 __m128i s2 = std::get<0x2>(s);
233 __m128i s3 = std::get<0x3>(s);
234 __m128i s6 = std::get<0x6>(s);
235 __m128i s7 = std::get<0x7>(s);
236 __m128i sB = std::get<0xB>(s);
237 std::get<0x1>(s) = std::get<0x4>(s);
238 std::get<0x2>(s) = std::get<0x8>(s);
239 std::get<0x3>(s) = std::get<0xC>(s);
240 std::get<0x6>(s) = std::get<0x9>(s);
241 std::get<0x7>(s) = std::get<0xD>(s);
242 std::get<0xB>(s) = std::get<0xE>(s);
243 std::get<0x4>(s) = s1;
244 std::get<0x8>(s) = s2;
245 std::get<0xC>(s) = s3;
246 std::get<0x9>(s) = s6;
247 std::get<0xD>(s) = s7;
248 std::get<0xE>(s) = sB;
250 transpose4x32_si128<0x0, 0x1, 0x2, 0x3>(s);
251 transpose4x32_si128<0x4, 0x5, 0x6, 0x7>(s);
252 transpose4x32_si128<0x8, 0x9, 0xA, 0xB>(s);
253 transpose4x32_si128<0xC, 0xD, 0xE, 0xF>(s);
256 MCKL_INLINE inline void transpose4x32_store_si128(std::array<__m128i, 16> &s)
258 transpose4x32_si128<0x0, 0x1, 0x2, 0x3>(s);
259 transpose4x32_si128<0x4, 0x5, 0x6, 0x7>(s);
260 transpose4x32_si128<0x8, 0x9, 0xA, 0xB>(s);
261 transpose4x32_si128<0xC, 0xD, 0xE, 0xF>(s);
263 __m128i s1 = std::get<0x1>(s);
264 __m128i s2 = std::get<0x2>(s);
265 __m128i s3 = std::get<0x3>(s);
266 __m128i s6 = std::get<0x6>(s);
267 __m128i s7 = std::get<0x7>(s);
268 __m128i sB = std::get<0xB>(s);
269 std::get<0x1>(s) = std::get<0x4>(s);
270 std::get<0x2>(s) = std::get<0x8>(s);
271 std::get<0x3>(s) = std::get<0xC>(s);
272 std::get<0x6>(s) = std::get<0x9>(s);
273 std::get<0x7>(s) = std::get<0xD>(s);
274 std::get<0xB>(s) = std::get<0xE>(s);
275 std::get<0x4>(s) = s1;
276 std::get<0x8>(s) = s2;
277 std::get<0xC>(s) = s3;
278 std::get<0x9>(s) = s6;
279 std::get<0xD>(s) = s7;
280 std::get<0xE>(s) = sB;
283 template <std::
size_t I0, std::
size_t I1, std::
size_t N>
284 MCKL_INLINE inline void transpose2x64_si128(std::array<__m128i, N> &s)
286 __m128i t0 = _mm_unpacklo_epi64(std::get<I0>(s), std::get<I1>(s));
287 __m128i t1 = _mm_unpackhi_epi64(std::get<I0>(s), std::get<I1>(s));
288 std::get<I0>(s) = t0;
289 std::get<I1>(s) = t1;
292 MCKL_INLINE inline void transpose2x64_load_si128(std::array<__m128i, 2> &s)
294 transpose2x64_si128<0, 1>(s);
297 MCKL_INLINE inline void transpose2x64_store_si128(std::array<__m128i, 2> &s)
299 transpose2x64_si128<0, 1>(s);
302 MCKL_INLINE inline void transpose2x64_load_si128(std::array<__m128i, 4> &s)
304 __m128i s1 = std::get<1>(s);
305 std::get<1>(s) = std::get<2>(s);
308 transpose2x64_si128<0, 1>(s);
309 transpose2x64_si128<2, 3>(s);
312 MCKL_INLINE inline void transpose2x64_store_si128(std::array<__m128i, 4> &s)
314 transpose2x64_si128<0, 1>(s);
315 transpose2x64_si128<2, 3>(s);
317 __m128i s1 = std::get<1>(s);
318 std::get<1>(s) = std::get<2>(s);
322 MCKL_INLINE inline void transpose2x64_load_si128(std::array<__m128i, 8> &s)
324 __m128i s2 = std::get<2>(s);
325 std::get<2>(s) = std::get<1>(s);
326 std::get<1>(s) = std::get<4>(s);
329 __m128i s6 = std::get<6>(s);
330 std::get<6>(s) = std::get<3>(s);
331 std::get<3>(s) = std::get<5>(s);
334 transpose2x64_si128<0, 1>(s);
335 transpose2x64_si128<2, 3>(s);
336 transpose2x64_si128<4, 5>(s);
337 transpose2x64_si128<6, 7>(s);
340 MCKL_INLINE inline void transpose2x64_store_si128(std::array<__m128i, 8> &s)
342 transpose2x64_si128<0, 1>(s);
343 transpose2x64_si128<2, 3>(s);
344 transpose2x64_si128<4, 5>(s);
345 transpose2x64_si128<6, 7>(s);
347 __m128i s1 = std::get<1>(s);
348 std::get<1>(s) = std::get<2>(s);
349 std::get<2>(s) = std::get<4>(s);
352 __m128i s3 = std::get<3>(s);
353 std::get<3>(s) = std::get<6>(s);
354 std::get<6>(s) = std::get<5>(s);
358 MCKL_INLINE inline void transpose2x64_load_si128(std::array<__m128i, 16> &s)
360 __m128i s2 = std::get<0x2>(s);
361 std::get<0x2>(s) = std::get<0x1>(s);
362 std::get<0x1>(s) = std::get<0x8>(s);
363 std::get<0x8>(s) = std::get<0x4>(s);
364 std::get<0x4>(s) = s2;
366 __m128i s6 = std::get<0x6>(s);
367 std::get<0x6>(s) = std::get<0x3>(s);
368 std::get<0x3>(s) = std::get<0x9>(s);
369 std::get<0x9>(s) = std::get<0xC>(s);
370 std::get<0xC>(s) = s6;
372 __m128i sE = std::get<0xE>(s);
373 std::get<0xE>(s) = std::get<0x7>(s);
374 std::get<0x7>(s) = std::get<0xB>(s);
375 std::get<0xB>(s) = std::get<0xD>(s);
376 std::get<0xD>(s) = sE;
378 __m128i s5 = std::get<0x5>(s);
379 std::get<0x5>(s) = std::get<0xA>(s);
380 std::get<0xA>(s) = s5;
382 transpose2x64_si128<0x0, 0x1>(s);
383 transpose2x64_si128<0x2, 0x3>(s);
384 transpose2x64_si128<0x4, 0x5>(s);
385 transpose2x64_si128<0x6, 0x7>(s);
386 transpose2x64_si128<0x8, 0x9>(s);
387 transpose2x64_si128<0xA, 0xB>(s);
388 transpose2x64_si128<0xC, 0xD>(s);
389 transpose2x64_si128<0xE, 0xF>(s);
392 MCKL_INLINE inline void transpose2x64_store_si128(std::array<__m128i, 16> &s)
394 transpose2x64_si128<0x0, 0x1>(s);
395 transpose2x64_si128<0x2, 0x3>(s);
396 transpose2x64_si128<0x4, 0x5>(s);
397 transpose2x64_si128<0x6, 0x7>(s);
398 transpose2x64_si128<0x8, 0x9>(s);
399 transpose2x64_si128<0xA, 0xB>(s);
400 transpose2x64_si128<0xC, 0xD>(s);
401 transpose2x64_si128<0xE, 0xF>(s);
403 __m128i s1 = std::get<0x1>(s);
404 std::get<0x1>(s) = std::get<0x2>(s);
405 std::get<0x2>(s) = std::get<0x4>(s);
406 std::get<0x4>(s) = std::get<0x8>(s);
407 std::get<0x8>(s) = s1;
409 __m128i s3 = std::get<0x3>(s);
410 std::get<0x3>(s) = std::get<0x6>(s);
411 std::get<0x6>(s) = std::get<0xC>(s);
412 std::get<0xC>(s) = std::get<0x9>(s);
413 std::get<0x9>(s) = s3;
415 __m128i s7 = std::get<0x7>(s);
416 std::get<0x7>(s) = std::get<0xE>(s);
417 std::get<0xE>(s) = std::get<0xD>(s);
418 std::get<0xD>(s) = std::get<0xB>(s);
419 std::get<0xB>(s) = s7;
421 __m128i s5 = std::get<0x5>(s);
422 std::get<0x5>(s) = std::get<0xA>(s);
423 std::get<0xA>(s) = s5;
432 #endif // MCKL_INTERNAL_SSE2_HPP #define MCKL_PUSH_GCC_WARNING(warning)
#define MCKL_POP_GCC_WARNING