comparison src/impl/x86/avx512f.c @ 31:bf6ad516f1e6

Backed out changeset c6c99ab1088a
author Paper <paper@tflc.us>
date Fri, 25 Apr 2025 17:40:33 -0400
parents c6c99ab1088a
children 99e4539f922f
comparison
equal deleted inserted replaced
30:641d8c79b1da 31:bf6ad516f1e6
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE. 22 * SOFTWARE.
23 **/ 23 **/
24 24
25 #include "vec/impl/x86/avx512f.h" 25 #include "vec/impl/x86/avx512f.h"
26 #include "vec/impl/generic.h"
26 27
27 #include <immintrin.h> 28 #include <immintrin.h>
28 29
29 /* ------------------------------------------------------------------------ */ 30 // this is a stupid amount of work just to do these operations, is it really worth it ?
30 31 // also same note in avx2.c applies here, these do not handle sign bits properly, which
31 #define VEC_AVX512F_MINMAX_TEMPLATE(SIGN, BITS, SIZE, INTLSIGN, OP) \ 32 // isn't that big of a deal for regular arithmetic operations, but matters quite a bit
32 VEC_FUNC_IMPL v##SIGN##int##BITS##x##SIZE v##SIGN##int##BITS##x##SIZE##_avx512f_##OP(v##SIGN##int##BITS##x##SIZE vec1, v##SIGN##int##BITS##x##SIZE vec2) \ 33 // when doing things like arithmetic shifts.
33 { \ 34 #define VEC_AVX512F_OPERATION_8x64(op, sign) \
34 union v##SIGN##int##BITS##x##SIZE##_impl_data *vec1d = (union v##SIGN##int##BITS##x##SIZE##_impl_data *)&vec1; \ 35 do { \
35 union v##SIGN##int##BITS##x##SIZE##_impl_data *vec2d = (union v##SIGN##int##BITS##x##SIZE##_impl_data *)&vec2; \ 36 union v##sign##int8x64_impl_data *vec1d = (union v##sign##int8x64_impl_data *)&vec1; \
36 \ 37 union v##sign##int8x64_impl_data *vec2d = (union v##sign##int8x64_impl_data *)&vec2; \
37 vec1d->avx512f = _mm512_##OP##_ep##INTLSIGN##BITS(vec1d->avx512f, vec2d->avx512f); \ 38 \
38 \ 39 /* unpack and operate */ \
39 return vec1d->vec; \ 40 __m512i dst_1 = _mm512_##op##_epi32(_mm512_srli_epi32(_mm512_slli_epi32(vec1d->avx512f, 24), 24), _mm512_srli_epi32(_mm512_slli_epi32(vec2d->avx512f, 24), 24)); \
40 } 41 __m512i dst_2 = _mm512_##op##_epi32(_mm512_srli_epi32(_mm512_slli_epi32(vec1d->avx512f, 16), 24), _mm512_srli_epi32(_mm512_slli_epi32(vec2d->avx512f, 16), 24)); \
41 42 __m512i dst_3 = _mm512_##op##_epi32(_mm512_srli_epi32(_mm512_slli_epi32(vec1d->avx512f, 8), 24), _mm512_srli_epi32(_mm512_slli_epi32(vec2d->avx512f, 8), 24)); \
42 #define VEC_AVX512F_MINMAX_32x16(OP) VEC_AVX512F_MINMAX_TEMPLATE( , 32, 16, i, OP) 43 __m512i dst_4 = _mm512_##op##_epi32(_mm512_srli_epi32(vec1d->avx512f, 24), _mm512_srli_epi32(vec2d->avx512f, 24)); \
43 #define VEC_AVX512F_MINMAX_u32x16(OP) VEC_AVX512F_MINMAX_TEMPLATE(u, 32, 16, u, OP) 44 \
44 #define VEC_AVX512F_MINMAX_64x8(OP) VEC_AVX512F_MINMAX_TEMPLATE( , 64, 8, i, OP) 45 /* repack */ \
45 #define VEC_AVX512F_MINMAX_u64x8(OP) VEC_AVX512F_MINMAX_TEMPLATE(u, 64, 8, u, OP) 46 vec1d->avx512f = _mm512_or_si512( \
46 47 _mm512_or_si512( \
47 #define VEC_AVX512F_STRUCT_MINMAX_32x16(OP, SIGN) v##SIGN##int32x16_avx512f_##OP 48 _mm512_srli_epi32(_mm512_slli_epi32(dst_1, 24), 24), \
48 #define VEC_AVX512F_STRUCT_MINMAX_64x8(OP, SIGN) v##SIGN##int64x8_avx512f_##OP 49 _mm512_srli_epi32(_mm512_slli_epi32(dst_2, 24), 16) \
49 50 ), \
50 /* ------------------------------------------------------------------------ */ 51 _mm512_or_si512( \
51 52 _mm512_srli_epi32(_mm512_slli_epi32(dst_3, 24), 8), \
52 #define VEC_AVX512F_OPERATION_EX(name, op, sign, bits, size, secondsign) \ 53 _mm512_slli_epi32(dst_4, 24) \
53 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_##name(v##sign##int##bits##x##size vec1, v##secondsign##int##bits##x##size vec2) \ 54 ) \
54 { \ 55 ); \
55 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ 56 \
56 union v##secondsign##int##bits##x##size##_impl_data *vec2d = (union v##secondsign##int##bits##x##size##_impl_data *)&vec2; \ 57 return vec1d->vec; \
57 \ 58 } while (0)
58 vec1d->avx512f = _mm512_##op##_epi##bits(vec1d->avx512f, vec2d->avx512f); \ 59
59 \ 60 #define VEC_AVX512F_OPERATION_16x32(op, sign) \
60 return vec1d->vec; \ 61 do { \
61 } 62 union v##sign##int16x32_impl_data *vec1d = (union v##sign##int16x32_impl_data *)&vec1; \
62 63 union v##sign##int16x32_impl_data *vec2d = (union v##sign##int16x32_impl_data *)&vec2; \
63 #define VEC_AVX512F_OPERATION(name, op, sign, bits, size) \ 64 \
64 VEC_AVX512F_OPERATION_EX(name, op, sign, bits, size, sign) 65 /* unpack and operate; it would be nice if we had an _m512_andi_epi32... */ \
65 66 __m512i dst_1 = _mm512_##op##_epi32(_mm512_srli_epi32(_mm512_slli_epi32(vec1d->avx512f, 16), 16), _mm512_srli_epi32(_mm512_slli_epi32(vec2d->avx512f, 16), 16)); \
66 #define VEC_AVX512F_OPERATION_SHIFT(name, op, sign, bits, size) \ 67 __m512i dst_2 = _mm512_##op##_epi32(_mm512_srli_epi32(vec1d->avx512f, 16), _mm512_srli_epi32(vec2d->avx512f, 16)); \
67 VEC_AVX512F_OPERATION_EX(name, op, sign, bits, size, u) 68 \
68 69 /* repack */ \
69 #define VEC_AVX512F_ADD_32x16(sign) VEC_AVX512F_OPERATION(add, add, sign, 32, 16) 70 vec1d->avx512f = _mm512_or_si512( \
70 #define VEC_AVX512F_ADD_64x8(sign) VEC_AVX512F_OPERATION(add, add, sign, 64, 8) 71 _mm512_srli_epi32(_mm512_slli_epi32(dst_1, 16), 16), \
71 72 _mm512_slli_epi32(dst_2, 16) \
72 #define VEC_AVX512F_SUB_32x16(sign) VEC_AVX512F_OPERATION(sub, sub, sign, 32, 16) 73 ); \
73 #define VEC_AVX512F_SUB_64x8(sign) VEC_AVX512F_OPERATION(sub, sub, sign, 64, 8) 74 return vec1d->vec; \
74 75 } while (0)
75 #define VEC_AVX512F_MUL_32x16(sign) VEC_AVX512F_OPERATION(mul, mullo, sign, 32, 16) 76
76 #define VEC_AVX512F_MUL_64x8(sign) VEC_AVX512F_OPERATION(mul, mullox, sign, 64, 8) 77 #define VEC_AVX512F_ADD_8x64(sign) \
77 78 VEC_AVX512F_OPERATION_8x64(add, sign)
78 #define VEC_AVX512F_LSHIFT_32x16(sign) VEC_AVX512F_OPERATION_SHIFT(lshift, sllv, sign, 32, 16) 79
79 #define VEC_AVX512F_LSHIFT_64x8(sign) VEC_AVX512F_OPERATION_SHIFT(lshift, sllv, sign, 64, 8) 80 #define VEC_AVX512F_ADD_16x32(sign) \
80 81 VEC_AVX512F_OPERATION_16x32(add, sign)
81 #define VEC_AVX512F_XRSHIFT(name, bits, size, sign, aORl) \ 82
82 VEC_AVX512F_OPERATION_SHIFT(name, sr##aORl##v, sign, bits, size) 83 #define VEC_AVX512F_ADD_32x16(sign) \
83 84 do { \
84 /* always the same, regardless of signedness */ 85 union v##sign##int32x16_impl_data *vec1d = (union v##sign##int32x16_impl_data *)&vec1; \
85 #define VEC_AVX512F_LRSHIFT_32x16(sign) VEC_AVX512F_XRSHIFT(lrshift, 32, 16, sign, l) 86 union v##sign##int32x16_impl_data *vec2d = (union v##sign##int32x16_impl_data *)&vec2; \
86 #define VEC_AVX512F_LRSHIFT_64x8(sign) VEC_AVX512F_XRSHIFT(lrshift, 64, 8, sign, l) 87 \
87 88 vec1d->avx512f = _mm512_add_epi32(vec1d->avx512f, vec2d->avx512f); \
88 #define VEC_AVX512F_RSHIFT_32x16(sign) VEC_AVX512F_XRSHIFT(rshift, 32, 16, sign, a) 89 return vec1d->vec; \
89 #define VEC_AVX512F_RSHIFT_64x8(sign) VEC_AVX512F_XRSHIFT(rshift, 64, 8, sign, a) 90 } while (0)
90 91
91 #define VEC_AVX512F_uRSHIFT_32x16(sign) VEC_AVX512F_XRSHIFT(rshift, 32, 16, sign, l) 92 #define VEC_AVX512F_ADD_64x8(sign) \
92 #define VEC_AVX512F_uRSHIFT_64x8(sign) VEC_AVX512F_XRSHIFT(rshift, 64, 8, sign, l) 93 do { \
93 94 union v##sign##int64x8_impl_data *vec1d = (union v##sign##int64x8_impl_data *)&vec1; \
94 /* ok */ 95 union v##sign##int64x8_impl_data *vec2d = (union v##sign##int64x8_impl_data *)&vec2; \
95 #define VEC_AVX512F_STRUCT_OPERATION_32x16(OP, SIGN) v##SIGN##int32x16_avx512f_##OP 96 \
96 #define VEC_AVX512F_STRUCT_OPERATION_64x8(OP, SIGN) v##SIGN##int64x8_avx512f_##OP 97 vec1d->avx512f = _mm512_add_epi64(vec1d->avx512f, vec2d->avx512f); \
97 98 return vec1d->vec; \
98 /* ------------------------------------------------------------------------ */ 99 } while (0)
100
101 #define VEC_AVX512F_SUB_8x64(sign) \
102 VEC_AVX512F_OPERATION_8x64(sub, sign)
103
104 #define VEC_AVX512F_SUB_16x32(sign) \
105 VEC_AVX512F_OPERATION_16x32(sub, sign)
106
107 #define VEC_AVX512F_SUB_32x16(sign) \
108 do { \
109 union v##sign##int32x16_impl_data *vec1d = (union v##sign##int32x16_impl_data *)&vec1; \
110 union v##sign##int32x16_impl_data *vec2d = (union v##sign##int32x16_impl_data *)&vec2; \
111 \
112 vec1d->avx512f = _mm512_sub_epi32(vec1d->avx512f, vec2d->avx512f); \
113 return vec1d->vec; \
114 } while (0)
115
116 #define VEC_AVX512F_SUB_64x8(sign) \
117 do { \
118 union v##sign##int64x8_impl_data *vec1d = (union v##sign##int64x8_impl_data *)&vec1; \
119 union v##sign##int64x8_impl_data *vec2d = (union v##sign##int64x8_impl_data *)&vec2; \
120 \
121 vec1d->avx512f = _mm512_sub_epi64(vec1d->avx512f, vec2d->avx512f); \
122 return vec1d->vec; \
123 } while (0)
124
125 #define VEC_AVX512F_MUL_8x64(sign) \
126 VEC_AVX512F_OPERATION_8x64(mullo, sign)
127
128 #define VEC_AVX512F_MUL_16x32(sign) \
129 VEC_AVX512F_OPERATION_16x32(mullo, sign)
130
131 #define VEC_AVX512F_MUL_32x16(sign) \
132 do { \
133 union v##sign##int32x16_impl_data *vec1d = (union v##sign##int32x16_impl_data *)&vec1; \
134 union v##sign##int32x16_impl_data *vec2d = (union v##sign##int32x16_impl_data *)&vec2; \
135 \
136 vec1d->avx512f = _mm512_mullo_epi32(vec1d->avx512f, vec2d->avx512f); \
137 return vec1d->vec; \
138 } while (0)
139
140 #define VEC_AVX512F_MUL_64x8(sign) \
141 do { \
142 union v##sign##int64x8_impl_data *vec1d = (union v##sign##int64x8_impl_data *)&vec1; \
143 union v##sign##int64x8_impl_data *vec2d = (union v##sign##int64x8_impl_data *)&vec2; \
144 \
145 __m512i ac = _mm512_mul_epu32(vec1d->avx512f, vec2d->avx512f); \
146 __m512i b = _mm512_srli_epi64(vec1d->avx512f, 32); \
147 __m512i bc = _mm512_mul_epu32(b, vec2d->avx512f); \
148 __m512i d = _mm512_srli_epi64(vec2d->avx512f, 32); \
149 __m512i ad = _mm512_mul_epu32(vec1d->avx512f, d); \
150 __m512i hi = _mm512_add_epi64(bc, ad); \
151 hi = _mm512_slli_epi64(hi, 32); \
152 \
153 vec1d->avx512f = _mm512_add_epi64(hi, ac); \
154 return vec1d->vec; \
155 } while (0)
156
157 #define VEC_AVX512F_LSHIFT_8x64(sign) \
158 VEC_AVX512F_OPERATION_8x64(sllv, sign)
159
160 #define VEC_AVX512F_LSHIFT_16x32(sign) \
161 VEC_AVX512F_OPERATION_16x32(sllv, sign)
162
163 #define VEC_AVX512F_LSHIFT_32x16(sign) \
164 do { \
165 union v##sign##int32x16_impl_data *vec1d = (union v##sign##int32x16_impl_data *)&vec1; \
166 union v##sign##int32x16_impl_data *vec2d = (union v##sign##int32x16_impl_data *)&vec2; \
167 \
168 vec1d->avx512f = _mm512_sllv_epi32(vec1d->avx512f, vec2d->avx512f); \
169 return vec1d->vec; \
170 } while (0)
171
172 #define VEC_AVX512F_LSHIFT_64x8(sign) \
173 do { \
174 union v##sign##int64x8_impl_data *vec1d = (union v##sign##int64x8_impl_data *)&vec1; \
175 union v##sign##int64x8_impl_data *vec2d = (union v##sign##int64x8_impl_data *)&vec2; \
176 \
177 vec1d->avx512f = _mm512_sllv_epi64(vec1d->avx512f, vec2d->avx512f); \
178 return vec1d->vec; \
179 } while (0)
180
181 #define VEC_AVX512F_lRSHIFT_8x64(sign) \
182 VEC_AVX512F_OPERATION_8x64(srlv, sign)
183
184 #define VEC_AVX512F_lRSHIFT_16x32(sign) \
185 VEC_AVX512F_OPERATION_16x32(srlv, sign)
186
187 #define VEC_AVX512F_aRSHIFT_8x64(sign) \
188 do { \
189 return v##sign##int8x64_generic_rshift(vec1, vec2); \
190 } while (0)
191
192 #define VEC_AVX512F_aRSHIFT_16x32(sign) \
193 do { \
194 return v##sign##int16x32_generic_rshift(vec1, vec2); \
195 } while (0)
196
197 #define VEC_AVX512F_RSHIFT_8x64(sign, aORl) VEC_AVX512F_##aORl##RSHIFT_8x64(sign)
198 #define VEC_AVX512F_RSHIFT_16x32(sign, aORl) VEC_AVX512F_##aORl##RSHIFT_16x32(sign)
199
200 #define VEC_AVX512F_RSHIFT_32x16(sign, aORl) \
201 do { \
202 union v##sign##int32x16_impl_data *vec1d = (union v##sign##int32x16_impl_data *)&vec1; \
203 union v##sign##int32x16_impl_data *vec2d = (union v##sign##int32x16_impl_data *)&vec2; \
204 \
205 vec1d->avx512f = _mm512_sr##aORl##v_epi32(vec1d->avx512f, vec2d->avx512f); \
206 return vec1d->vec; \
207 } while (0)
208
209 #define VEC_AVX512F_RSHIFT_64x8(sign, aORl) \
210 do { \
211 union v##sign##int64x8_impl_data *vec1d = (union v##sign##int64x8_impl_data *)&vec1; \
212 union v##sign##int64x8_impl_data *vec2d = (union v##sign##int64x8_impl_data *)&vec2; \
213 \
214 vec1d->avx512f = _mm512_sr##aORl##v_epi64(vec1d->avx512f, vec2d->avx512f); \
215 return vec1d->vec; \
216 } while (0)
217
218 #define VEC_AVX512F_uRSHIFT_8x64(sign, aORl) VEC_AVX512F_RSHIFT_8x64(sign, l)
219 #define VEC_AVX512F_uRSHIFT_16x32(sign, aORl) VEC_AVX512F_RSHIFT_16x32(sign, l)
220 #define VEC_AVX512F_uRSHIFT_32x16(sign, aORl) VEC_AVX512F_RSHIFT_32x16(sign, l)
221 #define VEC_AVX512F_uRSHIFT_64x8(sign, aORl) VEC_AVX512F_RSHIFT_64x8(sign, l)
99 222
100 #define VEC_AVX512F_DEFINE_OPERATIONS_SIGN(sign, bits, size) \ 223 #define VEC_AVX512F_DEFINE_OPERATIONS_SIGN(sign, bits, size) \
101 union v##sign##int##bits##x##size##_impl_data { \ 224 union v##sign##int##bits##x##size##_impl_data { \
102 v##sign##int##bits##x##size vec; \ 225 v##sign##int##bits##x##size vec; \
103 __m512i avx512f; \ 226 __m512i avx512f; \
104 }; \ 227 }; \
105 \ 228 \
106 VEC_STATIC_ASSERT(VEC_ALIGNOF(__m512i) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \ 229 VEC_STATIC_ASSERT(VEC_ALIGNOF(__m512i) <= VEC_ALIGNOF(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " alignment needs to be expanded to fit intrinsic type size"); \
107 VEC_STATIC_ASSERT(sizeof(__m512i) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \ 230 VEC_STATIC_ASSERT(sizeof(__m512i) <= sizeof(v##sign##int##bits##x##size), "vec: v" #sign "int" #bits "x" #size " needs to be expanded to fit intrinsic type size"); \
108 \ 231 \
109 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_load_aligned(const vec_##sign##int##bits in[size]) \ 232 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_load_aligned(const vec_##sign##int##bits in[size]) \
110 { \ 233 { \
111 union v##sign##int##bits##x##size##_impl_data vec; \ 234 union v##sign##int##bits##x##size##_impl_data vec; \
112 vec.avx512f = _mm512_load_si512((const __m512i *)in); \ 235 vec.avx512f = _mm512_load_si512((const __m512i *)in); \
113 return vec.vec; \ 236 return vec.vec; \
114 } \ 237 } \
115 \ 238 \
116 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_load(const vec_##sign##int##bits in[size]) \ 239 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_load(const vec_##sign##int##bits in[size]) \
117 { \ 240 { \
118 union v##sign##int##bits##x##size##_impl_data vec; \ 241 union v##sign##int##bits##x##size##_impl_data vec; \
119 vec.avx512f = _mm512_loadu_si512((const __m512i *)in); \ 242 vec.avx512f = _mm512_loadu_si512((const __m512i *)in); \
120 return vec.vec; \ 243 return vec.vec; \
121 } \ 244 } \
122 \ 245 \
123 VEC_FUNC_IMPL void v##sign##int##bits##x##size##_avx512f_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ 246 static void v##sign##int##bits##x##size##_avx512f_store_aligned(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \
124 { \ 247 { \
125 _mm512_store_si512((__m512i *)out, ((union v##sign##int##bits##x##size##_impl_data *)&vec)->avx512f); \ 248 _mm512_store_si512((__m512i *)out, ((union v##sign##int##bits##x##size##_impl_data *)&vec)->avx512f); \
126 } \ 249 } \
127 \ 250 \
128 VEC_FUNC_IMPL void v##sign##int##bits##x##size##_avx512f_store(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \ 251 static void v##sign##int##bits##x##size##_avx512f_store(v##sign##int##bits##x##size vec, vec_##sign##int##bits out[size]) \
129 { \ 252 { \
130 _mm512_storeu_si512((__m512i *)out, ((union v##sign##int##bits##x##size##_impl_data *)&vec)->avx512f); \ 253 _mm512_storeu_si512((__m512i *)out, ((union v##sign##int##bits##x##size##_impl_data *)&vec)->avx512f); \
131 } \ 254 } \
132 \ 255 \
133 VEC_AVX512F_ADD_##bits##x##size(sign) \ 256 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_add(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
134 VEC_AVX512F_SUB_##bits##x##size(sign) \ 257 { \
135 VEC_AVX512F_MUL_##bits##x##size(sign) \ 258 VEC_AVX512F_ADD_##bits##x##size(sign); \
136 \ 259 } \
137 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ 260 \
261 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_sub(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
262 { \
263 VEC_AVX512F_SUB_##bits##x##size(sign); \
264 } \
265 \
266 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_mul(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
267 { \
268 VEC_AVX512F_MUL_##bits##x##size(sign); \
269 } \
270 \
271 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_and(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
138 { \ 272 { \
139 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ 273 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \
140 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ 274 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \
141 \ 275 \
142 vec1d->avx512f = _mm512_and_si512(vec1d->avx512f, vec2d->avx512f); \ 276 vec1d->avx512f = _mm512_and_si512(vec1d->avx512f, vec2d->avx512f); \
143 return vec1d->vec; \ 277 return vec1d->vec; \
144 } \ 278 } \
145 \ 279 \
146 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ 280 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_or(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
147 { \ 281 { \
148 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ 282 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \
149 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ 283 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \
150 \ 284 \
151 vec1d->avx512f = _mm512_or_si512(vec1d->avx512f, vec2d->avx512f); \ 285 vec1d->avx512f = _mm512_or_si512(vec1d->avx512f, vec2d->avx512f); \
152 return vec1d->vec; \ 286 return vec1d->vec; \
153 } \ 287 } \
154 \ 288 \
155 VEC_FUNC_IMPL v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \ 289 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_xor(v##sign##int##bits##x##size vec1, v##sign##int##bits##x##size vec2) \
156 { \ 290 { \
157 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \ 291 union v##sign##int##bits##x##size##_impl_data *vec1d = (union v##sign##int##bits##x##size##_impl_data *)&vec1; \
158 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \ 292 union v##sign##int##bits##x##size##_impl_data *vec2d = (union v##sign##int##bits##x##size##_impl_data *)&vec2; \
159 \ 293 \
160 vec1d->avx512f = _mm512_xor_si512(vec1d->avx512f, vec2d->avx512f); \ 294 vec1d->avx512f = _mm512_xor_si512(vec1d->avx512f, vec2d->avx512f); \
161 return vec1d->vec; \ 295 return vec1d->vec; \
162 } \ 296 } \
163 \ 297 \
164 VEC_AVX512F_LSHIFT_##bits##x##size(sign); \ 298 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_lshift(v##sign##int##bits##x##size vec1, vuint##bits##x##size vec2) \
165 VEC_AVX512F_##sign##RSHIFT_##bits##x##size(sign); \ 299 { \
166 VEC_AVX512F_LRSHIFT_##bits##x##size(sign); \ 300 VEC_AVX512F_LSHIFT_##bits##x##size(sign); \
167 \ 301 } \
168 VEC_AVX512F_MINMAX_##sign##bits##x##size(min) \ 302 \
169 VEC_AVX512F_MINMAX_##sign##bits##x##size(max) \ 303 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_rshift(v##sign##int##bits##x##size vec1, vuint##bits##x##size vec2) \
304 { \
305 VEC_AVX512F_##sign##RSHIFT_##bits##x##size(sign, a); \
306 } \
307 \
308 static v##sign##int##bits##x##size v##sign##int##bits##x##size##_avx512f_lrshift(v##sign##int##bits##x##size vec1, vuint##bits##x##size vec2) \
309 { \
310 VEC_AVX512F_RSHIFT_##bits##x##size(sign, l); \
311 } \
170 \ 312 \
171 const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_avx512f = { \ 313 const v##sign##int##bits##x##size##_impl v##sign##int##bits##x##size##_impl_avx512f = { \
172 .load_aligned = v##sign##int##bits##x##size##_avx512f_load_aligned, \ 314 v##sign##int##bits##x##size##_generic_splat, \
173 .load = v##sign##int##bits##x##size##_avx512f_load, \ 315 v##sign##int##bits##x##size##_avx512f_load_aligned, \
174 .store_aligned = v##sign##int##bits##x##size##_avx512f_store_aligned, \ 316 v##sign##int##bits##x##size##_avx512f_load, \
175 .store = v##sign##int##bits##x##size##_avx512f_store, \ 317 v##sign##int##bits##x##size##_avx512f_store_aligned, \
176 .add = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(add, sign), \ 318 v##sign##int##bits##x##size##_avx512f_store, \
177 .sub = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(sub, sign), \ 319 v##sign##int##bits##x##size##_avx512f_add, \
178 .mul = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(mul, sign), \ 320 v##sign##int##bits##x##size##_avx512f_sub, \
179 .band = v##sign##int##bits##x##size##_avx512f_and, \ 321 v##sign##int##bits##x##size##_avx512f_mul, \
180 .bor = v##sign##int##bits##x##size##_avx512f_or, \ 322 v##sign##int##bits##x##size##_generic_div, \
181 .bxor = v##sign##int##bits##x##size##_avx512f_xor, \ 323 v##sign##int##bits##x##size##_generic_avg, \
182 .lshift = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(lshift, sign), \ 324 v##sign##int##bits##x##size##_avx512f_and, \
183 .rshift = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(rshift, sign), \ 325 v##sign##int##bits##x##size##_avx512f_or, \
184 .lrshift = VEC_AVX512F_STRUCT_OPERATION_##bits##x##size(lrshift, sign), \ 326 v##sign##int##bits##x##size##_avx512f_xor, \
185 .min = VEC_AVX512F_STRUCT_MINMAX_##bits##x##size(min, sign), \ 327 v##sign##int##bits##x##size##_generic_not, \
186 .max = VEC_AVX512F_STRUCT_MINMAX_##bits##x##size(max, sign), \ 328 v##sign##int##bits##x##size##_avx512f_lshift, \
329 v##sign##int##bits##x##size##_avx512f_rshift, \
330 v##sign##int##bits##x##size##_avx512f_lrshift, \
331 v##sign##int##bits##x##size##_generic_cmplt, \
332 v##sign##int##bits##x##size##_generic_cmple, \
333 v##sign##int##bits##x##size##_generic_cmpeq, \
334 v##sign##int##bits##x##size##_generic_cmpge, \
335 v##sign##int##bits##x##size##_generic_cmpgt, \
187 }; 336 };
188 337
189 #define VEC_AVX512F_DEFINE_OPERATIONS(bits, size) \ 338 #define VEC_AVX512F_DEFINE_OPERATIONS(bits, size) \
190 VEC_AVX512F_DEFINE_OPERATIONS_SIGN(u, bits, size) \ 339 VEC_AVX512F_DEFINE_OPERATIONS_SIGN(u, bits, size) \
191 VEC_AVX512F_DEFINE_OPERATIONS_SIGN( , bits, size) 340 VEC_AVX512F_DEFINE_OPERATIONS_SIGN( , bits, size)
192 341
342 VEC_AVX512F_DEFINE_OPERATIONS(8, 64)
343 VEC_AVX512F_DEFINE_OPERATIONS(16, 32)
193 VEC_AVX512F_DEFINE_OPERATIONS(32, 16) 344 VEC_AVX512F_DEFINE_OPERATIONS(32, 16)
194 VEC_AVX512F_DEFINE_OPERATIONS(64, 8) 345 VEC_AVX512F_DEFINE_OPERATIONS(64, 8)