]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/lib/Headers/avxintrin.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / contrib / llvm / tools / clang / lib / Headers / avxintrin.h
1 /*===---- avxintrin.h - AVX intrinsics -------------------------------------===
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  *
21  *===-----------------------------------------------------------------------===
22  */
23
24 #ifndef __IMMINTRIN_H
25 #error "Never use <avxintrin.h> directly; include <immintrin.h> instead."
26 #endif
27
28 typedef double __v4df __attribute__ ((__vector_size__ (32)));
29 typedef float __v8sf __attribute__ ((__vector_size__ (32)));
30 typedef long long __v4di __attribute__ ((__vector_size__ (32)));
31 typedef int __v8si __attribute__ ((__vector_size__ (32)));
32 typedef short __v16hi __attribute__ ((__vector_size__ (32)));
33 typedef char __v32qi __attribute__ ((__vector_size__ (32)));
34
35 typedef float __m256 __attribute__ ((__vector_size__ (32)));
36 typedef double __m256d __attribute__((__vector_size__(32)));
37 typedef long long __m256i __attribute__((__vector_size__(32)));
38
39 /* Arithmetic */
40 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
41 _mm256_add_pd(__m256d a, __m256d b)
42 {
43   return a+b;
44 }
45
46 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
47 _mm256_add_ps(__m256 a, __m256 b)
48 {
49   return a+b;
50 }
51
52 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
53 _mm256_sub_pd(__m256d a, __m256d b)
54 {
55   return a-b;
56 }
57
58 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
59 _mm256_sub_ps(__m256 a, __m256 b)
60 {
61   return a-b;
62 }
63
64 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
65 _mm256_addsub_pd(__m256d a, __m256d b)
66 {
67   return (__m256d)__builtin_ia32_addsubpd256((__v4df)a, (__v4df)b);
68 }
69
70 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
71 _mm256_addsub_ps(__m256 a, __m256 b)
72 {
73   return (__m256)__builtin_ia32_addsubps256((__v8sf)a, (__v8sf)b);
74 }
75
76 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
77 _mm256_div_pd(__m256d a, __m256d b)
78 {
79   return a / b;
80 }
81
82 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
83 _mm256_div_ps(__m256 a, __m256 b)
84 {
85   return a / b;
86 }
87
88 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
89 _mm256_max_pd(__m256d a, __m256d b)
90 {
91   return (__m256d)__builtin_ia32_maxpd256((__v4df)a, (__v4df)b);
92 }
93
94 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
95 _mm256_max_ps(__m256 a, __m256 b)
96 {
97   return (__m256)__builtin_ia32_maxps256((__v8sf)a, (__v8sf)b);
98 }
99
100 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
101 _mm256_min_pd(__m256d a, __m256d b)
102 {
103   return (__m256d)__builtin_ia32_minpd256((__v4df)a, (__v4df)b);
104 }
105
106 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
107 _mm256_min_ps(__m256 a, __m256 b)
108 {
109   return (__m256)__builtin_ia32_minps256((__v8sf)a, (__v8sf)b);
110 }
111
112 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
113 _mm256_mul_pd(__m256d a, __m256d b)
114 {
115   return a * b;
116 }
117
118 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
119 _mm256_mul_ps(__m256 a, __m256 b)
120 {
121   return a * b;
122 }
123
124 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
125 _mm256_sqrt_pd(__m256d a)
126 {
127   return (__m256d)__builtin_ia32_sqrtpd256((__v4df)a);
128 }
129
130 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
131 _mm256_sqrt_ps(__m256 a)
132 {
133   return (__m256)__builtin_ia32_sqrtps256((__v8sf)a);
134 }
135
136 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
137 _mm256_rsqrt_ps(__m256 a)
138 {
139   return (__m256)__builtin_ia32_rsqrtps256((__v8sf)a);
140 }
141
142 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
143 _mm256_rcp_ps(__m256 a)
144 {
145   return (__m256)__builtin_ia32_rcpps256((__v8sf)a);
146 }
147
148 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
149 _mm256_round_pd(__m256d v, const int m)
150 {
151   return (__m256d)__builtin_ia32_roundpd256((__v4df)v, m);
152 }
153
154 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
155 _mm256_round_ps(__m256 v, const int m)
156 {
157   return (__m256)__builtin_ia32_roundps256((__v8sf)v, m);
158 }
159
160 #define _mm256_ceil_pd(V)  _mm256_round_pd((V), _MM_FROUND_CEIL)
161 #define _mm256_floor_pd(V) _mm256_round_pd((V), _MM_FROUND_FLOOR)
162 #define _mm256_ceil_ps(V)  _mm256_round_ps((V), _MM_FROUND_CEIL)
163 #define _mm256_floor_ps(V) _mm256_round_ps((V), _MM_FROUND_FLOOR)
164
165 /* Logical */
166 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
167 _mm256_and_pd(__m256d a, __m256d b)
168 {
169   return (__m256d)((__v4di)a & (__v4di)b);
170 }
171
172 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
173 _mm256_and_ps(__m256 a, __m256 b)
174 {
175   return (__m256)((__v8si)a & (__v8si)b);
176 }
177
178 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
179 _mm256_andnot_pd(__m256d a, __m256d b)
180 {
181   return (__m256d)(~(__v4di)a & (__v4di)b);
182 }
183
184 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
185 _mm256_andnot_ps(__m256 a, __m256 b)
186 {
187   return (__m256)(~(__v8si)a & (__v8si)b);
188 }
189
190 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
191 _mm256_or_pd(__m256d a, __m256d b)
192 {
193   return (__m256d)((__v4di)a | (__v4di)b);
194 }
195
196 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
197 _mm256_or_ps(__m256 a, __m256 b)
198 {
199   return (__m256)((__v8si)a | (__v8si)b);
200 }
201
202 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
203 _mm256_xor_pd(__m256d a, __m256d b)
204 {
205   return (__m256d)((__v4di)a ^ (__v4di)b);
206 }
207
208 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
209 _mm256_xor_ps(__m256 a, __m256 b)
210 {
211   return (__m256)((__v8si)a ^ (__v8si)b);
212 }
213
214 /* Horizontal arithmetic */
215 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
216 _mm256_hadd_pd(__m256d a, __m256d b)
217 {
218   return (__m256d)__builtin_ia32_haddpd256((__v4df)a, (__v4df)b);
219 }
220
221 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
222 _mm256_hadd_ps(__m256 a, __m256 b)
223 {
224   return (__m256)__builtin_ia32_haddps256((__v8sf)a, (__v8sf)b);
225 }
226
227 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
228 _mm256_hsub_pd(__m256d a, __m256d b)
229 {
230   return (__m256d)__builtin_ia32_hsubpd256((__v4df)a, (__v4df)b);
231 }
232
233 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
234 _mm256_hsub_ps(__m256 a, __m256 b)
235 {
236   return (__m256)__builtin_ia32_hsubps256((__v8sf)a, (__v8sf)b);
237 }
238
239 /* Vector permutations */
240 static __inline __m128d __attribute__((__always_inline__, __nodebug__))
241 _mm_permutevar_pd(__m128d a, __m128i c)
242 {
243   return (__m128d)__builtin_ia32_vpermilvarpd((__v2df)a, (__v2di)c);
244 }
245
246 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
247 _mm256_permutevar_pd(__m256d a, __m256i c)
248 {
249   return (__m256d)__builtin_ia32_vpermilvarpd256((__v4df)a, (__v4di)c);
250 }
251
252 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
253 _mm_permutevar_ps(__m128 a, __m128i c)
254 {
255   return (__m128)__builtin_ia32_vpermilvarps((__v4sf)a, (__v4si)c);
256 }
257
258 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
259 _mm256_permutevar_ps(__m256 a, __m256i c)
260 {
261   return (__m256)__builtin_ia32_vpermilvarps256((__v8sf)a,
262                                                   (__v8si)c);
263 }
264
265 static __inline __m128d __attribute__((__always_inline__, __nodebug__))
266 _mm_permute_pd(__m128d a, const int c)
267 {
268   return (__m128d)__builtin_ia32_vpermilpd((__v2df)a, c);
269 }
270
271 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
272 _mm256_permute_pd(__m256d a, const int c)
273 {
274   return (__m256d)__builtin_ia32_vpermilpd256((__v4df)a, c);
275 }
276
277 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
278 _mm_permute_ps(__m128 a, const int c)
279 {
280   return (__m128)__builtin_ia32_vpermilps((__v4sf)a, c);
281 }
282
283 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
284 _mm256_permute_ps(__m256 a, const int c)
285 {
286   return (__m256)__builtin_ia32_vpermilps256((__v8sf)a, c);
287 }
288
289 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
290 _mm256_permute2f128_pd(__m256d a, __m256d b, const int c)
291 {
292   return (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)a, (__v4df)b, c);
293 }
294
295 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
296 _mm256_permute2f128_ps(__m256 a, __m256 b, const int c)
297 {
298   return (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)a, (__v8sf)b, c);
299 }
300
301 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
302 _mm256_permute2f128_si256(__m256i a, __m256i b, const int c)
303 {
304   return (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)a, (__v8si)b, c);
305 }
306
307 /* Vector Blend */
308 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
309 _mm256_blend_pd(__m256d a, __m256d b, const int c)
310 {
311   return (__m256d)__builtin_ia32_blendpd256((__v4df)a, (__v4df)b, c);
312 }
313
314 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
315 _mm256_blend_ps(__m256 a, __m256 b, const int c)
316 {
317   return (__m256)__builtin_ia32_blendps256((__v8sf)a, (__v8sf)b, c);
318 }
319
320 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
321 _mm256_blendv_pd(__m256d a, __m256d b, __m256d c)
322 {
323   return (__m256d)__builtin_ia32_blendvpd256((__v4df)a, (__v4df)b, (__v4df)c);
324 }
325
326 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
327 _mm256_blendv_ps(__m256 a, __m256 b, __m256 c)
328 {
329   return (__m256)__builtin_ia32_blendvps256((__v8sf)a, (__v8sf)b, (__v8sf)c);
330 }
331
332 /* Vector Dot Product */
333 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
334 _mm256_dp_ps(__m256 a, __m256 b, const int c)
335 {
336   return (__m256)__builtin_ia32_dpps256((__v8sf)a, (__v8sf)b, c);
337 }
338
339 /* Vector shuffle */
340 #define _mm256_shuffle_ps(a, b, mask) \
341         (__builtin_shufflevector((__v8sf)(a), (__v8sf)(b), \
342         (mask) & 0x3,                ((mask) & 0xc) >> 2, \
343         (((mask) & 0x30) >> 4) + 8,  (((mask) & 0xc0) >> 6) + 8, \
344         ((mask) & 0x3) + 4,          (((mask) & 0xc) >> 2) + 4, \
345         (((mask) & 0x30) >> 4) + 12, (((mask) & 0xc0) >> 6) + 12))
346
347 #define _mm256_shuffle_pd(a, b, mask) \
348         (__builtin_shufflevector((__v4df)(a), (__v4df)(b), \
349         (mask) & 0x1, \
350         (((mask) & 0x2) >> 1) + 4, \
351         (((mask) & 0x4) >> 2) + 2, \
352         (((mask) & 0x8) >> 3) + 6))
353
354 /* Compare */
355 #define _CMP_EQ_OQ    0x00 /* Equal (ordered, non-signaling)  */
356 #define _CMP_LT_OS    0x01 /* Less-than (ordered, signaling)  */
357 #define _CMP_LE_OS    0x02 /* Less-than-or-equal (ordered, signaling)  */
358 #define _CMP_UNORD_Q  0x03 /* Unordered (non-signaling)  */
359 #define _CMP_NEQ_UQ   0x04 /* Not-equal (unordered, non-signaling)  */
360 #define _CMP_NLT_US   0x05 /* Not-less-than (unordered, signaling)  */
361 #define _CMP_NLE_US   0x06 /* Not-less-than-or-equal (unordered, signaling)  */
362 #define _CMP_ORD_Q    0x07 /* Ordered (nonsignaling)   */
363 #define _CMP_EQ_UQ    0x08 /* Equal (unordered, non-signaling)  */
364 #define _CMP_NGE_US   0x09 /* Not-greater-than-or-equal (unord, signaling)  */
365 #define _CMP_NGT_US   0x0a /* Not-greater-than (unordered, signaling)  */
366 #define _CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling)  */
367 #define _CMP_NEQ_OQ   0x0c /* Not-equal (ordered, non-signaling)  */
368 #define _CMP_GE_OS    0x0d /* Greater-than-or-equal (ordered, signaling)  */
369 #define _CMP_GT_OS    0x0e /* Greater-than (ordered, signaling)  */
370 #define _CMP_TRUE_UQ  0x0f /* True (unordered, non-signaling)  */
371 #define _CMP_EQ_OS    0x10 /* Equal (ordered, signaling)  */
372 #define _CMP_LT_OQ    0x11 /* Less-than (ordered, non-signaling)  */
373 #define _CMP_LE_OQ    0x12 /* Less-than-or-equal (ordered, non-signaling)  */
374 #define _CMP_UNORD_S  0x13 /* Unordered (signaling)  */
375 #define _CMP_NEQ_US   0x14 /* Not-equal (unordered, signaling)  */
376 #define _CMP_NLT_UQ   0x15 /* Not-less-than (unordered, non-signaling)  */
377 #define _CMP_NLE_UQ   0x16 /* Not-less-than-or-equal (unord, non-signaling)  */
378 #define _CMP_ORD_S    0x17 /* Ordered (signaling)  */
379 #define _CMP_EQ_US    0x18 /* Equal (unordered, signaling)  */
380 #define _CMP_NGE_UQ   0x19 /* Not-greater-than-or-equal (unord, non-sign)  */
381 #define _CMP_NGT_UQ   0x1a /* Not-greater-than (unordered, non-signaling)  */
382 #define _CMP_FALSE_OS 0x1b /* False (ordered, signaling)  */
383 #define _CMP_NEQ_OS   0x1c /* Not-equal (ordered, signaling)  */
384 #define _CMP_GE_OQ    0x1d /* Greater-than-or-equal (ordered, non-signaling)  */
385 #define _CMP_GT_OQ    0x1e /* Greater-than (ordered, non-signaling)  */
386 #define _CMP_TRUE_US  0x1f /* True (unordered, signaling)  */
387
388 #define _mm_cmp_pd(a, b, c) \
389   (__m128d)__builtin_ia32_cmppd((__v2df)(a), (__v2df)(b), (c))
390
391 #define _mm_cmp_ps(a, b, c) \
392   (__m128)__builtin_ia32_cmpps((__v4sf)(a), (__v4sf)(b), (c))
393
394 #define _mm256_cmp_pd(a, b, c) \
395   (__m256d)__builtin_ia32_cmppd256((__v4df)(a), (__v4df)(b), (c))
396
397 #define _mm256_cmp_ps(a, b, c) \
398   (__m256)__builtin_ia32_cmpps256((__v8sf)(a), (__v8sf)(b), (c))
399
400 #define _mm_cmp_sd(a, b, c) \
401   (__m128d)__builtin_ia32_cmpsd((__v2df)(a), (__v2df)(b), (c))
402
403 #define _mm_cmp_ss(a, b, c) \
404   (__m128)__builtin_ia32_cmpss((__v4sf)(a), (__v4sf)(b), (c))
405
406 /* Vector extract */
407 static __inline __m128d __attribute__((__always_inline__, __nodebug__))
408 _mm256_extractf128_pd(__m256d a, const int o)
409 {
410   return (__m128d)__builtin_ia32_vextractf128_pd256((__v4df)a, o);
411 }
412
413 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
414 _mm256_extractf128_ps(__m256 a, const int o)
415 {
416   return (__m128)__builtin_ia32_vextractf128_ps256((__v8sf)a, o);
417 }
418
419 static __inline __m128i __attribute__((__always_inline__, __nodebug__))
420 _mm256_extractf128_si256(__m256i a, const int o)
421 {
422   return (__m128i)__builtin_ia32_vextractf128_si256((__v8si)a, o);
423 }
424
425 static __inline int __attribute__((__always_inline__, __nodebug__))
426 _mm256_extract_epi32(__m256i a, int const imm)
427 {
428   __v8si b = (__v8si)a;
429   return b[imm];
430 }
431
432 static __inline int __attribute__((__always_inline__, __nodebug__))
433 _mm256_extract_epi16(__m256i a, int const imm)
434 {
435   __v16hi b = (__v16hi)a;
436   return b[imm];
437 }
438
439 static __inline int __attribute__((__always_inline__, __nodebug__))
440 _mm256_extract_epi8(__m256i a, int const imm)
441 {
442   __v32qi b = (__v32qi)a;
443   return b[imm];
444 }
445
446 #ifdef __x86_64__
447 static __inline long long  __attribute__((__always_inline__, __nodebug__))
448 _mm256_extract_epi64(__m256i a, const int imm)
449 {
450   __v4di b = (__v4di)a;
451   return b[imm];
452 }
453 #endif
454
455 /* Vector insert */
456 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
457 _mm256_insertf128_pd(__m256d a, __m128d b, const int o)
458 {
459   return (__m256d)__builtin_ia32_vinsertf128_pd256((__v4df)a, (__v2df)b, o);
460 }
461
462 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
463 _mm256_insertf128_ps(__m256 a, __m128 b, const int o)
464 {
465   return (__m256)__builtin_ia32_vinsertf128_ps256((__v8sf)a, (__v4sf)b, o);
466 }
467
468 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
469 _mm256_insertf128_si256(__m256i a, __m128i b, const int o)
470 {
471   return (__m256i)__builtin_ia32_vinsertf128_si256((__v8si)a, (__v4si)b, o);
472 }
473
474 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
475 _mm256_insert_epi32(__m256i a, int b, int const imm)
476 {
477   __v8si c = (__v8si)a;
478   c[imm & 7] = b;
479   return (__m256i)c;
480 }
481
482 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
483 _mm256_insert_epi16(__m256i a, int b, int const imm)
484 {
485   __v16hi c = (__v16hi)a;
486   c[imm & 15] = b;
487   return (__m256i)c;
488 }
489
490 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
491 _mm256_insert_epi8(__m256i a, int b, int const imm)
492 {
493   __v32qi c = (__v32qi)a;
494   c[imm & 31] = b;
495   return (__m256i)c;
496 }
497
498 #ifdef __x86_64__
499 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
500 _mm256_insert_epi64(__m256i a, int b, int const imm)
501 {
502   __v4di c = (__v4di)a;
503   c[imm & 3] = b;
504   return (__m256i)c;
505 }
506 #endif
507
508 /* Conversion */
509 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
510 _mm256_cvtepi32_pd(__m128i a)
511 {
512   return (__m256d)__builtin_ia32_cvtdq2pd256((__v4si) a);
513 }
514
515 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
516 _mm256_cvtepi32_ps(__m256i a)
517 {
518   return (__m256)__builtin_ia32_cvtdq2ps256((__v8si) a);
519 }
520
521 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
522 _mm256_cvtpd_ps(__m256d a)
523 {
524   return (__m128)__builtin_ia32_cvtpd2ps256((__v4df) a);
525 }
526
527 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
528 _mm256_cvtps_epi32(__m256 a)
529 {
530   return (__m256i)__builtin_ia32_cvtps2dq256((__v8sf) a);
531 }
532
533 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
534 _mm256_cvtps_pd(__m128 a)
535 {
536   return (__m256d)__builtin_ia32_cvtps2pd256((__v4sf) a);
537 }
538
539 static __inline __m128i __attribute__((__always_inline__, __nodebug__))
540 _mm256_cvttpd_epi32(__m256d a)
541 {
542   return (__m128i)__builtin_ia32_cvttpd2dq256((__v4df) a);
543 }
544
545 static __inline __m128i __attribute__((__always_inline__, __nodebug__))
546 _mm256_cvtpd_epi32(__m256d a)
547 {
548   return (__m128i)__builtin_ia32_cvtpd2dq256((__v4df) a);
549 }
550
551 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
552 _mm256_cvttps_epi32(__m256 a)
553 {
554   return (__m256i)__builtin_ia32_cvttps2dq256((__v8sf) a);
555 }
556
557 /* Vector replicate */
558 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
559 _mm256_movehdup_ps(__m256 a)
560 {
561   return __builtin_shufflevector(a, a, 1, 1, 3, 3, 5, 5, 7, 7);
562 }
563
564 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
565 _mm256_moveldup_ps(__m256 a)
566 {
567   return __builtin_shufflevector(a, a, 0, 0, 2, 2, 4, 4, 6, 6);
568 }
569
570 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
571 _mm256_movedup_pd(__m256d a)
572 {
573   return __builtin_shufflevector(a, a, 0, 0, 2, 2);
574 }
575
576 /* Unpack and Interleave */
577 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
578 _mm256_unpackhi_pd(__m256d a, __m256d b)
579 {
580   return __builtin_shufflevector(a, b, 1, 5, 1+2, 5+2);
581 }
582
583 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
584 _mm256_unpacklo_pd(__m256d a, __m256d b)
585 {
586   return __builtin_shufflevector(a, b, 0, 4, 0+2, 4+2);
587 }
588
589 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
590 _mm256_unpackhi_ps(__m256 a, __m256 b)
591 {
592   return __builtin_shufflevector(a, b, 2, 10, 2+1, 10+1, 6, 14, 6+1, 14+1);
593 }
594
595 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
596 _mm256_unpacklo_ps(__m256 a, __m256 b)
597 {
598   return __builtin_shufflevector(a, b, 0, 8, 0+1, 8+1, 4, 12, 4+1, 12+1);
599 }
600
601 /* Bit Test */
602 static __inline int __attribute__((__always_inline__, __nodebug__))
603 _mm_testz_pd(__m128d a, __m128d b)
604 {
605   return __builtin_ia32_vtestzpd((__v2df)a, (__v2df)b);
606 }
607
608 static __inline int __attribute__((__always_inline__, __nodebug__))
609 _mm_testc_pd(__m128d a, __m128d b)
610 {
611   return __builtin_ia32_vtestcpd((__v2df)a, (__v2df)b);
612 }
613
614 static __inline int __attribute__((__always_inline__, __nodebug__))
615 _mm_testnzc_pd(__m128d a, __m128d b)
616 {
617   return __builtin_ia32_vtestnzcpd((__v2df)a, (__v2df)b);
618 }
619
620 static __inline int __attribute__((__always_inline__, __nodebug__))
621 _mm_testz_ps(__m128 a, __m128 b)
622 {
623   return __builtin_ia32_vtestzps((__v4sf)a, (__v4sf)b);
624 }
625
626 static __inline int __attribute__((__always_inline__, __nodebug__))
627 _mm_testc_ps(__m128 a, __m128 b)
628 {
629   return __builtin_ia32_vtestcps((__v4sf)a, (__v4sf)b);
630 }
631
632 static __inline int __attribute__((__always_inline__, __nodebug__))
633 _mm_testnzc_ps(__m128 a, __m128 b)
634 {
635   return __builtin_ia32_vtestnzcps((__v4sf)a, (__v4sf)b);
636 }
637
638 static __inline int __attribute__((__always_inline__, __nodebug__))
639 _mm256_testz_pd(__m256d a, __m256d b)
640 {
641   return __builtin_ia32_vtestzpd256((__v4df)a, (__v4df)b);
642 }
643
644 static __inline int __attribute__((__always_inline__, __nodebug__))
645 _mm256_testc_pd(__m256d a, __m256d b)
646 {
647   return __builtin_ia32_vtestcpd256((__v4df)a, (__v4df)b);
648 }
649
650 static __inline int __attribute__((__always_inline__, __nodebug__))
651 _mm256_testnzc_pd(__m256d a, __m256d b)
652 {
653   return __builtin_ia32_vtestnzcpd256((__v4df)a, (__v4df)b);
654 }
655
656 static __inline int __attribute__((__always_inline__, __nodebug__))
657 _mm256_testz_ps(__m256 a, __m256 b)
658 {
659   return __builtin_ia32_vtestzps256((__v8sf)a, (__v8sf)b);
660 }
661
662 static __inline int __attribute__((__always_inline__, __nodebug__))
663 _mm256_testc_ps(__m256 a, __m256 b)
664 {
665   return __builtin_ia32_vtestcps256((__v8sf)a, (__v8sf)b);
666 }
667
668 static __inline int __attribute__((__always_inline__, __nodebug__))
669 _mm256_testnzc_ps(__m256 a, __m256 b)
670 {
671   return __builtin_ia32_vtestnzcps256((__v8sf)a, (__v8sf)b);
672 }
673
674 static __inline int __attribute__((__always_inline__, __nodebug__))
675 _mm256_testz_si256(__m256i a, __m256i b)
676 {
677   return __builtin_ia32_ptestz256((__v4di)a, (__v4di)b);
678 }
679
680 static __inline int __attribute__((__always_inline__, __nodebug__))
681 _mm256_testc_si256(__m256i a, __m256i b)
682 {
683   return __builtin_ia32_ptestc256((__v4di)a, (__v4di)b);
684 }
685
686 static __inline int __attribute__((__always_inline__, __nodebug__))
687 _mm256_testnzc_si256(__m256i a, __m256i b)
688 {
689   return __builtin_ia32_ptestnzc256((__v4di)a, (__v4di)b);
690 }
691
692 /* Vector extract sign mask */
693 static __inline int __attribute__((__always_inline__, __nodebug__))
694 _mm256_movemask_pd(__m256d a)
695 {
696   return __builtin_ia32_movmskpd256((__v4df)a);
697 }
698
699 static __inline int __attribute__((__always_inline__, __nodebug__))
700 _mm256_movemask_ps(__m256 a)
701 {
702   return __builtin_ia32_movmskps256((__v8sf)a);
703 }
704
705 /* Vector zero */
706 static __inline void __attribute__((__always_inline__, __nodebug__))
707 _mm256_zeroall(void)
708 {
709   __builtin_ia32_vzeroall();
710 }
711
712 static __inline void __attribute__((__always_inline__, __nodebug__))
713 _mm256_zeroupper(void)
714 {
715   __builtin_ia32_vzeroupper();
716 }
717
718 /* Vector load with broadcast */
719 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
720 _mm_broadcast_ss(float const *a)
721 {
722   return (__m128)__builtin_ia32_vbroadcastss(a);
723 }
724
725 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
726 _mm256_broadcast_sd(double const *a)
727 {
728   return (__m256d)__builtin_ia32_vbroadcastsd256(a);
729 }
730
731 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
732 _mm256_broadcast_ss(float const *a)
733 {
734   return (__m256)__builtin_ia32_vbroadcastss256(a);
735 }
736
737 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
738 _mm256_broadcast_pd(__m128d const *a)
739 {
740   return (__m256d)__builtin_ia32_vbroadcastf128_pd256(a);
741 }
742
743 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
744 _mm256_broadcast_ps(__m128 const *a)
745 {
746   return (__m256)__builtin_ia32_vbroadcastf128_ps256(a);
747 }
748
749 /* SIMD load ops */
750 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
751 _mm256_load_pd(double const *p)
752 {
753   return *(__m256d *)p;
754 }
755
756 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
757 _mm256_load_ps(float const *p)
758 {
759   return *(__m256 *)p;
760 }
761
762 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
763 _mm256_loadu_pd(double const *p)
764 {
765   return (__m256d)__builtin_ia32_loadupd256(p);
766 }
767
768 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
769 _mm256_loadu_ps(float const *p)
770 {
771   return (__m256)__builtin_ia32_loadups256(p);
772 }
773
774 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
775 _mm256_load_si256(__m256i const *p)
776 {
777   return *p;
778 }
779
780 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
781 _mm256_loadu_si256(__m256i const *p)
782 {
783   return (__m256i)__builtin_ia32_loaddqu256((char const *)p);
784 }
785
786 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
787 _mm256_lddqu_si256(__m256i const *p)
788 {
789   return (__m256i)__builtin_ia32_lddqu256((char const *)p);
790 }
791
792 /* SIMD store ops */
793 static __inline void __attribute__((__always_inline__, __nodebug__))
794 _mm256_store_pd(double *p, __m256d a)
795 {
796   *(__m256d *)p = a;
797 }
798
799 static __inline void __attribute__((__always_inline__, __nodebug__))
800 _mm256_store_ps(float *p, __m256 a)
801 {
802   *(__m256 *)p = a;
803 }
804
805 static __inline void __attribute__((__always_inline__, __nodebug__))
806 _mm256_storeu_pd(double *p, __m256d a)
807 {
808   __builtin_ia32_storeupd256(p, (__v4df)a);
809 }
810
811 static __inline void __attribute__((__always_inline__, __nodebug__))
812 _mm256_storeu_ps(float *p, __m256 a)
813 {
814   __builtin_ia32_storeups256(p, (__v8sf)a);
815 }
816
817 static __inline void __attribute__((__always_inline__, __nodebug__))
818 _mm256_store_si256(__m256i *p, __m256i a)
819 {
820   *p = a;
821 }
822
823 static __inline void __attribute__((__always_inline__, __nodebug__))
824 _mm256_storeu_si256(__m256i *p, __m256i a)
825 {
826   __builtin_ia32_storedqu256((char *)p, (__v32qi)a);
827 }
828
829 /* Conditional load ops */
830 static __inline __m128d __attribute__((__always_inline__, __nodebug__))
831 _mm_maskload_pd(double const *p, __m128d m)
832 {
833   return (__m128d)__builtin_ia32_maskloadpd((const __v2df *)p, (__v2df)m);
834 }
835
836 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
837 _mm256_maskload_pd(double const *p, __m256d m)
838 {
839   return (__m256d)__builtin_ia32_maskloadpd256((const __v4df *)p, (__v4df)m);
840 }
841
842 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
843 _mm_maskload_ps(float const *p, __m128 m)
844 {
845   return (__m128)__builtin_ia32_maskloadps((const __v4sf *)p, (__v4sf)m);
846 }
847
848 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
849 _mm256_maskload_ps(float const *p, __m256 m)
850 {
851   return (__m256)__builtin_ia32_maskloadps256((const __v8sf *)p, (__v8sf)m);
852 }
853
854 /* Conditional store ops */
855 static __inline void __attribute__((__always_inline__, __nodebug__))
856 _mm256_maskstore_ps(float *p, __m256 m, __m256 a)
857 {
858   __builtin_ia32_maskstoreps256((__v8sf *)p, (__v8sf)m, (__v8sf)a);
859 }
860
861 static __inline void __attribute__((__always_inline__, __nodebug__))
862 _mm_maskstore_pd(double *p, __m128d m, __m128d a)
863 {
864   __builtin_ia32_maskstorepd((__v2df *)p, (__v2df)m, (__v2df)a);
865 }
866
867 static __inline void __attribute__((__always_inline__, __nodebug__))
868 _mm256_maskstore_pd(double *p, __m256d m, __m256d a)
869 {
870   __builtin_ia32_maskstorepd256((__v4df *)p, (__v4df)m, (__v4df)a);
871 }
872
873 static __inline void __attribute__((__always_inline__, __nodebug__))
874 _mm_maskstore_ps(float *p, __m128 m, __m128 a)
875 {
876   __builtin_ia32_maskstoreps((__v4sf *)p, (__v4sf)m, (__v4sf)a);
877 }
878
879 /* Cacheability support ops */
880 static __inline void __attribute__((__always_inline__, __nodebug__))
881 _mm256_stream_si256(__m256i *a, __m256i b)
882 {
883   __builtin_ia32_movntdq256((__v4di *)a, (__v4di)b);
884 }
885
886 static __inline void __attribute__((__always_inline__, __nodebug__))
887 _mm256_stream_pd(double *a, __m256d b)
888 {
889   __builtin_ia32_movntpd256(a, (__v4df)b);
890 }
891
892 static __inline void __attribute__((__always_inline__, __nodebug__))
893 _mm256_stream_ps(float *p, __m256 a)
894 {
895   __builtin_ia32_movntps256(p, (__v8sf)a);
896 }
897
898 /* Create vectors */
899 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
900 _mm256_set_pd(double a, double b, double c, double d)
901 {
902   return (__m256d){ d, c, b, a };
903 }
904
905 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
906 _mm256_set_ps(float a, float b, float c, float d,
907                     float e, float f, float g, float h)
908 {
909   return (__m256){ h, g, f, e, d, c, b, a };
910 }
911
912 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
913 _mm256_set_epi32(int i0, int i1, int i2, int i3,
914                              int i4, int i5, int i6, int i7)
915 {
916   return (__m256i)(__v8si){ i7, i6, i5, i4, i3, i2, i1, i0 };
917 }
918
919 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
920 _mm256_set_epi16(short w15, short w14, short w13, short w12,
921                              short w11, short w10, short w09, short w08,
922                              short w07, short w06, short w05, short w04,
923                              short w03, short w02, short w01, short w00)
924 {
925   return (__m256i)(__v16hi){ w00, w01, w02, w03, w04, w05, w06, w07,
926                              w08, w09, w10, w11, w12, w13, w14, w15 };
927 }
928
929 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
930 _mm256_set_epi8(char b31, char b30, char b29, char b28,
931                             char b27, char b26, char b25, char b24,
932                             char b23, char b22, char b21, char b20,
933                             char b19, char b18, char b17, char b16,
934                             char b15, char b14, char b13, char b12,
935                             char b11, char b10, char b09, char b08,
936                             char b07, char b06, char b05, char b04,
937                             char b03, char b02, char b01, char b00)
938 {
939   return (__m256i)(__v32qi){
940     b00, b01, b02, b03, b04, b05, b06, b07,
941     b08, b09, b10, b11, b12, b13, b14, b15,
942     b16, b17, b18, b19, b20, b21, b22, b23,
943     b24, b25, b26, b27, b28, b29, b30, b31
944   };
945 }
946
947 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
948 _mm256_set_epi64x(long long a, long long b, long long c, long long d)
949 {
950   return (__m256i)(__v4di){ d, c, b, a };
951 }
952
953 /* Create vectors with elements in reverse order */
954 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
955 _mm256_setr_pd(double a, double b, double c, double d)
956 {
957   return (__m256d){ a, b, c, d };
958 }
959
960 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
961 _mm256_setr_ps(float a, float b, float c, float d,
962                            float e, float f, float g, float h)
963 {
964   return (__m256){ a, b, c, d, e, f, g, h };
965 }
966
967 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
968 _mm256_setr_epi32(int i0, int i1, int i2, int i3,
969                               int i4, int i5, int i6, int i7)
970 {
971   return (__m256i)(__v8si){ i0, i1, i2, i3, i4, i5, i6, i7 };
972 }
973
974 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
975 _mm256_setr_epi16(short w15, short w14, short w13, short w12,
976                    short w11, short w10, short w09, short w08,
977                    short w07, short w06, short w05, short w04,
978                    short w03, short w02, short w01, short w00)
979 {
980   return (__m256i)(__v16hi){ w15, w14, w13, w12, w11, w10, w09, w08,
981                                                w07, w06, w05, w04, w03, w02, w01, w00 };
982 }
983
984 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
985 _mm256_setr_epi8(char b31, char b30, char b29, char b28,
986                              char b27, char b26, char b25, char b24,
987                              char b23, char b22, char b21, char b20,
988                              char b19, char b18, char b17, char b16,
989                              char b15, char b14, char b13, char b12,
990                              char b11, char b10, char b09, char b08,
991                              char b07, char b06, char b05, char b04,
992                              char b03, char b02, char b01, char b00)
993 {
994   return (__m256i)(__v32qi){
995     b31, b30, b29, b28, b27, b26, b25, b24,
996                 b23, b22, b21, b20, b19, b18, b17, b16,
997                 b15, b14, b13, b12, b11, b10, b09, b08,
998                 b07, b06, b05, b04, b03, b02, b01, b00 };
999 }
1000
1001 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1002 _mm256_setr_epi64x(long long a, long long b, long long c, long long d)
1003 {
1004   return (__m256i)(__v4di){ a, b, c, d };
1005 }
1006
1007 /* Create vectors with repeated elements */
1008 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
1009 _mm256_set1_pd(double w)
1010 {
1011   return (__m256d){ w, w, w, w };
1012 }
1013
1014 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
1015 _mm256_set1_ps(float w)
1016 {
1017   return (__m256){ w, w, w, w, w, w, w, w };
1018 }
1019
1020 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1021 _mm256_set1_epi32(int i)
1022 {
1023   return (__m256i)(__v8si){ i, i, i, i, i, i, i, i };
1024 }
1025
1026 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1027 _mm256_set1_epi16(short w)
1028 {
1029   return (__m256i)(__v16hi){ w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w };
1030 }
1031
1032 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1033 _mm256_set1_epi8(char b)
1034 {
1035   return (__m256i)(__v32qi){ b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b,
1036                              b, b, b, b, b, b, b, b, b, b, b, b, b, b, b, b };
1037 }
1038
1039 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1040 _mm256_set1_epi64x(long long q)
1041 {
1042   return (__m256i)(__v4di){ q, q, q, q };
1043 }
1044
1045 /* Create zeroed vectors */
1046 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
1047 _mm256_setzero_pd(void)
1048 {
1049   return (__m256d){ 0, 0, 0, 0 };
1050 }
1051
1052 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
1053 _mm256_setzero_ps(void)
1054 {
1055   return (__m256){ 0, 0, 0, 0, 0, 0, 0, 0 };
1056 }
1057
1058 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1059 _mm256_setzero_si256(void)
1060 {
1061   return (__m256i){ 0LL, 0LL, 0LL, 0LL };
1062 }
1063
1064 /* Cast between vector types */
1065 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
1066 _mm256_castpd_ps(__m256d in)
1067 {
1068   return (__m256)in;
1069 }
1070
1071 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1072 _mm256_castpd_si256(__m256d in)
1073 {
1074   return (__m256i)in;
1075 }
1076
1077 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
1078 _mm256_castps_pd(__m256 in)
1079 {
1080   return (__m256d)in;
1081 }
1082
1083 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1084 _mm256_castps_si256(__m256 in)
1085 {
1086   return (__m256i)in;
1087 }
1088
1089 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
1090 _mm256_castsi256_ps(__m256i in)
1091 {
1092   return (__m256)in;
1093 }
1094
1095 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
1096 _mm256_castsi256_pd(__m256i in)
1097 {
1098   return (__m256d)in;
1099 }
1100
1101 static __inline __m128d __attribute__((__always_inline__, __nodebug__))
1102 _mm256_castpd256_pd128(__m256d in)
1103 {
1104   return __builtin_shufflevector(in, in, 0, 1);
1105 }
1106
1107 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
1108 _mm256_castps256_ps128(__m256 in)
1109 {
1110   return __builtin_shufflevector(in, in, 0, 1, 2, 3);
1111 }
1112
1113 static __inline __m128i __attribute__((__always_inline__, __nodebug__))
1114 _mm256_castsi256_si128(__m256i in)
1115 {
1116   return __builtin_shufflevector(in, in, 0, 1);
1117 }
1118
1119 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
1120 _mm256_castpd128_pd256(__m128d in)
1121 {
1122   __m128d zero = _mm_setzero_pd();
1123   return __builtin_shufflevector(in, zero, 0, 1, 2, 2);
1124 }
1125
1126 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
1127 _mm256_castps128_ps256(__m128 in)
1128 {
1129   __m128 zero = _mm_setzero_ps();
1130   return __builtin_shufflevector(in, zero, 0, 1, 2, 3, 4, 4, 4, 4);
1131 }
1132
1133 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
1134 _mm256_castsi128_si256(__m128i in)
1135 {
1136   __m128i zero = _mm_setzero_si128();
1137   return __builtin_shufflevector(in, zero, 0, 1, 2, 2);
1138 }