1 /* This file is part of the Vc library.
3 Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
5 Vc is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation, either version 3 of
8 the License, or (at your option) any later version.
10 Vc is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with Vc. If not, see <http://www.gnu.org/licenses/>.
20 #ifndef VC_AVX_INTRINSICS_H
21 #define VC_AVX_INTRINSICS_H
23 #include "../common/windows_fix_intrin.h"
26 #include <immintrin.h>
28 #if defined(VC_CLANG) && VC_CLANG < 0x30100
29 // _mm_permute_ps is broken: http://llvm.org/bugs/show_bug.cgi?id=12401
31 #define _mm_permute_ps(A, C) __extension__ ({ \
33 (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \
34 (C) & 0x3, ((C) & 0xc) >> 2, \
35 ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6); })
38 #include <Vc/global.h>
39 #include "const_data.h"
43 #if defined(VC_CLANG) || defined(VC_MSVC) || (defined(VC_GCC) && !defined(__OPTIMIZE__))
44 #define VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT
47 #if defined(VC_CLANG) && VC_CLANG <= 0x30000
48 // _mm_alignr_epi8 doesn't specify its return type, thus breaking overload resolution
49 #undef _mm_alignr_epi8
50 #define _mm_alignr_epi8(a, b, n) ((__m128i)__builtin_ia32_palignr128((a), (b), (n)))
57 #if defined(VC_GNU_ASM) && !defined(NVALGRIND)
58 static inline __m128i CONST _mm_setallone() { __m128i r; __asm__("pcmpeqb %0,%0":"=x"(r)); return r; }
60 static inline __m128i CONST _mm_setallone() { __m128i r = _mm_setzero_si128(); return _mm_cmpeq_epi8(r, r); }
62 static inline __m128i CONST _mm_setallone_si128() { return _mm_setallone(); }
63 static inline __m128d CONST _mm_setallone_pd() { return _mm_castsi128_pd(_mm_setallone()); }
64 static inline __m128 CONST _mm_setallone_ps() { return _mm_castsi128_ps(_mm_setallone()); }
66 static inline __m128i CONST _mm_setone_epi8 () { return _mm_set1_epi8(1); }
67 static inline __m128i CONST _mm_setone_epu8 () { return _mm_setone_epi8(); }
68 static inline __m128i CONST _mm_setone_epi16() { return _mm_castps_si128(_mm_broadcast_ss(reinterpret_cast<const float *>(c_general::one16))); }
69 static inline __m128i CONST _mm_setone_epu16() { return _mm_setone_epi16(); }
70 static inline __m128i CONST _mm_setone_epi32() { return _mm_castps_si128(_mm_broadcast_ss(reinterpret_cast<const float *>(&_IndexesFromZero32[1]))); }
72 #if defined(VC_GNU_ASM) && !defined(NVALGRIND)
73 static inline __m256 CONST _mm256_setallone() { __m256 r; __asm__("vcmpps $8,%0,%0,%0":"=x"(r)); return r; }
75 static inline __m256 CONST _mm256_setallone() { __m256 r = _mm256_setzero_ps(); return _mm256_cmp_ps(r, r, _CMP_EQ_UQ); }
77 static inline __m256i CONST _mm256_setallone_si256() { return _mm256_castps_si256(_mm256_setallone()); }
78 static inline __m256d CONST _mm256_setallone_pd() { return _mm256_castps_pd(_mm256_setallone()); }
79 static inline __m256 CONST _mm256_setallone_ps() { return _mm256_setallone(); }
81 static inline __m256i CONST _mm256_setone_epi8 () { return _mm256_set1_epi8(1); }
82 static inline __m256i CONST _mm256_setone_epu8 () { return _mm256_setone_epi8(); }
83 static inline __m256i CONST _mm256_setone_epi16() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(c_general::one16))); }
84 static inline __m256i CONST _mm256_setone_epu16() { return _mm256_setone_epi16(); }
85 static inline __m256i CONST _mm256_setone_epi32() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(&_IndexesFromZero32[1]))); }
86 static inline __m256i CONST _mm256_setone_epu32() { return _mm256_setone_epi32(); }
88 static inline __m256 CONST _mm256_setone_ps() { return _mm256_broadcast_ss(&c_general::oneFloat); }
89 static inline __m256d CONST _mm256_setone_pd() { return _mm256_broadcast_sd(&c_general::oneDouble); }
91 static inline __m256d CONST _mm256_setabsmask_pd() { return _mm256_broadcast_sd(reinterpret_cast<const double *>(&c_general::absMaskFloat[0])); }
92 static inline __m256 CONST _mm256_setabsmask_ps() { return _mm256_broadcast_ss(reinterpret_cast<const float *>(&c_general::absMaskFloat[1])); }
93 static inline __m256d CONST _mm256_setsignmask_pd(){ return _mm256_broadcast_sd(reinterpret_cast<const double *>(&c_general::signMaskFloat[0])); }
94 static inline __m256 CONST _mm256_setsignmask_ps(){ return _mm256_broadcast_ss(reinterpret_cast<const float *>(&c_general::signMaskFloat[1])); }
96 static inline __m256 CONST _mm256_set2power31_ps() { return _mm256_broadcast_ss(&c_general::_2power31); }
97 static inline __m256i CONST _mm256_set2power31_epu32() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(&c_general::signMaskFloat[1]))); }
99 //X static inline __m256i CONST _mm256_setmin_epi8 () { return _mm256_slli_epi8 (_mm256_setallone_si256(), 7); }
100 static inline __m128i CONST _mm_setmin_epi16() { return _mm_castps_si128(_mm_broadcast_ss(reinterpret_cast<const float *>(c_general::minShort))); }
101 static inline __m128i CONST _mm_setmin_epi32() { return _mm_castps_si128(_mm_broadcast_ss(reinterpret_cast<const float *>(&c_general::signMaskFloat[1]))); }
102 static inline __m256i CONST _mm256_setmin_epi16() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(c_general::minShort))); }
103 static inline __m256i CONST _mm256_setmin_epi32() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(&c_general::signMaskFloat[1]))); }
105 #ifdef VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT
106 #define _mm_extract_epu8 _mm_extract_epi8
107 #define _mm_extract_epu16 _mm_extract_epi16
108 #define _mm_extract_epu32 _mm_extract_epi32
110 static inline unsigned char INTRINSIC CONST _mm_extract_epu8(__m128i x, const int i) { return _mm_extract_epi8(x, i); }
111 static inline unsigned short INTRINSIC CONST _mm_extract_epu16(__m128i x, const int i) { return _mm_extract_epi16(x, i); }
112 static inline unsigned int INTRINSIC CONST _mm_extract_epu32(__m128i x, const int i) { return _mm_extract_epi32(x, i); }
115 /////////////////////// COMPARE OPS ///////////////////////
116 static inline __m256d INTRINSIC CONST _mm256_cmpeq_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_EQ_OQ); }
117 static inline __m256d INTRINSIC CONST _mm256_cmpneq_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_NEQ_UQ); }
118 static inline __m256d INTRINSIC CONST _mm256_cmplt_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_LT_OS); }
119 static inline __m256d INTRINSIC CONST _mm256_cmpnlt_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_NLT_US); }
120 static inline __m256d INTRINSIC CONST _mm256_cmple_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_LE_OS); }
121 static inline __m256d INTRINSIC CONST _mm256_cmpnle_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_NLE_US); }
122 static inline __m256d INTRINSIC CONST _mm256_cmpord_pd (__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_ORD_Q); }
123 static inline __m256d INTRINSIC CONST _mm256_cmpunord_pd(__m256d a, __m256d b) { return _mm256_cmp_pd(a, b, _CMP_UNORD_Q); }
125 static inline __m256 INTRINSIC CONST _mm256_cmpeq_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_EQ_OQ); }
126 static inline __m256 INTRINSIC CONST _mm256_cmpneq_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_NEQ_UQ); }
127 static inline __m256 INTRINSIC CONST _mm256_cmplt_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_LT_OS); }
128 static inline __m256 INTRINSIC CONST _mm256_cmpnlt_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_NLT_US); }
129 static inline __m256 INTRINSIC CONST _mm256_cmpge_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_NLT_US); }
130 static inline __m256 INTRINSIC CONST _mm256_cmple_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_LE_OS); }
131 static inline __m256 INTRINSIC CONST _mm256_cmpnle_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_NLE_US); }
132 static inline __m256 INTRINSIC CONST _mm256_cmpgt_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_NLE_US); }
133 static inline __m256 INTRINSIC CONST _mm256_cmpord_ps (__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_ORD_Q); }
134 static inline __m256 INTRINSIC CONST _mm256_cmpunord_ps(__m256 a, __m256 b) { return _mm256_cmp_ps(a, b, _CMP_UNORD_Q); }
136 static inline __m128i _mm_cmplt_epu16(__m128i a, __m128i b) {
137 return _mm_cmplt_epi16(_mm_xor_si128(a, _mm_setmin_epi16()), _mm_xor_si128(b, _mm_setmin_epi16()));
139 static inline __m128i _mm_cmpgt_epu16(__m128i a, __m128i b) {
140 return _mm_cmpgt_epi16(_mm_xor_si128(a, _mm_setmin_epi16()), _mm_xor_si128(b, _mm_setmin_epi16()));
143 /////////////////////// INTEGER OPS ///////////////////////
144 #define AVX_TO_SSE_2(name) \
145 static inline __m256i INTRINSIC CONST _mm256_##name(__m256i a0, __m256i b0) { \
146 __m128i a1 = _mm256_extractf128_si256(a0, 1); \
147 __m128i b1 = _mm256_extractf128_si256(b0, 1); \
148 __m128i r0 = _mm_##name(_mm256_castsi256_si128(a0), _mm256_castsi256_si128(b0)); \
149 __m128i r1 = _mm_##name(a1, b1); \
150 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1); \
152 #define AVX_TO_SSE_2_si128_si256(name) \
153 static inline __m256i INTRINSIC CONST _mm256_##name##_si256(__m256i a0, __m256i b0) { \
154 __m128i a1 = _mm256_extractf128_si256(a0, 1); \
155 __m128i b1 = _mm256_extractf128_si256(b0, 1); \
156 __m128i r0 = _mm_##name##_si128(_mm256_castsi256_si128(a0), _mm256_castsi256_si128(b0)); \
157 __m128i r1 = _mm_##name##_si128(a1, b1); \
158 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1); \
160 #define AVX_TO_SSE_1(name) \
161 static inline __m256i INTRINSIC CONST _mm256_##name(__m256i a0) { \
162 __m128i a1 = _mm256_extractf128_si256(a0, 1); \
163 __m128i r0 = _mm_##name(_mm256_castsi256_si128(a0)); \
164 __m128i r1 = _mm_##name(a1); \
165 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1); \
167 #define AVX_TO_SSE_1i(name) \
168 static inline __m256i INTRINSIC CONST _mm256_##name(__m256i a0, const int i) { \
169 __m128i a1 = _mm256_extractf128_si256(a0, 1); \
170 __m128i r0 = _mm_##name(_mm256_castsi256_si128(a0), i); \
171 __m128i r1 = _mm_##name(a1, i); \
172 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1); \
175 AVX_TO_SSE_2(cmpeq_epi8)
176 AVX_TO_SSE_2(cmpeq_epi16)
177 AVX_TO_SSE_2(cmpeq_epi32)
178 AVX_TO_SSE_2(cmplt_epi8)
179 AVX_TO_SSE_2(cmplt_epi16)
180 AVX_TO_SSE_2(cmplt_epi32)
181 AVX_TO_SSE_2(cmpgt_epi8)
182 AVX_TO_SSE_2(cmpgt_epi16)
183 AVX_TO_SSE_2(cmpgt_epi32)
186 // ICC ships the Integer intrinsics inside the AVX1 header these days.
188 #ifdef VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT
189 # define _mm256_srli_si256(a, i) \
190 _mm256_insertf128_si256( \
191 _mm256_castsi128_si256(_mm_srli_si128(_mm256_castsi256_si128((a)), i)), \
192 _mm_srli_si128(_mm256_extractf128_si256((a), 1), i), 1);
193 # define _mm256_slli_si256(a, i) \
194 _mm256_insertf128_si256( \
195 _mm256_castsi128_si256( _mm_slli_si128(_mm256_castsi256_si128((a)), i)), \
196 _mm_slli_si128(_mm256_extractf128_si256((a), 1), i), 1);
198 static inline __m256i INTRINSIC CONST _mm256_srli_si256(__m256i a0, const int i) {
199 const __m128i r0 = _mm_srli_si128(_mm256_castsi256_si128(a0), i);
200 const __m128i r1 = _mm_srli_si128(_mm256_extractf128_si256(a0, 1), i);
201 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1);
203 static inline __m256i INTRINSIC CONST _mm256_slli_si256(__m256i a0, const int i) {
204 const __m128i r0 = _mm_slli_si128(_mm256_castsi256_si128(a0), i);
205 const __m128i r1 = _mm_slli_si128(_mm256_extractf128_si256(a0, 1), i);
206 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1);
210 static inline __m256i INTRINSIC CONST _mm256_and_si256(__m256i x, __m256i y) {
211 return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(x), _mm256_castsi256_ps(y)));
213 static inline __m256i INTRINSIC CONST _mm256_andnot_si256(__m256i x, __m256i y) {
214 return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(x), _mm256_castsi256_ps(y)));
216 static inline __m256i INTRINSIC CONST _mm256_or_si256(__m256i x, __m256i y) {
217 return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(x), _mm256_castsi256_ps(y)));
219 static inline __m256i INTRINSIC CONST _mm256_xor_si256(__m256i x, __m256i y) {
220 return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(x), _mm256_castsi256_ps(y)));
223 AVX_TO_SSE_2(packs_epi16)
224 AVX_TO_SSE_2(packs_epi32)
225 AVX_TO_SSE_2(packus_epi16)
226 AVX_TO_SSE_2(unpackhi_epi8)
227 AVX_TO_SSE_2(unpackhi_epi16)
228 AVX_TO_SSE_2(unpackhi_epi32)
229 AVX_TO_SSE_2(unpackhi_epi64)
230 AVX_TO_SSE_2(unpacklo_epi8)
231 AVX_TO_SSE_2(unpacklo_epi16)
232 AVX_TO_SSE_2(unpacklo_epi32)
233 AVX_TO_SSE_2(unpacklo_epi64)
234 AVX_TO_SSE_2(add_epi8)
235 AVX_TO_SSE_2(add_epi16)
236 AVX_TO_SSE_2(add_epi32)
237 AVX_TO_SSE_2(add_epi64)
238 AVX_TO_SSE_2(adds_epi8)
239 AVX_TO_SSE_2(adds_epi16)
240 AVX_TO_SSE_2(adds_epu8)
241 AVX_TO_SSE_2(adds_epu16)
242 AVX_TO_SSE_2(sub_epi8)
243 AVX_TO_SSE_2(sub_epi16)
244 AVX_TO_SSE_2(sub_epi32)
245 AVX_TO_SSE_2(sub_epi64)
246 AVX_TO_SSE_2(subs_epi8)
247 AVX_TO_SSE_2(subs_epi16)
248 AVX_TO_SSE_2(subs_epu8)
249 AVX_TO_SSE_2(subs_epu16)
250 AVX_TO_SSE_2(madd_epi16)
251 AVX_TO_SSE_2(mulhi_epi16)
252 AVX_TO_SSE_2(mullo_epi16)
253 AVX_TO_SSE_2(mul_epu32)
254 AVX_TO_SSE_1i(slli_epi16)
255 AVX_TO_SSE_1i(slli_epi32)
256 AVX_TO_SSE_1i(slli_epi64)
257 AVX_TO_SSE_1i(srai_epi16)
258 AVX_TO_SSE_1i(srai_epi32)
259 AVX_TO_SSE_1i(srli_epi16)
260 AVX_TO_SSE_1i(srli_epi32)
261 AVX_TO_SSE_1i(srli_epi64)
262 AVX_TO_SSE_2(sll_epi16)
263 AVX_TO_SSE_2(sll_epi32)
264 AVX_TO_SSE_2(sll_epi64)
265 AVX_TO_SSE_2(sra_epi16)
266 AVX_TO_SSE_2(sra_epi32)
267 AVX_TO_SSE_2(srl_epi16)
268 AVX_TO_SSE_2(srl_epi32)
269 AVX_TO_SSE_2(srl_epi64)
270 AVX_TO_SSE_2(max_epi16)
271 AVX_TO_SSE_2(max_epu8)
272 AVX_TO_SSE_2(min_epi16)
273 AVX_TO_SSE_2(min_epu8)
274 inline int INTRINSIC CONST _mm256_movemask_epi8(__m256i a0)
276 __m128i a1 = _mm256_extractf128_si256(a0, 1);
277 return (_mm_movemask_epi8(a1) << 16) | _mm_movemask_epi8(_mm256_castsi256_si128(a0));
279 AVX_TO_SSE_2(mulhi_epu16)
281 // shufflelo_epi16 (__m128i __A, const int __mask)
282 // shuffle_epi32 (__m128i __A, const int __mask)
283 // maskmoveu_si128 (__m128i __A, __m128i __B, char *__C)
284 AVX_TO_SSE_2(avg_epu8)
285 AVX_TO_SSE_2(avg_epu16)
286 AVX_TO_SSE_2(sad_epu8)
287 // stream_si32 (int *__A, int __B)
288 // stream_si128 (__m128i *__A, __m128i __B)
289 // cvtsi32_si128 (int __A)
290 // cvtsi64_si128 (long long __A)
291 // cvtsi64x_si128 (long long __A)
292 AVX_TO_SSE_2(hadd_epi16)
293 AVX_TO_SSE_2(hadd_epi32)
294 AVX_TO_SSE_2(hadds_epi16)
295 AVX_TO_SSE_2(hsub_epi16)
296 AVX_TO_SSE_2(hsub_epi32)
297 AVX_TO_SSE_2(hsubs_epi16)
298 AVX_TO_SSE_2(maddubs_epi16)
299 AVX_TO_SSE_2(mulhrs_epi16)
300 AVX_TO_SSE_2(shuffle_epi8)
301 AVX_TO_SSE_2(sign_epi8)
302 AVX_TO_SSE_2(sign_epi16)
303 AVX_TO_SSE_2(sign_epi32)
304 // alignr_epi8(__m128i __X, __m128i __Y, const int __N)
305 AVX_TO_SSE_1(abs_epi8)
306 AVX_TO_SSE_1(abs_epi16)
307 AVX_TO_SSE_1(abs_epi32)
308 #if !defined(VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT)
309 __m256i inline INTRINSIC CONST _mm256_blend_epi16(__m256i a0, __m256i b0, const int m) {
310 __m128i a1 = _mm256_extractf128_si256(a0, 1);
311 __m128i b1 = _mm256_extractf128_si256(b0, 1);
312 __m128i r0 = _mm_blend_epi16(_mm256_castsi256_si128(a0), _mm256_castsi256_si128(b0), m & 0xff);
313 __m128i r1 = _mm_blend_epi16(a1, b1, m >> 8);
314 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1);
317 # define _mm256_blend_epi16(a0, b0, m) \
318 _mm256_insertf128_si256( \
319 _mm256_castsi128_si256( \
321 _mm256_castsi256_si128(a0), _mm256_castsi256_si128(b0), m & 0xff)), \
322 _mm_blend_epi16(_mm256_extractf128_si256(a0, 1), _mm256_extractf128_si256(b0, 1), m >> 8);, 1)
324 inline __m256i INTRINSIC CONST _mm256_blendv_epi8(__m256i a0, __m256i b0, __m256i m0) {
325 __m128i a1 = _mm256_extractf128_si256(a0, 1);
326 __m128i b1 = _mm256_extractf128_si256(b0, 1);
327 __m128i m1 = _mm256_extractf128_si256(m0, 1);
328 __m128i r0 = _mm_blendv_epi8(_mm256_castsi256_si128(a0), _mm256_castsi256_si128(b0), _mm256_castsi256_si128(m0));
329 __m128i r1 = _mm_blendv_epi8(a1, b1, m1);
330 return _mm256_insertf128_si256(_mm256_castsi128_si256(r0), r1, 1);
332 AVX_TO_SSE_2(cmpeq_epi64)
333 AVX_TO_SSE_2(min_epi8)
334 AVX_TO_SSE_2(max_epi8)
335 AVX_TO_SSE_2(min_epu16)
336 AVX_TO_SSE_2(max_epu16)
337 AVX_TO_SSE_2(min_epi32)
338 AVX_TO_SSE_2(max_epi32)
339 AVX_TO_SSE_2(min_epu32)
340 AVX_TO_SSE_2(max_epu32)
341 AVX_TO_SSE_2(mullo_epi32)
342 AVX_TO_SSE_2(mul_epi32)
343 #if !defined(VC_CLANG) || VC_CLANG > 0x30100
344 // clang is missing _mm_minpos_epu16 from smmintrin.h
345 // http://llvm.org/bugs/show_bug.cgi?id=12399
346 AVX_TO_SSE_1(minpos_epu16)
348 AVX_TO_SSE_1(cvtepi8_epi32)
349 AVX_TO_SSE_1(cvtepi16_epi32)
350 AVX_TO_SSE_1(cvtepi8_epi64)
351 AVX_TO_SSE_1(cvtepi32_epi64)
352 AVX_TO_SSE_1(cvtepi16_epi64)
353 AVX_TO_SSE_1(cvtepi8_epi16)
354 AVX_TO_SSE_1(cvtepu8_epi32)
355 AVX_TO_SSE_1(cvtepu16_epi32)
356 AVX_TO_SSE_1(cvtepu8_epi64)
357 AVX_TO_SSE_1(cvtepu32_epi64)
358 AVX_TO_SSE_1(cvtepu16_epi64)
359 AVX_TO_SSE_1(cvtepu8_epi16)
360 AVX_TO_SSE_2(packus_epi32)
361 // mpsadbw_epu8 (__m128i __X, __m128i __Y, const int __M)
362 // stream_load_si128 (__m128i *__X)
363 AVX_TO_SSE_2(cmpgt_epi64)
366 //X static inline __m256i _mm256_cmplt_epu8 (__m256i a, __m256i b) { return _mm256_cmplt_epi8 (
367 //X _mm256_xor_si256(a, _mm256_setmin_epi8 ()), _mm256_xor_si256(b, _mm256_setmin_epi8 ())); }
368 //X static inline __m256i _mm256_cmpgt_epu8 (__m256i a, __m256i b) { return _mm256_cmpgt_epi8 (
369 //X _mm256_xor_si256(a, _mm256_setmin_epi8 ()), _mm256_xor_si256(b, _mm256_setmin_epi8 ())); }
370 static inline __m256i CONST _mm256_cmplt_epu32(__m256i a, __m256i b) {
371 a = _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(_mm256_setmin_epi32())));
372 b = _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(_mm256_setmin_epi32())));
373 return _mm256_insertf128_si256(_mm256_castsi128_si256(
374 _mm_cmplt_epi32(_mm256_castsi256_si128(a), _mm256_castsi256_si128(b))),
375 _mm_cmplt_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1)), 1);
377 static inline __m256i CONST _mm256_cmpgt_epu32(__m256i a, __m256i b) {
378 a = _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(a), _mm256_castsi256_ps(_mm256_setmin_epi32())));
379 b = _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(b), _mm256_castsi256_ps(_mm256_setmin_epi32())));
380 return _mm256_insertf128_si256(_mm256_castsi128_si256(
381 _mm_cmpgt_epi32(_mm256_castsi256_si128(a), _mm256_castsi256_si128(b))),
382 _mm_cmpgt_epi32(_mm256_extractf128_si256(a, 1), _mm256_extractf128_si256(b, 1)), 1);
385 static inline void INTRINSIC _mm256_maskstore(float *mem, const __m256 mask, const __m256 v) {
386 #ifndef VC_MM256_MASKSTORE_WRONG_MASK_TYPE
387 _mm256_maskstore_ps(mem, _mm256_castps_si256(mask), v);
389 _mm256_maskstore_ps(mem, mask, v);
392 static inline void INTRINSIC _mm256_maskstore(double *mem, const __m256d mask, const __m256d v) {
393 #ifndef VC_MM256_MASKSTORE_WRONG_MASK_TYPE
394 _mm256_maskstore_pd(mem, _mm256_castpd_si256(mask), v);
396 _mm256_maskstore_pd(mem, mask, v);
399 static inline void INTRINSIC _mm256_maskstore(int *mem, const __m256i mask, const __m256i v) {
400 #ifndef VC_MM256_MASKSTORE_WRONG_MASK_TYPE
401 _mm256_maskstore_ps(reinterpret_cast<float *>(mem), mask, _mm256_castsi256_ps(v));
403 _mm256_maskstore_ps(reinterpret_cast<float *>(mem), _mm256_castsi256_ps(mask), _mm256_castsi256_ps(v));
406 static inline void INTRINSIC _mm256_maskstore(unsigned int *mem, const __m256i mask, const __m256i v) {
407 _mm256_maskstore(reinterpret_cast<int *>(mem), mask, v);
414 #endif // VC_AVX_INTRINSICS_H