1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2015 Intel Corporation
3  */
4 
5 #ifndef _RTE_VECT_X86_H_
6 #define _RTE_VECT_X86_H_
7 
8 /**
9  * @file
10  *
11  * RTE SSE/AVX related header.
12  */
13 
14 #include <stdint.h>
15 #include <rte_config.h>
16 #include <rte_common.h>
17 #include "generic/rte_vect.h"
18 
19 #if (defined(__ICC) || \
20 	(defined(_WIN64)) || \
21 	(__GNUC__ == 4 &&  __GNUC_MINOR__ < 4))
22 
23 #include <smmintrin.h> /* SSE4 */
24 
25 #if defined(__AVX__)
26 #include <immintrin.h>
27 #endif
28 
29 #else
30 
31 #include <x86intrin.h>
32 
33 #endif
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 #define RTE_VECT_DEFAULT_SIMD_BITWIDTH RTE_VECT_SIMD_256
40 
41 typedef __m128i xmm_t;
42 
43 #define	XMM_SIZE	(sizeof(xmm_t))
44 #define	XMM_MASK	(XMM_SIZE - 1)
45 
46 typedef union rte_xmm {
47 	xmm_t    x;
48 	uint8_t  u8[XMM_SIZE / sizeof(uint8_t)];
49 	uint16_t u16[XMM_SIZE / sizeof(uint16_t)];
50 	uint32_t u32[XMM_SIZE / sizeof(uint32_t)];
51 	uint64_t u64[XMM_SIZE / sizeof(uint64_t)];
52 	double   pd[XMM_SIZE / sizeof(double)];
53 } rte_xmm_t;
54 
55 #ifdef __AVX__
56 
57 typedef __m256i ymm_t;
58 
59 #define	YMM_SIZE	(sizeof(ymm_t))
60 #define	YMM_MASK	(YMM_SIZE - 1)
61 
62 typedef union rte_ymm {
63 	ymm_t    y;
64 	xmm_t    x[YMM_SIZE / sizeof(xmm_t)];
65 	uint8_t  u8[YMM_SIZE / sizeof(uint8_t)];
66 	uint16_t u16[YMM_SIZE / sizeof(uint16_t)];
67 	uint32_t u32[YMM_SIZE / sizeof(uint32_t)];
68 	uint64_t u64[YMM_SIZE / sizeof(uint64_t)];
69 	double   pd[YMM_SIZE / sizeof(double)];
70 } rte_ymm_t;
71 
72 #endif /* __AVX__ */
73 
74 #ifdef RTE_ARCH_I686
75 #define _mm_cvtsi128_si64(a)    \
76 __extension__ ({                \
77 	rte_xmm_t m;            \
78 	m.x = (a);              \
79 	(m.u64[0]);             \
80 })
81 #endif
82 
83 /*
84  * Prior to version 12.1 icc doesn't support _mm_set_epi64x.
85  */
86 #if (defined(__ICC) && __ICC < 1210)
87 #define _mm_set_epi64x(a, b)     \
88 __extension__ ({                 \
89 	rte_xmm_t m;             \
90 	m.u64[0] = b;            \
91 	m.u64[1] = a;            \
92 	(m.x);                   \
93 })
94 #endif /* (defined(__ICC) && __ICC < 1210) */
95 
96 #ifdef __AVX512F__
97 
98 #define RTE_X86_ZMM_SIZE	(sizeof(__m512i))
99 #define RTE_X86_ZMM_MASK	(RTE_X86_ZMM_SIZE - 1)
100 
101 typedef union __rte_x86_zmm {
102 	__m512i	 z;
103 	ymm_t    y[RTE_X86_ZMM_SIZE / sizeof(ymm_t)];
104 	xmm_t    x[RTE_X86_ZMM_SIZE / sizeof(xmm_t)];
105 	uint8_t  u8[RTE_X86_ZMM_SIZE / sizeof(uint8_t)];
106 	uint16_t u16[RTE_X86_ZMM_SIZE / sizeof(uint16_t)];
107 	uint32_t u32[RTE_X86_ZMM_SIZE / sizeof(uint32_t)];
108 	uint64_t u64[RTE_X86_ZMM_SIZE / sizeof(uint64_t)];
109 	double   pd[RTE_X86_ZMM_SIZE / sizeof(double)];
110 } __rte_aligned(RTE_X86_ZMM_SIZE) __rte_x86_zmm_t;
111 
112 #endif /* __AVX512F__ */
113 
114 #ifdef __cplusplus
115 }
116 #endif
117 
118 #endif /* _RTE_VECT_X86_H_ */
119