]> git.uio.no Git - u/mrichter/AliRoot.git/blob - Vc/include/Vc/avx/intrinsics.h
Vc package added (version 0.6.79-dev)
[u/mrichter/AliRoot.git] / Vc / include / Vc / avx / intrinsics.h
1 /*  This file is part of the Vc library.
2
3     Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
4
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.
9
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.
14
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/>.
17
18 */
19
20 #ifndef VC_AVX_INTRINSICS_H
21 #define VC_AVX_INTRINSICS_H
22
23 #include "../common/windows_fix_intrin.h"
24
25 // AVX
26 #include <immintrin.h>
27
28 #if defined(VC_CLANG) && VC_CLANG < 0x30100
29 // _mm_permute_ps is broken: http://llvm.org/bugs/show_bug.cgi?id=12401
30 #undef _mm_permute_ps
31 #define _mm_permute_ps(A, C) __extension__ ({ \
32   __m128 __A = (A); \
33   (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \
34                                    (C) & 0x3, ((C) & 0xc) >> 2, \
35                                    ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6); })
36 #endif
37
38 #include <Vc/global.h>
39 #include "const_data.h"
40 #include "macros.h"
41 #include <cstdlib>
42
43 #if defined(VC_CLANG) || defined(VC_MSVC) || (defined(VC_GCC) && !defined(__OPTIMIZE__))
44 #define VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT
45 #endif
46
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)))
51 #endif
52
53 namespace Vc
54 {
55 namespace AVX
56 {
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; }
59 #else
60     static inline __m128i CONST _mm_setallone() { __m128i r = _mm_setzero_si128(); return _mm_cmpeq_epi8(r, r); }
61 #endif
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()); }
65
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]))); }
71
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; }
74 #else
75     static inline __m256 CONST _mm256_setallone() { __m256 r = _mm256_setzero_ps(); return _mm256_cmp_ps(r, r, _CMP_EQ_UQ); }
76 #endif
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(); }
80
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(); }
87
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); }
90
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])); }
95
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]))); }
98
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]))); }
104
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
109 #else
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); }
113 #endif
114
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); }
124
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); }
135
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()));
138     }
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()));
141     }
142
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); \
151     }
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); \
159     }
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); \
166     }
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); \
173     }
174
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)
184
185 #ifndef VC_ICC
186     // ICC ships the Integer intrinsics inside the AVX1 header these days.
187
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);
197 #else
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);
202     }
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);
207     }
208 #endif
209
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)));
212     }
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)));
215     }
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)));
218     }
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)));
221     }
222
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)
275     {
276         __m128i a1 = _mm256_extractf128_si256(a0, 1);
277         return (_mm_movemask_epi8(a1) << 16) | _mm_movemask_epi8(_mm256_castsi256_si128(a0));
278     }
279     AVX_TO_SSE_2(mulhi_epu16)
280     // shufflehi_epi16
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);
315     }
316 #else
317 #   define _mm256_blend_epi16(a0, b0, m) \
318     _mm256_insertf128_si256( \
319             _mm256_castsi128_si256( \
320                 _mm_blend_epi16( \
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)
323 #endif
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);
331     }
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)
347 #endif
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)
364 #endif
365
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);
376     }
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);
383     }
384
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);
388 #else
389             _mm256_maskstore_ps(mem, mask, v);
390 #endif
391         }
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);
395 #else
396             _mm256_maskstore_pd(mem, mask, v);
397 #endif
398         }
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));
402 #else
403             _mm256_maskstore_ps(reinterpret_cast<float *>(mem), _mm256_castsi256_ps(mask), _mm256_castsi256_ps(v));
404 #endif
405         }
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);
408         }
409 } // namespace AVX
410 } // namespace Vc
411
412 #include "shuffle.h"
413
414 #endif // VC_AVX_INTRINSICS_H