Line data Source code
1 : /*
2 : * Copyright(c) 2019 Intel Corporation
3 : * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 : */
5 :
6 : #ifndef AOM_DSP_X86_PICKRST_AVX2_H_
7 : #define AOM_DSP_X86_PICKRST_AVX2_H_
8 :
9 : #include <immintrin.h> // AVX2
10 : #include "aom_dsp_rtcd.h"
11 : #include "EbRestoration.h"
12 : #include "transpose_sse2.h"
13 : #include "transpose_avx2.h"
14 :
15 : EB_ALIGN(16)
16 : static const uint8_t mask_8bit[16][16] = {
17 : {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
18 : {0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
19 : {0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
20 : {0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
21 : {0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
22 : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
23 : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
24 : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0},
25 : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0},
26 : {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0},
27 : {0xFF,
28 : 0xFF,
29 : 0xFF,
30 : 0xFF,
31 : 0xFF,
32 : 0xFF,
33 : 0xFF,
34 : 0xFF,
35 : 0xFF,
36 : 0xFF,
37 : 0,
38 : 0,
39 : 0,
40 : 0,
41 : 0,
42 : 0},
43 : {0xFF,
44 : 0xFF,
45 : 0xFF,
46 : 0xFF,
47 : 0xFF,
48 : 0xFF,
49 : 0xFF,
50 : 0xFF,
51 : 0xFF,
52 : 0xFF,
53 : 0xFF,
54 : 0,
55 : 0,
56 : 0,
57 : 0,
58 : 0},
59 : {0xFF,
60 : 0xFF,
61 : 0xFF,
62 : 0xFF,
63 : 0xFF,
64 : 0xFF,
65 : 0xFF,
66 : 0xFF,
67 : 0xFF,
68 : 0xFF,
69 : 0xFF,
70 : 0xFF,
71 : 0,
72 : 0,
73 : 0,
74 : 0},
75 : {0xFF,
76 : 0xFF,
77 : 0xFF,
78 : 0xFF,
79 : 0xFF,
80 : 0xFF,
81 : 0xFF,
82 : 0xFF,
83 : 0xFF,
84 : 0xFF,
85 : 0xFF,
86 : 0xFF,
87 : 0xFF,
88 : 0,
89 : 0,
90 : 0},
91 : {0xFF,
92 : 0xFF,
93 : 0xFF,
94 : 0xFF,
95 : 0xFF,
96 : 0xFF,
97 : 0xFF,
98 : 0xFF,
99 : 0xFF,
100 : 0xFF,
101 : 0xFF,
102 : 0xFF,
103 : 0xFF,
104 : 0xFF,
105 : 0,
106 : 0},
107 : {0xFF,
108 : 0xFF,
109 : 0xFF,
110 : 0xFF,
111 : 0xFF,
112 : 0xFF,
113 : 0xFF,
114 : 0xFF,
115 : 0xFF,
116 : 0xFF,
117 : 0xFF,
118 : 0xFF,
119 : 0xFF,
120 : 0xFF,
121 : 0xFF,
122 : 0}};
123 :
124 : EB_ALIGN(32)
125 : static const uint16_t mask_16bit[16][16] = {
126 : {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
127 : {0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
128 : {0xFFFF, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
129 : {0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
130 : {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
131 : {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
132 : {0xFFFF,
133 : 0xFFFF,
134 : 0xFFFF,
135 : 0xFFFF,
136 : 0xFFFF,
137 : 0xFFFF,
138 : 0,
139 : 0,
140 : 0,
141 : 0,
142 : 0,
143 : 0,
144 : 0,
145 : 0,
146 : 0,
147 : 0},
148 : {0xFFFF,
149 : 0xFFFF,
150 : 0xFFFF,
151 : 0xFFFF,
152 : 0xFFFF,
153 : 0xFFFF,
154 : 0xFFFF,
155 : 0,
156 : 0,
157 : 0,
158 : 0,
159 : 0,
160 : 0,
161 : 0,
162 : 0,
163 : 0},
164 : {0xFFFF,
165 : 0xFFFF,
166 : 0xFFFF,
167 : 0xFFFF,
168 : 0xFFFF,
169 : 0xFFFF,
170 : 0xFFFF,
171 : 0xFFFF,
172 : 0,
173 : 0,
174 : 0,
175 : 0,
176 : 0,
177 : 0,
178 : 0,
179 : 0},
180 : {0xFFFF,
181 : 0xFFFF,
182 : 0xFFFF,
183 : 0xFFFF,
184 : 0xFFFF,
185 : 0xFFFF,
186 : 0xFFFF,
187 : 0xFFFF,
188 : 0xFFFF,
189 : 0,
190 : 0,
191 : 0,
192 : 0,
193 : 0,
194 : 0,
195 : 0},
196 : {0xFFFF,
197 : 0xFFFF,
198 : 0xFFFF,
199 : 0xFFFF,
200 : 0xFFFF,
201 : 0xFFFF,
202 : 0xFFFF,
203 : 0xFFFF,
204 : 0xFFFF,
205 : 0xFFFF,
206 : 0,
207 : 0,
208 : 0,
209 : 0,
210 : 0,
211 : 0},
212 : {0xFFFF,
213 : 0xFFFF,
214 : 0xFFFF,
215 : 0xFFFF,
216 : 0xFFFF,
217 : 0xFFFF,
218 : 0xFFFF,
219 : 0xFFFF,
220 : 0xFFFF,
221 : 0xFFFF,
222 : 0xFFFF,
223 : 0,
224 : 0,
225 : 0,
226 : 0,
227 : 0},
228 : {0xFFFF,
229 : 0xFFFF,
230 : 0xFFFF,
231 : 0xFFFF,
232 : 0xFFFF,
233 : 0xFFFF,
234 : 0xFFFF,
235 : 0xFFFF,
236 : 0xFFFF,
237 : 0xFFFF,
238 : 0xFFFF,
239 : 0xFFFF,
240 : 0,
241 : 0,
242 : 0,
243 : 0},
244 : {0xFFFF,
245 : 0xFFFF,
246 : 0xFFFF,
247 : 0xFFFF,
248 : 0xFFFF,
249 : 0xFFFF,
250 : 0xFFFF,
251 : 0xFFFF,
252 : 0xFFFF,
253 : 0xFFFF,
254 : 0xFFFF,
255 : 0xFFFF,
256 : 0xFFFF,
257 : 0,
258 : 0,
259 : 0},
260 : {0xFFFF,
261 : 0xFFFF,
262 : 0xFFFF,
263 : 0xFFFF,
264 : 0xFFFF,
265 : 0xFFFF,
266 : 0xFFFF,
267 : 0xFFFF,
268 : 0xFFFF,
269 : 0xFFFF,
270 : 0xFFFF,
271 : 0xFFFF,
272 : 0xFFFF,
273 : 0xFFFF,
274 : 0,
275 : 0},
276 : {0xFFFF,
277 : 0xFFFF,
278 : 0xFFFF,
279 : 0xFFFF,
280 : 0xFFFF,
281 : 0xFFFF,
282 : 0xFFFF,
283 : 0xFFFF,
284 : 0xFFFF,
285 : 0xFFFF,
286 : 0xFFFF,
287 : 0xFFFF,
288 : 0xFFFF,
289 : 0xFFFF,
290 : 0xFFFF,
291 : 0}};
292 :
293 0 : static INLINE void add_six_32_to_64_avx2(const __m256i src, __m256i *const sum,
294 : __m128i *const sum128) {
295 0 : const __m256i s0 = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(src, 0));
296 0 : const __m128i s1 = _mm_cvtepi32_epi64(_mm256_extracti128_si256(src, 1));
297 0 : *sum = _mm256_add_epi64(*sum, s0);
298 0 : *sum128 = _mm_add_epi64(*sum128, s1);
299 0 : }
300 :
301 0 : static INLINE __m128i add_hi_lo_64_avx2(const __m256i src) {
302 0 : const __m128i s0 = _mm256_extracti128_si256(src, 0);
303 0 : const __m128i s1 = _mm256_extracti128_si256(src, 1);
304 0 : return _mm_add_epi64(s0, s1);
305 : }
306 :
307 13560 : static INLINE __m128i sub_hi_lo_32_avx2(const __m256i src) {
308 13560 : const __m128i s0 = _mm256_extracti128_si256(src, 0);
309 13560 : const __m128i s1 = _mm256_extracti128_si256(src, 1);
310 13560 : return _mm_sub_epi32(s1, s0);
311 : }
312 :
313 34560 : static INLINE __m256i hadd_32x8_to_64x4_avx2(const __m256i src) {
314 34560 : const __m256i s0 = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(src, 0));
315 69120 : const __m256i s1 = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(src, 1));
316 34560 : return _mm256_add_epi64(s0, s1);
317 : }
318 :
319 0 : static INLINE __m256i hsub_32x8_to_64x4_avx2(const __m256i src) {
320 0 : const __m256i s0 = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(src, 0));
321 0 : const __m256i s1 = _mm256_cvtepi32_epi64(_mm256_extracti128_si256(src, 1));
322 0 : return _mm256_sub_epi64(s1, s0);
323 : }
324 :
325 36589 : static INLINE __m128i hadd_64_avx2(const __m256i src) {
326 36589 : const __m256i t0 = _mm256_srli_si256(src, 8);
327 36589 : const __m256i sum = _mm256_add_epi64(src, t0);
328 36589 : const __m128i sum0 = _mm256_extracti128_si256(sum, 0); // 00+01 10+11
329 36589 : const __m128i sum1 = _mm256_extracti128_si256(sum, 1); // 02+03 12+13
330 36589 : return _mm_add_epi64(sum0, sum1); // 00+01+02+03 10+11+12+13
331 : }
332 :
333 1680 : static INLINE __m128i hadd_two_64_avx2(const __m256i src0, const __m256i src1) {
334 1680 : const __m256i t0 = _mm256_unpacklo_epi64(src0, src1); // 00 10 02 12
335 1680 : const __m256i t1 = _mm256_unpackhi_epi64(src0, src1); // 01 11 03 13
336 1680 : const __m256i sum = _mm256_add_epi64(t0, t1); // 00+01 10+11 02+03 12+13
337 1680 : const __m128i sum0 = _mm256_extracti128_si256(sum, 0); // 00+01 10+11
338 1680 : const __m128i sum1 = _mm256_extracti128_si256(sum, 1); // 02+03 12+13
339 1680 : return _mm_add_epi64(sum0, sum1); // 00+01+02+03 10+11+12+13
340 : }
341 :
342 1680 : static INLINE __m128i hadd_two_32_to_64_avx2(const __m256i src0,
343 : const __m256i src1) {
344 1680 : const __m256i s0 = hadd_32x8_to_64x4_avx2(src0); // 00 01 02 03
345 1680 : const __m256i s1 = hadd_32x8_to_64x4_avx2(src1); // 10 11 12 13
346 1680 : return hadd_two_64_avx2(s0, s1);
347 : }
348 :
349 24540 : static INLINE __m128i hadd_two_32_avx2(const __m256i src0, const __m256i src1) {
350 24540 : const __m256i s01 = _mm256_hadd_epi32(src0, src1); // 0 0 1 1 0 0 1 1
351 24540 : const __m128i sum0 = _mm256_extracti128_si256(s01, 0); // 0 0 1 1
352 24540 : const __m128i sum1 = _mm256_extracti128_si256(s01, 1); // 0 0 1 1
353 24540 : const __m128i sum = _mm_add_epi32(sum0, sum1); // 0 0 1 1
354 24540 : return _mm_hadd_epi32(sum, sum); // 0 1 0 1
355 : }
356 :
357 34980 : static INLINE __m128i hadd_four_32_avx2(const __m256i src0, const __m256i src1,
358 : const __m256i src2,
359 : const __m256i src3) {
360 34980 : const __m256i s01 = _mm256_hadd_epi32(src0, src1); // 0 0 1 1 0 0 1 1
361 34980 : const __m256i s23 = _mm256_hadd_epi32(src2, src3); // 2 2 3 3 2 2 3 3
362 34980 : const __m256i s0123 = _mm256_hadd_epi32(s01, s23); // 0 1 2 3 0 1 2 3
363 34980 : const __m128i sum0 = _mm256_extracti128_si256(s0123, 0); // 0 1 2 3
364 34980 : const __m128i sum1 = _mm256_extracti128_si256(s0123, 1); // 0 1 2 3
365 34980 : return _mm_add_epi32(sum0, sum1); // 0 1 2 3
366 : }
367 :
368 7800 : static INLINE __m256i hadd_four_64_avx2(const __m256i src0, const __m256i src1,
369 : const __m256i src2,
370 : const __m256i src3) {
371 : __m256i s[2], t[4];
372 :
373 : // 00 01 02 03
374 : // 10 11 12 13
375 : // 20 21 22 23
376 : // 30 31 32 33
377 :
378 7800 : t[0] = _mm256_unpacklo_epi64(src0, src1); // 00 10 02 12
379 7800 : t[1] = _mm256_unpackhi_epi64(src0, src1); // 01 11 03 13
380 7800 : t[2] = _mm256_unpacklo_epi64(src2, src3); // 20 30 22 32
381 7800 : t[3] = _mm256_unpackhi_epi64(src2, src3); // 21 31 23 33
382 :
383 7800 : s[0] = _mm256_add_epi64(t[0], t[1]); // 00+01 10+11 02+03 12+13
384 7800 : s[1] = _mm256_add_epi64(t[2], t[3]); // 20+21 30+31 22+23 32+33
385 :
386 : // 00+01 10+11 20+21 30+31
387 7800 : t[0] = _mm256_inserti128_si256(s[0], _mm256_extracti128_si256(s[1], 0), 1);
388 : // 02+03 12+13 22+23 32+33
389 7800 : t[1] = _mm256_inserti128_si256(s[1], _mm256_extracti128_si256(s[0], 1), 0);
390 :
391 : // 00+01+02+03 10+11+12+13 20+21+22+23 30+31+32+33
392 15600 : return _mm256_add_epi64(t[0], t[1]);
393 : }
394 :
395 : // inputs' value range is 31-bit
396 0 : static INLINE __m128i hadd_two_31_to_64_avx2(const __m256i src0,
397 : const __m256i src1) {
398 : __m256i s;
399 0 : s = _mm256_hadd_epi32(src0, src1); // 0 0 1 1 0 0 1 1
400 0 : s = hadd_32x8_to_64x4_avx2(s); // 0 0 1 1
401 0 : s = _mm256_permute4x64_epi64(s, 0xD8); // 0 1 0 1
402 :
403 0 : return add_hi_lo_64_avx2(s);
404 : }
405 :
406 0 : static INLINE __m256i hadd_x_64_avx2(const __m256i src01, const __m256i src23) {
407 : // 0 0 1 1
408 : // 2 2 3 3
409 0 : const __m256i t0 = _mm256_unpacklo_epi64(src01, src23); // 0 2 1 3
410 0 : const __m256i t1 = _mm256_unpackhi_epi64(src01, src23); // 0 2 1 3
411 0 : const __m256i t = _mm256_add_epi64(t0, t1); // 0 2 1 3
412 :
413 0 : return _mm256_permute4x64_epi64(t, 0xD8); // 0 1 2 3
414 : }
415 :
416 : // inputs' value range is 31-bit
417 0 : static INLINE __m256i hadd_four_31_to_64_avx2(const __m256i src0,
418 : const __m256i src1,
419 : const __m256i src2,
420 : const __m256i src3) {
421 : __m256i s[2];
422 0 : s[0] = _mm256_hadd_epi32(src0, src1); // 0 0 1 1 0 0 1 1
423 0 : s[1] = _mm256_hadd_epi32(src2, src3); // 2 2 3 3 2 2 3 3
424 0 : s[0] = hadd_32x8_to_64x4_avx2(s[0]); // 0 0 1 1
425 0 : s[1] = hadd_32x8_to_64x4_avx2(s[1]); // 2 2 3 3
426 :
427 0 : return hadd_x_64_avx2(s[0], s[1]);
428 : }
429 :
430 7800 : static INLINE __m256i hadd_four_32_to_64_avx2(const __m256i src0,
431 : const __m256i src1,
432 : const __m256i src2,
433 : const __m256i src3) {
434 : __m256i s[4];
435 :
436 7800 : s[0] = hadd_32x8_to_64x4_avx2(src0); // 00 01 02 03
437 7800 : s[1] = hadd_32x8_to_64x4_avx2(src1); // 10 11 12 13
438 7800 : s[2] = hadd_32x8_to_64x4_avx2(src2); // 20 21 22 23
439 7800 : s[3] = hadd_32x8_to_64x4_avx2(src3); // 30 31 32 33
440 :
441 7800 : return hadd_four_64_avx2(s[0], s[1], s[2], s[3]);
442 : }
443 :
444 2880 : static INLINE void madd_sse2(const __m128i src, const __m128i dgd,
445 : __m128i *sum) {
446 2880 : const __m128i sd = _mm_madd_epi16(src, dgd);
447 2880 : *sum = _mm_add_epi32(*sum, sd);
448 2880 : }
449 :
450 148966000 : static INLINE void madd_avx2(const __m256i src, const __m256i dgd,
451 : __m256i *sum) {
452 148966000 : const __m256i sd = _mm256_madd_epi16(src, dgd);
453 148966000 : *sum = _mm256_add_epi32(*sum, sd);
454 148966000 : }
455 :
456 2671200 : static INLINE void msub_avx2(const __m256i src, const __m256i dgd,
457 : __m256i *sum) {
458 2671200 : const __m256i sd = _mm256_madd_epi16(src, dgd);
459 2671200 : *sum = _mm256_sub_epi32(*sum, sd);
460 2671200 : }
461 :
462 27660 : static INLINE void update_2_stats_sse2(const int64_t *const src,
463 : const __m128i delta,
464 : int64_t *const dst) {
465 27660 : const __m128i s = _mm_loadu_si128((__m128i *)src);
466 27660 : const __m128i d = _mm_add_epi64(s, delta);
467 : _mm_storeu_si128((__m128i *)dst, d);
468 27660 : }
469 :
470 40620 : static INLINE void update_4_stats_avx2(const int64_t *const src,
471 : const __m128i delta,
472 : int64_t *const dst) {
473 40620 : const __m256i s = _mm256_loadu_si256((__m256i *)src);
474 40620 : const __m256i dlt = _mm256_cvtepi32_epi64(delta);
475 40620 : const __m256i d = _mm256_add_epi64(s, dlt);
476 : _mm256_storeu_si256((__m256i *)dst, d);
477 40620 : }
478 :
479 0 : static INLINE void update_4_stats_highbd_avx2(const int64_t *const src,
480 : const __m256i delta,
481 : int64_t *const dst) {
482 0 : const __m256i s = _mm256_loadu_si256((__m256i *)src);
483 0 : const __m256i d = _mm256_add_epi64(s, delta);
484 : _mm256_storeu_si256((__m256i *)dst, d);
485 0 : }
486 :
487 480 : static INLINE void update_5_stats_avx2(const int64_t *const src,
488 : const __m128i delta,
489 : const int64_t delta4,
490 : int64_t *const dst) {
491 480 : update_4_stats_avx2(src + 0, delta, dst + 0);
492 480 : dst[4] = src[4] + delta4;
493 480 : }
494 :
495 0 : static INLINE void update_5_stats_highbd_avx2(const int64_t *const src,
496 : const __m256i delta,
497 : const int64_t delta4,
498 : int64_t *const dst) {
499 0 : update_4_stats_highbd_avx2(src + 0, delta, dst + 0);
500 0 : dst[4] = src[4] + delta4;
501 0 : }
502 :
503 3780 : static INLINE void update_8_stats_avx2(const int64_t *const src,
504 : const __m256i delta,
505 : int64_t *const dst) {
506 3780 : update_4_stats_avx2(src + 0, _mm256_extracti128_si256(delta, 0), dst + 0);
507 3780 : update_4_stats_avx2(src + 4, _mm256_extracti128_si256(delta, 1), dst + 4);
508 3780 : }
509 :
510 7920 : static INLINE void hadd_update_4_stats_avx2(const int64_t *const src,
511 : const __m256i deltas[4],
512 : int64_t *const dst) {
513 : const __m128i delta =
514 7920 : hadd_four_32_avx2(deltas[0], deltas[1], deltas[2], deltas[3]);
515 7920 : update_4_stats_avx2(src, delta, dst);
516 7920 : }
517 :
518 0 : static INLINE void hadd_update_4_stats_highbd_avx2(const int64_t *const src,
519 : const __m256i deltas[4],
520 : int64_t *const dst) {
521 : const __m256i delta =
522 0 : hadd_four_31_to_64_avx2(deltas[0], deltas[1], deltas[2], deltas[3]);
523 0 : update_4_stats_highbd_avx2(src, delta, dst);
524 0 : }
525 :
526 23940 : static INLINE void hadd_update_6_stats_avx2(const int64_t *const src,
527 : const __m256i deltas[6],
528 : int64_t *const dst) {
529 : const __m128i delta0123 =
530 23940 : hadd_four_32_avx2(deltas[0], deltas[1], deltas[2], deltas[3]);
531 23940 : const __m128i delta45 = hadd_two_32_avx2(deltas[4], deltas[5]);
532 23940 : const __m128i delta45T = _mm_cvtepi32_epi64(delta45);
533 23940 : update_4_stats_avx2(src + 0, delta0123, dst + 0);
534 23940 : update_2_stats_sse2(src + 4, delta45T, dst + 4);
535 23940 : }
536 :
537 0 : static INLINE void hadd_update_6_stats_highbd_avx2(const int64_t *const src,
538 : const __m256i deltas[6],
539 : int64_t *const dst) {
540 : const __m256i delta0123 =
541 0 : hadd_four_31_to_64_avx2(deltas[0], deltas[1], deltas[2], deltas[3]);
542 0 : const __m128i delta45 = hadd_two_31_to_64_avx2(deltas[4], deltas[5]);
543 0 : update_4_stats_highbd_avx2(src + 0, delta0123, dst + 0);
544 0 : update_2_stats_sse2(src + 4, delta45, dst + 4);
545 0 : }
546 :
547 1584720 : static INLINE void load_more_16_avx2(const int16_t *const src,
548 : const int32_t width, const __m256i org,
549 : __m256i *const dst) {
550 1584720 : *dst = _mm256_srli_si256(org, 2);
551 1584720 : *dst = _mm256_insert_epi16(*dst, *(int32_t *)src, 7);
552 1584720 : *dst = _mm256_insert_epi16(*dst, *(int32_t *)(src + width), 15);
553 1584720 : }
554 :
555 0 : static INLINE void load_more_32_avx2(const int16_t *const src,
556 : const int32_t width, __m256i *const dst) {
557 0 : *dst = _mm256_srli_si256(*dst, 4);
558 0 : *dst = _mm256_insert_epi32(*dst, *(int32_t *)src, 3);
559 0 : *dst = _mm256_insert_epi32(*dst, *(int32_t *)(src + width), 7);
560 0 : }
561 :
562 21840 : static INLINE void load_more_64_avx2(const int16_t *const src,
563 : const int32_t width, __m256i *const dst) {
564 21840 : *dst = _mm256_srli_si256(*dst, 8);
565 21840 : *dst = _mm256_insert_epi64(*dst, *(int64_t *)src, 1);
566 21840 : *dst = _mm256_insert_epi64(*dst, *(int64_t *)(src + width), 3);
567 21840 : }
568 :
569 65880 : static INLINE __m256i load_win7_avx2(const int16_t *const d,
570 : const int32_t width) {
571 : // 16-bit idx: 0, 4, 1, 5, 2, 6, 3, 7
572 65880 : const __m256i shf = _mm256_setr_epi8(0,
573 : 1,
574 : 8,
575 : 9,
576 : 2,
577 : 3,
578 : 10,
579 : 11,
580 : 4,
581 : 5,
582 : 12,
583 : 13,
584 : 6,
585 : 7,
586 : 14,
587 : 15,
588 : 0,
589 : 1,
590 : 8,
591 : 9,
592 : 2,
593 : 3,
594 : 10,
595 : 11,
596 : 4,
597 : 5,
598 : 12,
599 : 13,
600 : 6,
601 : 7,
602 : 14,
603 : 15);
604 : // 00s 01s 02s 03s 04s 05s 06s 07s
605 65880 : const __m128i ds = _mm_load_si128((__m128i *)d);
606 : // 00e 01e 02e 03e 04e 05e 06e 07e
607 131760 : const __m128i de = _mm_loadu_si128((__m128i *)(d + width));
608 : const __m256i t0 =
609 65880 : _mm256_inserti128_si256(_mm256_castsi128_si256(ds), de, 1);
610 : // 00s 01s 02s 03s 00e 01e 02e 03e 04s 05s 06s 07s 04e 05e 06e 07e
611 65880 : const __m256i t1 = _mm256_permute4x64_epi64(t0, 0xD8);
612 : // 00s 00e 01s 01e 02s 02e 03s 03e 04s 04e 05s 05e 06s 06e 07s 07e
613 65880 : return _mm256_shuffle_epi8(t1, shf);
614 : }
615 :
616 0 : static INLINE void step3_win3_avx2(const int16_t **const d,
617 : const int32_t d_stride, const int32_t width,
618 : const int32_t h4, __m256i *const dd,
619 : __m256i deltas[WIENER_WIN_3TAP]) {
620 : // 16-bit idx: 0, 2, 4, 6, 1, 3, 5, 7, 0, 2, 4, 6, 1, 3, 5, 7
621 0 : const __m256i shf = _mm256_setr_epi8(0,
622 : 1,
623 : 4,
624 : 5,
625 : 8,
626 : 9,
627 : 12,
628 : 13,
629 : 2,
630 : 3,
631 : 6,
632 : 7,
633 : 10,
634 : 11,
635 : 14,
636 : 15,
637 : 0,
638 : 1,
639 : 4,
640 : 5,
641 : 8,
642 : 9,
643 : 12,
644 : 13,
645 : 2,
646 : 3,
647 : 6,
648 : 7,
649 : 10,
650 : 11,
651 : 14,
652 : 15);
653 :
654 0 : int32_t y = h4;
655 : do {
656 : __m256i ds[WIENER_WIN_3TAP];
657 :
658 : // 00s 01s 10s 11s 20s 21s 30s 31s 00e 01e 10e 11e 20e 21e 30e 31e
659 0 : *dd = _mm256_insert_epi32(*dd, *(int32_t *)(*d + 2 * d_stride), 2);
660 0 : *dd = _mm256_insert_epi32(
661 : *dd, *(int32_t *)(*d + 2 * d_stride + width), 6);
662 0 : *dd = _mm256_insert_epi32(*dd, *(int32_t *)(*d + 3 * d_stride), 3);
663 0 : *dd = _mm256_insert_epi32(
664 : *dd, *(int32_t *)(*d + 3 * d_stride + width), 7);
665 : // 00s 10s 20s 30s 01s 11s 21s 31s 00e 10e 20e 30e 01e 11e 21e 31e
666 0 : ds[0] = _mm256_shuffle_epi8(*dd, shf);
667 :
668 : // 10s 11s 20s 21s 30s 31s 40s 41s 10e 11e 20e 21e 30e 31e 40e 41e
669 0 : load_more_32_avx2(*d + 4 * d_stride, width, dd);
670 : // 10s 20s 30s 40s 11s 21s 31s 41s 10e 20e 30e 40e 11e 21e 31e 41e
671 0 : ds[1] = _mm256_shuffle_epi8(*dd, shf);
672 :
673 : // 20s 21s 30s 31s 40s 41s 50s 51s 20e 21e 30e 31e 40e 41e 50e 51e
674 0 : load_more_32_avx2(*d + 5 * d_stride, width, dd);
675 : // 20s 30s 40s 50s 21s 31s 41s 51s 20e 30e 40e 50e 21e 31e 41e 51e
676 0 : ds[2] = _mm256_shuffle_epi8(*dd, shf);
677 :
678 0 : madd_avx2(ds[0], ds[0], &deltas[0]);
679 0 : madd_avx2(ds[0], ds[1], &deltas[1]);
680 0 : madd_avx2(ds[0], ds[2], &deltas[2]);
681 :
682 0 : *dd = _mm256_srli_si256(*dd, 8);
683 0 : *d += 4 * d_stride;
684 0 : y -= 4;
685 0 : } while (y);
686 0 : }
687 :
688 120 : static INLINE void step3_win5_avx2(const int16_t **const d,
689 : const int32_t d_stride, const int32_t width,
690 : const int32_t height, __m256i *const dd,
691 : __m256i ds[WIENER_WIN_CHROMA],
692 : __m256i deltas[WIENER_WIN_CHROMA]) {
693 : // 16-bit idx: 0, 4, 1, 5, 2, 6, 3, 7
694 120 : const __m256i shf = _mm256_setr_epi8(0,
695 : 1,
696 : 8,
697 : 9,
698 : 2,
699 : 3,
700 : 10,
701 : 11,
702 : 4,
703 : 5,
704 : 12,
705 : 13,
706 : 6,
707 : 7,
708 : 14,
709 : 15,
710 : 0,
711 : 1,
712 : 8,
713 : 9,
714 : 2,
715 : 3,
716 : 10,
717 : 11,
718 : 4,
719 : 5,
720 : 12,
721 : 13,
722 : 6,
723 : 7,
724 : 14,
725 : 15);
726 :
727 120 : int32_t y = height;
728 : do {
729 10800 : *d += 2 * d_stride;
730 :
731 : // 30s 31s 32s 33s 40s 41s 42s 43s 30e 31e 32e 33e 40e 41e 42e 43e
732 10800 : load_more_64_avx2(*d + 2 * d_stride, width, dd);
733 : // 30s 40s 31s 41s 32s 42s 33s 43s 30e 40e 31e 41e 32e 42e 33e 43e
734 10800 : ds[3] = _mm256_shuffle_epi8(*dd, shf);
735 :
736 : // 40s 41s 42s 43s 50s 51s 52s 53s 40e 41e 42e 43e 50e 51e 52e 53e
737 10800 : load_more_64_avx2(*d + 3 * d_stride, width, dd);
738 : // 40s 50s 41s 51s 42s 52s 43s 53s 40e 50e 41e 51e 42e 52e 43e 53e
739 10800 : ds[4] = _mm256_shuffle_epi8(*dd, shf);
740 :
741 10800 : madd_avx2(ds[0], ds[0], &deltas[0]);
742 10800 : madd_avx2(ds[0], ds[1], &deltas[1]);
743 10800 : madd_avx2(ds[0], ds[2], &deltas[2]);
744 10800 : madd_avx2(ds[0], ds[3], &deltas[3]);
745 10800 : madd_avx2(ds[0], ds[4], &deltas[4]);
746 :
747 10800 : ds[0] = ds[2];
748 10800 : ds[1] = ds[3];
749 10800 : ds[2] = ds[4];
750 10800 : y -= 2;
751 10800 : } while (y);
752 120 : }
753 :
754 180 : static INLINE void step3_win7_avx2(const int16_t **const d,
755 : const int32_t d_stride, const int32_t width,
756 : const int32_t height, __m256i ds[WIENER_WIN],
757 : __m256i deltas[WIENER_WIN]) {
758 180 : const __m256i const_n1_0 = _mm256_setr_epi16(0xFFFF,
759 : 0,
760 : 0xFFFF,
761 : 0,
762 : 0xFFFF,
763 : 0,
764 : 0xFFFF,
765 : 0,
766 : 0xFFFF,
767 : 0,
768 : 0xFFFF,
769 : 0,
770 : 0xFFFF,
771 : 0,
772 : 0xFFFF,
773 : 0);
774 :
775 180 : int32_t y = height;
776 : do {
777 : __m256i dd;
778 :
779 64800 : dd = ds[0];
780 64800 : dd = _mm256_xor_si256(dd, const_n1_0);
781 64800 : dd = _mm256_sub_epi16(dd, const_n1_0);
782 :
783 : // 60s 60e 61s 61e 62s 62e 63s 63e 64s 64e 65s 65e 66s 66e 67s 67e
784 64800 : ds[6] = load_win7_avx2(*d, width);
785 :
786 64800 : madd_avx2(dd, ds[0], &deltas[0]);
787 64800 : madd_avx2(dd, ds[1], &deltas[1]);
788 64800 : madd_avx2(dd, ds[2], &deltas[2]);
789 64800 : madd_avx2(dd, ds[3], &deltas[3]);
790 64800 : madd_avx2(dd, ds[4], &deltas[4]);
791 64800 : madd_avx2(dd, ds[5], &deltas[5]);
792 64800 : madd_avx2(dd, ds[6], &deltas[6]);
793 :
794 64800 : ds[0] = ds[1];
795 64800 : ds[1] = ds[2];
796 64800 : ds[2] = ds[3];
797 64800 : ds[3] = ds[4];
798 64800 : ds[4] = ds[5];
799 64800 : ds[5] = ds[6];
800 64800 : *d += d_stride;
801 64800 : } while (--y);
802 180 : }
803 :
804 : #endif // AOM_DSP_X86_PICKRST_AVX2_H_
|