xref: /aosp_15_r20/external/libaom/av1/common/x86/reconinter_avx2.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2018, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #include <immintrin.h>
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #include "config/av1_rtcd.h"
15*77c1e3ccSAndroid Build Coastguard Worker 
16*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_integer.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/blend.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/x86/synonyms.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/x86/synonyms_avx2.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/blockd.h"
21*77c1e3ccSAndroid Build Coastguard Worker 
calc_mask_avx2(const __m256i mask_base,const __m256i s0,const __m256i s1)22*77c1e3ccSAndroid Build Coastguard Worker static inline __m256i calc_mask_avx2(const __m256i mask_base, const __m256i s0,
23*77c1e3ccSAndroid Build Coastguard Worker                                      const __m256i s1) {
24*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff = _mm256_abs_epi16(_mm256_sub_epi16(s0, s1));
25*77c1e3ccSAndroid Build Coastguard Worker   return _mm256_abs_epi16(
26*77c1e3ccSAndroid Build Coastguard Worker       _mm256_add_epi16(mask_base, _mm256_srli_epi16(diff, 4)));
27*77c1e3ccSAndroid Build Coastguard Worker   // clamp(diff, 0, 64) can be skiped for diff is always in the range ( 38, 54)
28*77c1e3ccSAndroid Build Coastguard Worker }
av1_build_compound_diffwtd_mask_avx2(uint8_t * mask,DIFFWTD_MASK_TYPE mask_type,const uint8_t * src0,int src0_stride,const uint8_t * src1,int src1_stride,int h,int w)29*77c1e3ccSAndroid Build Coastguard Worker void av1_build_compound_diffwtd_mask_avx2(uint8_t *mask,
30*77c1e3ccSAndroid Build Coastguard Worker                                           DIFFWTD_MASK_TYPE mask_type,
31*77c1e3ccSAndroid Build Coastguard Worker                                           const uint8_t *src0, int src0_stride,
32*77c1e3ccSAndroid Build Coastguard Worker                                           const uint8_t *src1, int src1_stride,
33*77c1e3ccSAndroid Build Coastguard Worker                                           int h, int w) {
34*77c1e3ccSAndroid Build Coastguard Worker   const int mb = (mask_type == DIFFWTD_38_INV) ? AOM_BLEND_A64_MAX_ALPHA : 0;
35*77c1e3ccSAndroid Build Coastguard Worker   const __m256i y_mask_base = _mm256_set1_epi16(38 - mb);
36*77c1e3ccSAndroid Build Coastguard Worker   int i = 0;
37*77c1e3ccSAndroid Build Coastguard Worker   if (4 == w) {
38*77c1e3ccSAndroid Build Coastguard Worker     do {
39*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0A = xx_loadl_32(src0);
40*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0B = xx_loadl_32(src0 + src0_stride);
41*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0C = xx_loadl_32(src0 + src0_stride * 2);
42*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0D = xx_loadl_32(src0 + src0_stride * 3);
43*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0AB = _mm_unpacklo_epi32(s0A, s0B);
44*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0CD = _mm_unpacklo_epi32(s0C, s0D);
45*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0ABCD = _mm_unpacklo_epi64(s0AB, s0CD);
46*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0ABCD_w = _mm256_cvtepu8_epi16(s0ABCD);
47*77c1e3ccSAndroid Build Coastguard Worker 
48*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1A = xx_loadl_32(src1);
49*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1B = xx_loadl_32(src1 + src1_stride);
50*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1C = xx_loadl_32(src1 + src1_stride * 2);
51*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1D = xx_loadl_32(src1 + src1_stride * 3);
52*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1AB = _mm_unpacklo_epi32(s1A, s1B);
53*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1CD = _mm_unpacklo_epi32(s1C, s1D);
54*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1ABCD = _mm_unpacklo_epi64(s1AB, s1CD);
55*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1ABCD_w = _mm256_cvtepu8_epi16(s1ABCD);
56*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16 = calc_mask_avx2(y_mask_base, s0ABCD_w, s1ABCD_w);
57*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16, _mm256_setzero_si256());
58*77c1e3ccSAndroid Build Coastguard Worker       const __m128i x_m8 =
59*77c1e3ccSAndroid Build Coastguard Worker           _mm256_castsi256_si128(_mm256_permute4x64_epi64(m8, 0xd8));
60*77c1e3ccSAndroid Build Coastguard Worker       xx_storeu_128(mask, x_m8);
61*77c1e3ccSAndroid Build Coastguard Worker       src0 += (src0_stride << 2);
62*77c1e3ccSAndroid Build Coastguard Worker       src1 += (src1_stride << 2);
63*77c1e3ccSAndroid Build Coastguard Worker       mask += 16;
64*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
65*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
66*77c1e3ccSAndroid Build Coastguard Worker   } else if (8 == w) {
67*77c1e3ccSAndroid Build Coastguard Worker     do {
68*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0A = xx_loadl_64(src0);
69*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0B = xx_loadl_64(src0 + src0_stride);
70*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0C = xx_loadl_64(src0 + src0_stride * 2);
71*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0D = xx_loadl_64(src0 + src0_stride * 3);
72*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0AC_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(s0A, s0C));
73*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0BD_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(s0B, s0D));
74*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1A = xx_loadl_64(src1);
75*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1B = xx_loadl_64(src1 + src1_stride);
76*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1C = xx_loadl_64(src1 + src1_stride * 2);
77*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1D = xx_loadl_64(src1 + src1_stride * 3);
78*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1AB_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(s1A, s1C));
79*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1CD_w = _mm256_cvtepu8_epi16(_mm_unpacklo_epi64(s1B, s1D));
80*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16AC = calc_mask_avx2(y_mask_base, s0AC_w, s1AB_w);
81*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16BD = calc_mask_avx2(y_mask_base, s0BD_w, s1CD_w);
82*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16AC, m16BD);
83*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, m8);
84*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 2;
85*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 2;
86*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
87*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
88*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
89*77c1e3ccSAndroid Build Coastguard Worker   } else if (16 == w) {
90*77c1e3ccSAndroid Build Coastguard Worker     do {
91*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0A = xx_load_128(src0);
92*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0B = xx_load_128(src0 + src0_stride);
93*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1A = xx_load_128(src1);
94*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1B = xx_load_128(src1 + src1_stride);
95*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0AL = _mm256_cvtepu8_epi16(s0A);
96*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0BL = _mm256_cvtepu8_epi16(s0B);
97*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1AL = _mm256_cvtepu8_epi16(s1A);
98*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1BL = _mm256_cvtepu8_epi16(s1B);
99*77c1e3ccSAndroid Build Coastguard Worker 
100*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16AL = calc_mask_avx2(y_mask_base, s0AL, s1AL);
101*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16BL = calc_mask_avx2(y_mask_base, s0BL, s1BL);
102*77c1e3ccSAndroid Build Coastguard Worker 
103*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 =
104*77c1e3ccSAndroid Build Coastguard Worker           _mm256_permute4x64_epi64(_mm256_packus_epi16(m16AL, m16BL), 0xd8);
105*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, m8);
106*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 1;
107*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 1;
108*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
109*77c1e3ccSAndroid Build Coastguard Worker       i += 2;
110*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
111*77c1e3ccSAndroid Build Coastguard Worker   } else {
112*77c1e3ccSAndroid Build Coastguard Worker     do {
113*77c1e3ccSAndroid Build Coastguard Worker       int j = 0;
114*77c1e3ccSAndroid Build Coastguard Worker       do {
115*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s0 = yy_loadu_256(src0 + j);
116*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s1 = yy_loadu_256(src1 + j);
117*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s0L = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(s0));
118*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s1L = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(s1));
119*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s0H =
120*77c1e3ccSAndroid Build Coastguard Worker             _mm256_cvtepu8_epi16(_mm256_extracti128_si256(s0, 1));
121*77c1e3ccSAndroid Build Coastguard Worker         const __m256i s1H =
122*77c1e3ccSAndroid Build Coastguard Worker             _mm256_cvtepu8_epi16(_mm256_extracti128_si256(s1, 1));
123*77c1e3ccSAndroid Build Coastguard Worker         const __m256i m16L = calc_mask_avx2(y_mask_base, s0L, s1L);
124*77c1e3ccSAndroid Build Coastguard Worker         const __m256i m16H = calc_mask_avx2(y_mask_base, s0H, s1H);
125*77c1e3ccSAndroid Build Coastguard Worker         const __m256i m8 =
126*77c1e3ccSAndroid Build Coastguard Worker             _mm256_permute4x64_epi64(_mm256_packus_epi16(m16L, m16H), 0xd8);
127*77c1e3ccSAndroid Build Coastguard Worker         yy_storeu_256(mask + j, m8);
128*77c1e3ccSAndroid Build Coastguard Worker         j += 32;
129*77c1e3ccSAndroid Build Coastguard Worker       } while (j < w);
130*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
131*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
132*77c1e3ccSAndroid Build Coastguard Worker       mask += w;
133*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
134*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
135*77c1e3ccSAndroid Build Coastguard Worker   }
136*77c1e3ccSAndroid Build Coastguard Worker }
137*77c1e3ccSAndroid Build Coastguard Worker 
calc_mask_d16_avx2(const __m256i * data_src0,const __m256i * data_src1,const __m256i * round_const,const __m256i * mask_base_16,const __m256i * clip_diff,int round)138*77c1e3ccSAndroid Build Coastguard Worker static inline __m256i calc_mask_d16_avx2(const __m256i *data_src0,
139*77c1e3ccSAndroid Build Coastguard Worker                                          const __m256i *data_src1,
140*77c1e3ccSAndroid Build Coastguard Worker                                          const __m256i *round_const,
141*77c1e3ccSAndroid Build Coastguard Worker                                          const __m256i *mask_base_16,
142*77c1e3ccSAndroid Build Coastguard Worker                                          const __m256i *clip_diff, int round) {
143*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diffa = _mm256_subs_epu16(*data_src0, *data_src1);
144*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diffb = _mm256_subs_epu16(*data_src1, *data_src0);
145*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff = _mm256_max_epu16(diffa, diffb);
146*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_round =
147*77c1e3ccSAndroid Build Coastguard Worker       _mm256_srli_epi16(_mm256_adds_epu16(diff, *round_const), round);
148*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_factor = _mm256_srli_epi16(diff_round, DIFF_FACTOR_LOG2);
149*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_mask = _mm256_adds_epi16(diff_factor, *mask_base_16);
150*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_clamp = _mm256_min_epi16(diff_mask, *clip_diff);
151*77c1e3ccSAndroid Build Coastguard Worker   return diff_clamp;
152*77c1e3ccSAndroid Build Coastguard Worker }
153*77c1e3ccSAndroid Build Coastguard Worker 
calc_mask_d16_inv_avx2(const __m256i * data_src0,const __m256i * data_src1,const __m256i * round_const,const __m256i * mask_base_16,const __m256i * clip_diff,int round)154*77c1e3ccSAndroid Build Coastguard Worker static inline __m256i calc_mask_d16_inv_avx2(const __m256i *data_src0,
155*77c1e3ccSAndroid Build Coastguard Worker                                              const __m256i *data_src1,
156*77c1e3ccSAndroid Build Coastguard Worker                                              const __m256i *round_const,
157*77c1e3ccSAndroid Build Coastguard Worker                                              const __m256i *mask_base_16,
158*77c1e3ccSAndroid Build Coastguard Worker                                              const __m256i *clip_diff,
159*77c1e3ccSAndroid Build Coastguard Worker                                              int round) {
160*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diffa = _mm256_subs_epu16(*data_src0, *data_src1);
161*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diffb = _mm256_subs_epu16(*data_src1, *data_src0);
162*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff = _mm256_max_epu16(diffa, diffb);
163*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_round =
164*77c1e3ccSAndroid Build Coastguard Worker       _mm256_srli_epi16(_mm256_adds_epu16(diff, *round_const), round);
165*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_factor = _mm256_srli_epi16(diff_round, DIFF_FACTOR_LOG2);
166*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_mask = _mm256_adds_epi16(diff_factor, *mask_base_16);
167*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_clamp = _mm256_min_epi16(diff_mask, *clip_diff);
168*77c1e3ccSAndroid Build Coastguard Worker   const __m256i diff_const_16 = _mm256_sub_epi16(*clip_diff, diff_clamp);
169*77c1e3ccSAndroid Build Coastguard Worker   return diff_const_16;
170*77c1e3ccSAndroid Build Coastguard Worker }
171*77c1e3ccSAndroid Build Coastguard Worker 
build_compound_diffwtd_mask_d16_avx2(uint8_t * mask,const CONV_BUF_TYPE * src0,int src0_stride,const CONV_BUF_TYPE * src1,int src1_stride,int h,int w,int shift)172*77c1e3ccSAndroid Build Coastguard Worker static inline void build_compound_diffwtd_mask_d16_avx2(
173*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *mask, const CONV_BUF_TYPE *src0, int src0_stride,
174*77c1e3ccSAndroid Build Coastguard Worker     const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, int shift) {
175*77c1e3ccSAndroid Build Coastguard Worker   const int mask_base = 38;
176*77c1e3ccSAndroid Build Coastguard Worker   const __m256i _r = _mm256_set1_epi16((1 << shift) >> 1);
177*77c1e3ccSAndroid Build Coastguard Worker   const __m256i y38 = _mm256_set1_epi16(mask_base);
178*77c1e3ccSAndroid Build Coastguard Worker   const __m256i y64 = _mm256_set1_epi16(AOM_BLEND_A64_MAX_ALPHA);
179*77c1e3ccSAndroid Build Coastguard Worker   int i = 0;
180*77c1e3ccSAndroid Build Coastguard Worker   if (w == 4) {
181*77c1e3ccSAndroid Build Coastguard Worker     do {
182*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0A = xx_loadl_64(src0);
183*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0B = xx_loadl_64(src0 + src0_stride);
184*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0C = xx_loadl_64(src0 + src0_stride * 2);
185*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0D = xx_loadl_64(src0 + src0_stride * 3);
186*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1A = xx_loadl_64(src1);
187*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1B = xx_loadl_64(src1 + src1_stride);
188*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1C = xx_loadl_64(src1 + src1_stride * 2);
189*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1D = xx_loadl_64(src1 + src1_stride * 3);
190*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0 = yy_set_m128i(_mm_unpacklo_epi64(s0C, s0D),
191*77c1e3ccSAndroid Build Coastguard Worker                                       _mm_unpacklo_epi64(s0A, s0B));
192*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1 = yy_set_m128i(_mm_unpacklo_epi64(s1C, s1D),
193*77c1e3ccSAndroid Build Coastguard Worker                                       _mm_unpacklo_epi64(s1A, s1B));
194*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16 = calc_mask_d16_avx2(&s0, &s1, &_r, &y38, &y64, shift);
195*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16, _mm256_setzero_si256());
196*77c1e3ccSAndroid Build Coastguard Worker       xx_storeu_128(mask,
197*77c1e3ccSAndroid Build Coastguard Worker                     _mm256_castsi256_si128(_mm256_permute4x64_epi64(m8, 0xd8)));
198*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 2;
199*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 2;
200*77c1e3ccSAndroid Build Coastguard Worker       mask += 16;
201*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
202*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
203*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 8) {
204*77c1e3ccSAndroid Build Coastguard Worker     do {
205*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0AB = yy_loadu2_128(src0 + src0_stride, src0);
206*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0CD =
207*77c1e3ccSAndroid Build Coastguard Worker           yy_loadu2_128(src0 + src0_stride * 3, src0 + src0_stride * 2);
208*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1AB = yy_loadu2_128(src1 + src1_stride, src1);
209*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1CD =
210*77c1e3ccSAndroid Build Coastguard Worker           yy_loadu2_128(src1 + src1_stride * 3, src1 + src1_stride * 2);
211*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16AB =
212*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0AB, &s1AB, &_r, &y38, &y64, shift);
213*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16CD =
214*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0CD, &s1CD, &_r, &y38, &y64, shift);
215*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16AB, m16CD);
216*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
217*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 2;
218*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 2;
219*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
220*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
221*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
222*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 16) {
223*77c1e3ccSAndroid Build Coastguard Worker     do {
224*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
225*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + src0_stride);
226*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
227*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + src1_stride);
228*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
229*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
230*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
231*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
232*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16A, m16B);
233*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
234*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 1;
235*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 1;
236*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
237*77c1e3ccSAndroid Build Coastguard Worker       i += 2;
238*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
239*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 32) {
240*77c1e3ccSAndroid Build Coastguard Worker     do {
241*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
242*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
243*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
244*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
245*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
246*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
247*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
248*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
249*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16A, m16B);
250*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
251*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
252*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
253*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
254*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
255*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
256*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 64) {
257*77c1e3ccSAndroid Build Coastguard Worker     do {
258*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
259*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
260*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0C = yy_loadu_256(src0 + 32);
261*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0D = yy_loadu_256(src0 + 48);
262*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
263*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
264*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1C = yy_loadu_256(src1 + 32);
265*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1D = yy_loadu_256(src1 + 48);
266*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
267*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
268*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
269*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
270*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16C =
271*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0C, &s1C, &_r, &y38, &y64, shift);
272*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16D =
273*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0D, &s1D, &_r, &y38, &y64, shift);
274*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8AB = _mm256_packus_epi16(m16A, m16B);
275*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8CD = _mm256_packus_epi16(m16C, m16D);
276*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8AB, 0xd8));
277*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 32, _mm256_permute4x64_epi64(m8CD, 0xd8));
278*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
279*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
280*77c1e3ccSAndroid Build Coastguard Worker       mask += 64;
281*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
282*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
283*77c1e3ccSAndroid Build Coastguard Worker   } else {
284*77c1e3ccSAndroid Build Coastguard Worker     do {
285*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
286*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
287*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0C = yy_loadu_256(src0 + 32);
288*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0D = yy_loadu_256(src0 + 48);
289*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0E = yy_loadu_256(src0 + 64);
290*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0F = yy_loadu_256(src0 + 80);
291*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0G = yy_loadu_256(src0 + 96);
292*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0H = yy_loadu_256(src0 + 112);
293*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
294*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
295*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1C = yy_loadu_256(src1 + 32);
296*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1D = yy_loadu_256(src1 + 48);
297*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1E = yy_loadu_256(src1 + 64);
298*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1F = yy_loadu_256(src1 + 80);
299*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1G = yy_loadu_256(src1 + 96);
300*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1H = yy_loadu_256(src1 + 112);
301*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
302*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
303*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
304*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
305*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16C =
306*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0C, &s1C, &_r, &y38, &y64, shift);
307*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16D =
308*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0D, &s1D, &_r, &y38, &y64, shift);
309*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16E =
310*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0E, &s1E, &_r, &y38, &y64, shift);
311*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16F =
312*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0F, &s1F, &_r, &y38, &y64, shift);
313*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16G =
314*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0G, &s1G, &_r, &y38, &y64, shift);
315*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16H =
316*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_avx2(&s0H, &s1H, &_r, &y38, &y64, shift);
317*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8AB = _mm256_packus_epi16(m16A, m16B);
318*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8CD = _mm256_packus_epi16(m16C, m16D);
319*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8EF = _mm256_packus_epi16(m16E, m16F);
320*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8GH = _mm256_packus_epi16(m16G, m16H);
321*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8AB, 0xd8));
322*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 32, _mm256_permute4x64_epi64(m8CD, 0xd8));
323*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 64, _mm256_permute4x64_epi64(m8EF, 0xd8));
324*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 96, _mm256_permute4x64_epi64(m8GH, 0xd8));
325*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
326*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
327*77c1e3ccSAndroid Build Coastguard Worker       mask += 128;
328*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
329*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
330*77c1e3ccSAndroid Build Coastguard Worker   }
331*77c1e3ccSAndroid Build Coastguard Worker }
332*77c1e3ccSAndroid Build Coastguard Worker 
build_compound_diffwtd_mask_d16_inv_avx2(uint8_t * mask,const CONV_BUF_TYPE * src0,int src0_stride,const CONV_BUF_TYPE * src1,int src1_stride,int h,int w,int shift)333*77c1e3ccSAndroid Build Coastguard Worker static inline void build_compound_diffwtd_mask_d16_inv_avx2(
334*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *mask, const CONV_BUF_TYPE *src0, int src0_stride,
335*77c1e3ccSAndroid Build Coastguard Worker     const CONV_BUF_TYPE *src1, int src1_stride, int h, int w, int shift) {
336*77c1e3ccSAndroid Build Coastguard Worker   const int mask_base = 38;
337*77c1e3ccSAndroid Build Coastguard Worker   const __m256i _r = _mm256_set1_epi16((1 << shift) >> 1);
338*77c1e3ccSAndroid Build Coastguard Worker   const __m256i y38 = _mm256_set1_epi16(mask_base);
339*77c1e3ccSAndroid Build Coastguard Worker   const __m256i y64 = _mm256_set1_epi16(AOM_BLEND_A64_MAX_ALPHA);
340*77c1e3ccSAndroid Build Coastguard Worker   int i = 0;
341*77c1e3ccSAndroid Build Coastguard Worker   if (w == 4) {
342*77c1e3ccSAndroid Build Coastguard Worker     do {
343*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0A = xx_loadl_64(src0);
344*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0B = xx_loadl_64(src0 + src0_stride);
345*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0C = xx_loadl_64(src0 + src0_stride * 2);
346*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s0D = xx_loadl_64(src0 + src0_stride * 3);
347*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1A = xx_loadl_64(src1);
348*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1B = xx_loadl_64(src1 + src1_stride);
349*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1C = xx_loadl_64(src1 + src1_stride * 2);
350*77c1e3ccSAndroid Build Coastguard Worker       const __m128i s1D = xx_loadl_64(src1 + src1_stride * 3);
351*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0 = yy_set_m128i(_mm_unpacklo_epi64(s0C, s0D),
352*77c1e3ccSAndroid Build Coastguard Worker                                       _mm_unpacklo_epi64(s0A, s0B));
353*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1 = yy_set_m128i(_mm_unpacklo_epi64(s1C, s1D),
354*77c1e3ccSAndroid Build Coastguard Worker                                       _mm_unpacklo_epi64(s1A, s1B));
355*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16 =
356*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0, &s1, &_r, &y38, &y64, shift);
357*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16, _mm256_setzero_si256());
358*77c1e3ccSAndroid Build Coastguard Worker       xx_storeu_128(mask,
359*77c1e3ccSAndroid Build Coastguard Worker                     _mm256_castsi256_si128(_mm256_permute4x64_epi64(m8, 0xd8)));
360*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 2;
361*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 2;
362*77c1e3ccSAndroid Build Coastguard Worker       mask += 16;
363*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
364*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
365*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 8) {
366*77c1e3ccSAndroid Build Coastguard Worker     do {
367*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0AB = yy_loadu2_128(src0 + src0_stride, src0);
368*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0CD =
369*77c1e3ccSAndroid Build Coastguard Worker           yy_loadu2_128(src0 + src0_stride * 3, src0 + src0_stride * 2);
370*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1AB = yy_loadu2_128(src1 + src1_stride, src1);
371*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1CD =
372*77c1e3ccSAndroid Build Coastguard Worker           yy_loadu2_128(src1 + src1_stride * 3, src1 + src1_stride * 2);
373*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16AB =
374*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0AB, &s1AB, &_r, &y38, &y64, shift);
375*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16CD =
376*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0CD, &s1CD, &_r, &y38, &y64, shift);
377*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16AB, m16CD);
378*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
379*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 2;
380*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 2;
381*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
382*77c1e3ccSAndroid Build Coastguard Worker       i += 4;
383*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
384*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 16) {
385*77c1e3ccSAndroid Build Coastguard Worker     do {
386*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
387*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + src0_stride);
388*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
389*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + src1_stride);
390*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
391*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
392*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
393*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
394*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16A, m16B);
395*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
396*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride << 1;
397*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride << 1;
398*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
399*77c1e3ccSAndroid Build Coastguard Worker       i += 2;
400*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
401*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 32) {
402*77c1e3ccSAndroid Build Coastguard Worker     do {
403*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
404*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
405*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
406*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
407*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
408*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
409*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
410*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
411*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8 = _mm256_packus_epi16(m16A, m16B);
412*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8, 0xd8));
413*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
414*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
415*77c1e3ccSAndroid Build Coastguard Worker       mask += 32;
416*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
417*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
418*77c1e3ccSAndroid Build Coastguard Worker   } else if (w == 64) {
419*77c1e3ccSAndroid Build Coastguard Worker     do {
420*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
421*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
422*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0C = yy_loadu_256(src0 + 32);
423*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0D = yy_loadu_256(src0 + 48);
424*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
425*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
426*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1C = yy_loadu_256(src1 + 32);
427*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1D = yy_loadu_256(src1 + 48);
428*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
429*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
430*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
431*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
432*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16C =
433*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0C, &s1C, &_r, &y38, &y64, shift);
434*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16D =
435*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0D, &s1D, &_r, &y38, &y64, shift);
436*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8AB = _mm256_packus_epi16(m16A, m16B);
437*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8CD = _mm256_packus_epi16(m16C, m16D);
438*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8AB, 0xd8));
439*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 32, _mm256_permute4x64_epi64(m8CD, 0xd8));
440*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
441*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
442*77c1e3ccSAndroid Build Coastguard Worker       mask += 64;
443*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
444*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
445*77c1e3ccSAndroid Build Coastguard Worker   } else {
446*77c1e3ccSAndroid Build Coastguard Worker     do {
447*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0A = yy_loadu_256(src0);
448*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0B = yy_loadu_256(src0 + 16);
449*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0C = yy_loadu_256(src0 + 32);
450*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0D = yy_loadu_256(src0 + 48);
451*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0E = yy_loadu_256(src0 + 64);
452*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0F = yy_loadu_256(src0 + 80);
453*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0G = yy_loadu_256(src0 + 96);
454*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s0H = yy_loadu_256(src0 + 112);
455*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1A = yy_loadu_256(src1);
456*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1B = yy_loadu_256(src1 + 16);
457*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1C = yy_loadu_256(src1 + 32);
458*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1D = yy_loadu_256(src1 + 48);
459*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1E = yy_loadu_256(src1 + 64);
460*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1F = yy_loadu_256(src1 + 80);
461*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1G = yy_loadu_256(src1 + 96);
462*77c1e3ccSAndroid Build Coastguard Worker       const __m256i s1H = yy_loadu_256(src1 + 112);
463*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16A =
464*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0A, &s1A, &_r, &y38, &y64, shift);
465*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16B =
466*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0B, &s1B, &_r, &y38, &y64, shift);
467*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16C =
468*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0C, &s1C, &_r, &y38, &y64, shift);
469*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16D =
470*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0D, &s1D, &_r, &y38, &y64, shift);
471*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16E =
472*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0E, &s1E, &_r, &y38, &y64, shift);
473*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16F =
474*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0F, &s1F, &_r, &y38, &y64, shift);
475*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16G =
476*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0G, &s1G, &_r, &y38, &y64, shift);
477*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m16H =
478*77c1e3ccSAndroid Build Coastguard Worker           calc_mask_d16_inv_avx2(&s0H, &s1H, &_r, &y38, &y64, shift);
479*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8AB = _mm256_packus_epi16(m16A, m16B);
480*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8CD = _mm256_packus_epi16(m16C, m16D);
481*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8EF = _mm256_packus_epi16(m16E, m16F);
482*77c1e3ccSAndroid Build Coastguard Worker       const __m256i m8GH = _mm256_packus_epi16(m16G, m16H);
483*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask, _mm256_permute4x64_epi64(m8AB, 0xd8));
484*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 32, _mm256_permute4x64_epi64(m8CD, 0xd8));
485*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 64, _mm256_permute4x64_epi64(m8EF, 0xd8));
486*77c1e3ccSAndroid Build Coastguard Worker       yy_storeu_256(mask + 96, _mm256_permute4x64_epi64(m8GH, 0xd8));
487*77c1e3ccSAndroid Build Coastguard Worker       src0 += src0_stride;
488*77c1e3ccSAndroid Build Coastguard Worker       src1 += src1_stride;
489*77c1e3ccSAndroid Build Coastguard Worker       mask += 128;
490*77c1e3ccSAndroid Build Coastguard Worker       i += 1;
491*77c1e3ccSAndroid Build Coastguard Worker     } while (i < h);
492*77c1e3ccSAndroid Build Coastguard Worker   }
493*77c1e3ccSAndroid Build Coastguard Worker }
494*77c1e3ccSAndroid Build Coastguard Worker 
av1_build_compound_diffwtd_mask_d16_avx2(uint8_t * mask,DIFFWTD_MASK_TYPE mask_type,const CONV_BUF_TYPE * src0,int src0_stride,const CONV_BUF_TYPE * src1,int src1_stride,int h,int w,ConvolveParams * conv_params,int bd)495*77c1e3ccSAndroid Build Coastguard Worker void av1_build_compound_diffwtd_mask_d16_avx2(
496*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0,
497*77c1e3ccSAndroid Build Coastguard Worker     int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w,
498*77c1e3ccSAndroid Build Coastguard Worker     ConvolveParams *conv_params, int bd) {
499*77c1e3ccSAndroid Build Coastguard Worker   const int shift =
500*77c1e3ccSAndroid Build Coastguard Worker       2 * FILTER_BITS - conv_params->round_0 - conv_params->round_1 + (bd - 8);
501*77c1e3ccSAndroid Build Coastguard Worker   // When rounding constant is added, there is a possibility of overflow.
502*77c1e3ccSAndroid Build Coastguard Worker   // However that much precision is not required. Code should very well work for
503*77c1e3ccSAndroid Build Coastguard Worker   // other values of DIFF_FACTOR_LOG2 and AOM_BLEND_A64_MAX_ALPHA as well. But
504*77c1e3ccSAndroid Build Coastguard Worker   // there is a possibility of corner case bugs.
505*77c1e3ccSAndroid Build Coastguard Worker   assert(DIFF_FACTOR_LOG2 == 4);
506*77c1e3ccSAndroid Build Coastguard Worker   assert(AOM_BLEND_A64_MAX_ALPHA == 64);
507*77c1e3ccSAndroid Build Coastguard Worker 
508*77c1e3ccSAndroid Build Coastguard Worker   if (mask_type == DIFFWTD_38) {
509*77c1e3ccSAndroid Build Coastguard Worker     build_compound_diffwtd_mask_d16_avx2(mask, src0, src0_stride, src1,
510*77c1e3ccSAndroid Build Coastguard Worker                                          src1_stride, h, w, shift);
511*77c1e3ccSAndroid Build Coastguard Worker   } else {
512*77c1e3ccSAndroid Build Coastguard Worker     build_compound_diffwtd_mask_d16_inv_avx2(mask, src0, src0_stride, src1,
513*77c1e3ccSAndroid Build Coastguard Worker                                              src1_stride, h, w, shift);
514*77c1e3ccSAndroid Build Coastguard Worker   }
515*77c1e3ccSAndroid Build Coastguard Worker }
516*77c1e3ccSAndroid Build Coastguard Worker 
517*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
518*77c1e3ccSAndroid Build Coastguard Worker 
av1_build_compound_diffwtd_mask_highbd_avx2(uint8_t * mask,DIFFWTD_MASK_TYPE mask_type,const uint8_t * src0,int src0_stride,const uint8_t * src1,int src1_stride,int h,int w,int bd)519*77c1e3ccSAndroid Build Coastguard Worker void av1_build_compound_diffwtd_mask_highbd_avx2(
520*77c1e3ccSAndroid Build Coastguard Worker     uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0,
521*77c1e3ccSAndroid Build Coastguard Worker     int src0_stride, const uint8_t *src1, int src1_stride, int h, int w,
522*77c1e3ccSAndroid Build Coastguard Worker     int bd) {
523*77c1e3ccSAndroid Build Coastguard Worker   if (w < 16) {
524*77c1e3ccSAndroid Build Coastguard Worker     av1_build_compound_diffwtd_mask_highbd_ssse3(
525*77c1e3ccSAndroid Build Coastguard Worker         mask, mask_type, src0, src0_stride, src1, src1_stride, h, w, bd);
526*77c1e3ccSAndroid Build Coastguard Worker   } else {
527*77c1e3ccSAndroid Build Coastguard Worker     assert(mask_type == DIFFWTD_38 || mask_type == DIFFWTD_38_INV);
528*77c1e3ccSAndroid Build Coastguard Worker     assert(bd >= 8);
529*77c1e3ccSAndroid Build Coastguard Worker     assert((w % 16) == 0);
530*77c1e3ccSAndroid Build Coastguard Worker     const __m256i y0 = _mm256_setzero_si256();
531*77c1e3ccSAndroid Build Coastguard Worker     const __m256i yAOM_BLEND_A64_MAX_ALPHA =
532*77c1e3ccSAndroid Build Coastguard Worker         _mm256_set1_epi16(AOM_BLEND_A64_MAX_ALPHA);
533*77c1e3ccSAndroid Build Coastguard Worker     const int mask_base = 38;
534*77c1e3ccSAndroid Build Coastguard Worker     const __m256i ymask_base = _mm256_set1_epi16(mask_base);
535*77c1e3ccSAndroid Build Coastguard Worker     const uint16_t *ssrc0 = CONVERT_TO_SHORTPTR(src0);
536*77c1e3ccSAndroid Build Coastguard Worker     const uint16_t *ssrc1 = CONVERT_TO_SHORTPTR(src1);
537*77c1e3ccSAndroid Build Coastguard Worker     if (bd == 8) {
538*77c1e3ccSAndroid Build Coastguard Worker       if (mask_type == DIFFWTD_38_INV) {
539*77c1e3ccSAndroid Build Coastguard Worker         for (int i = 0; i < h; ++i) {
540*77c1e3ccSAndroid Build Coastguard Worker           for (int j = 0; j < w; j += 16) {
541*77c1e3ccSAndroid Build Coastguard Worker             __m256i s0 = _mm256_loadu_si256((const __m256i *)&ssrc0[j]);
542*77c1e3ccSAndroid Build Coastguard Worker             __m256i s1 = _mm256_loadu_si256((const __m256i *)&ssrc1[j]);
543*77c1e3ccSAndroid Build Coastguard Worker             __m256i diff = _mm256_srai_epi16(
544*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_abs_epi16(_mm256_sub_epi16(s0, s1)), DIFF_FACTOR_LOG2);
545*77c1e3ccSAndroid Build Coastguard Worker             __m256i m = _mm256_min_epi16(
546*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_max_epi16(y0, _mm256_add_epi16(diff, ymask_base)),
547*77c1e3ccSAndroid Build Coastguard Worker                 yAOM_BLEND_A64_MAX_ALPHA);
548*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_sub_epi16(yAOM_BLEND_A64_MAX_ALPHA, m);
549*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_packus_epi16(m, m);
550*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_permute4x64_epi64(m, _MM_SHUFFLE(0, 0, 2, 0));
551*77c1e3ccSAndroid Build Coastguard Worker             __m128i m0 = _mm256_castsi256_si128(m);
552*77c1e3ccSAndroid Build Coastguard Worker             _mm_storeu_si128((__m128i *)&mask[j], m0);
553*77c1e3ccSAndroid Build Coastguard Worker           }
554*77c1e3ccSAndroid Build Coastguard Worker           ssrc0 += src0_stride;
555*77c1e3ccSAndroid Build Coastguard Worker           ssrc1 += src1_stride;
556*77c1e3ccSAndroid Build Coastguard Worker           mask += w;
557*77c1e3ccSAndroid Build Coastguard Worker         }
558*77c1e3ccSAndroid Build Coastguard Worker       } else {
559*77c1e3ccSAndroid Build Coastguard Worker         for (int i = 0; i < h; ++i) {
560*77c1e3ccSAndroid Build Coastguard Worker           for (int j = 0; j < w; j += 16) {
561*77c1e3ccSAndroid Build Coastguard Worker             __m256i s0 = _mm256_loadu_si256((const __m256i *)&ssrc0[j]);
562*77c1e3ccSAndroid Build Coastguard Worker             __m256i s1 = _mm256_loadu_si256((const __m256i *)&ssrc1[j]);
563*77c1e3ccSAndroid Build Coastguard Worker             __m256i diff = _mm256_srai_epi16(
564*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_abs_epi16(_mm256_sub_epi16(s0, s1)), DIFF_FACTOR_LOG2);
565*77c1e3ccSAndroid Build Coastguard Worker             __m256i m = _mm256_min_epi16(
566*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_max_epi16(y0, _mm256_add_epi16(diff, ymask_base)),
567*77c1e3ccSAndroid Build Coastguard Worker                 yAOM_BLEND_A64_MAX_ALPHA);
568*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_packus_epi16(m, m);
569*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_permute4x64_epi64(m, _MM_SHUFFLE(0, 0, 2, 0));
570*77c1e3ccSAndroid Build Coastguard Worker             __m128i m0 = _mm256_castsi256_si128(m);
571*77c1e3ccSAndroid Build Coastguard Worker             _mm_storeu_si128((__m128i *)&mask[j], m0);
572*77c1e3ccSAndroid Build Coastguard Worker           }
573*77c1e3ccSAndroid Build Coastguard Worker           ssrc0 += src0_stride;
574*77c1e3ccSAndroid Build Coastguard Worker           ssrc1 += src1_stride;
575*77c1e3ccSAndroid Build Coastguard Worker           mask += w;
576*77c1e3ccSAndroid Build Coastguard Worker         }
577*77c1e3ccSAndroid Build Coastguard Worker       }
578*77c1e3ccSAndroid Build Coastguard Worker     } else {
579*77c1e3ccSAndroid Build Coastguard Worker       const __m128i xshift = _mm_set1_epi64x(bd - 8 + DIFF_FACTOR_LOG2);
580*77c1e3ccSAndroid Build Coastguard Worker       if (mask_type == DIFFWTD_38_INV) {
581*77c1e3ccSAndroid Build Coastguard Worker         for (int i = 0; i < h; ++i) {
582*77c1e3ccSAndroid Build Coastguard Worker           for (int j = 0; j < w; j += 16) {
583*77c1e3ccSAndroid Build Coastguard Worker             __m256i s0 = _mm256_loadu_si256((const __m256i *)&ssrc0[j]);
584*77c1e3ccSAndroid Build Coastguard Worker             __m256i s1 = _mm256_loadu_si256((const __m256i *)&ssrc1[j]);
585*77c1e3ccSAndroid Build Coastguard Worker             __m256i diff = _mm256_sra_epi16(
586*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_abs_epi16(_mm256_sub_epi16(s0, s1)), xshift);
587*77c1e3ccSAndroid Build Coastguard Worker             __m256i m = _mm256_min_epi16(
588*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_max_epi16(y0, _mm256_add_epi16(diff, ymask_base)),
589*77c1e3ccSAndroid Build Coastguard Worker                 yAOM_BLEND_A64_MAX_ALPHA);
590*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_sub_epi16(yAOM_BLEND_A64_MAX_ALPHA, m);
591*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_packus_epi16(m, m);
592*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_permute4x64_epi64(m, _MM_SHUFFLE(0, 0, 2, 0));
593*77c1e3ccSAndroid Build Coastguard Worker             __m128i m0 = _mm256_castsi256_si128(m);
594*77c1e3ccSAndroid Build Coastguard Worker             _mm_storeu_si128((__m128i *)&mask[j], m0);
595*77c1e3ccSAndroid Build Coastguard Worker           }
596*77c1e3ccSAndroid Build Coastguard Worker           ssrc0 += src0_stride;
597*77c1e3ccSAndroid Build Coastguard Worker           ssrc1 += src1_stride;
598*77c1e3ccSAndroid Build Coastguard Worker           mask += w;
599*77c1e3ccSAndroid Build Coastguard Worker         }
600*77c1e3ccSAndroid Build Coastguard Worker       } else {
601*77c1e3ccSAndroid Build Coastguard Worker         for (int i = 0; i < h; ++i) {
602*77c1e3ccSAndroid Build Coastguard Worker           for (int j = 0; j < w; j += 16) {
603*77c1e3ccSAndroid Build Coastguard Worker             __m256i s0 = _mm256_loadu_si256((const __m256i *)&ssrc0[j]);
604*77c1e3ccSAndroid Build Coastguard Worker             __m256i s1 = _mm256_loadu_si256((const __m256i *)&ssrc1[j]);
605*77c1e3ccSAndroid Build Coastguard Worker             __m256i diff = _mm256_sra_epi16(
606*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_abs_epi16(_mm256_sub_epi16(s0, s1)), xshift);
607*77c1e3ccSAndroid Build Coastguard Worker             __m256i m = _mm256_min_epi16(
608*77c1e3ccSAndroid Build Coastguard Worker                 _mm256_max_epi16(y0, _mm256_add_epi16(diff, ymask_base)),
609*77c1e3ccSAndroid Build Coastguard Worker                 yAOM_BLEND_A64_MAX_ALPHA);
610*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_packus_epi16(m, m);
611*77c1e3ccSAndroid Build Coastguard Worker             m = _mm256_permute4x64_epi64(m, _MM_SHUFFLE(0, 0, 2, 0));
612*77c1e3ccSAndroid Build Coastguard Worker             __m128i m0 = _mm256_castsi256_si128(m);
613*77c1e3ccSAndroid Build Coastguard Worker             _mm_storeu_si128((__m128i *)&mask[j], m0);
614*77c1e3ccSAndroid Build Coastguard Worker           }
615*77c1e3ccSAndroid Build Coastguard Worker           ssrc0 += src0_stride;
616*77c1e3ccSAndroid Build Coastguard Worker           ssrc1 += src1_stride;
617*77c1e3ccSAndroid Build Coastguard Worker           mask += w;
618*77c1e3ccSAndroid Build Coastguard Worker         }
619*77c1e3ccSAndroid Build Coastguard Worker       }
620*77c1e3ccSAndroid Build Coastguard Worker     }
621*77c1e3ccSAndroid Build Coastguard Worker   }
622*77c1e3ccSAndroid Build Coastguard Worker }
623*77c1e3ccSAndroid Build Coastguard Worker 
624*77c1e3ccSAndroid Build Coastguard Worker #endif  // CONFIG_AV1_HIGHBITDEPTH
625