Line data Source code
1 : /*
2 : * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 : *
4 : * This source code is subject to the terms of the BSD 2 Clause License and
5 : * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 : * was not distributed with this source code in the LICENSE file, you can
7 : * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 : * Media Patent License 1.0 was not distributed with this source code in the
9 : * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 : */
11 :
12 : #include <immintrin.h> // avx2
13 :
14 : #include "./av1_rtcd.h"
15 : #include "./aom_dsp_rtcd.h"
16 :
17 : #include "aom_dsp/x86/fwd_txfm_avx2.h"
18 : #include "aom_dsp/txfm_common.h"
19 : #include "aom_dsp/x86/txfm_common_avx2.h"
20 :
21 0 : static int32_t get_16x16_sum(const int16_t *input, int stride) {
22 : __m256i r0, r1, r2, r3, u0, u1;
23 0 : __m256i zero = _mm256_setzero_si256();
24 0 : __m256i sum = _mm256_setzero_si256();
25 0 : const int16_t *blockBound = input + (stride << 4);
26 : __m128i v0, v1;
27 :
28 0 : while (input < blockBound) {
29 0 : r0 = _mm256_loadu_si256((__m256i const *)input);
30 0 : r1 = _mm256_loadu_si256((__m256i const *)(input + stride));
31 0 : r2 = _mm256_loadu_si256((__m256i const *)(input + 2 * stride));
32 0 : r3 = _mm256_loadu_si256((__m256i const *)(input + 3 * stride));
33 :
34 0 : u0 = _mm256_add_epi16(r0, r1);
35 0 : u1 = _mm256_add_epi16(r2, r3);
36 0 : sum = _mm256_add_epi16(sum, u0);
37 0 : sum = _mm256_add_epi16(sum, u1);
38 :
39 0 : input += stride << 2;
40 : }
41 :
42 : // unpack 16 int16_t into 2x8 int32_t
43 0 : u0 = _mm256_unpacklo_epi16(zero, sum);
44 0 : u1 = _mm256_unpackhi_epi16(zero, sum);
45 0 : u0 = _mm256_srai_epi32(u0, 16);
46 0 : u1 = _mm256_srai_epi32(u1, 16);
47 0 : sum = _mm256_add_epi32(u0, u1);
48 :
49 0 : u0 = _mm256_srli_si256(sum, 8);
50 0 : u1 = _mm256_add_epi32(sum, u0);
51 :
52 0 : v0 = _mm_add_epi32(_mm256_extracti128_si256(u1, 1),
53 : _mm256_castsi256_si128(u1));
54 0 : v1 = _mm_srli_si128(v0, 4);
55 0 : v0 = _mm_add_epi32(v0, v1);
56 0 : return (int32_t)_mm_extract_epi32(v0, 0);
57 : }
58 :
59 0 : void aom_fdct16x16_1_avx2(const int16_t *input, tran_low_t *output,
60 : int stride) {
61 0 : int32_t dc = get_16x16_sum(input, stride);
62 0 : output[0] = (tran_low_t)(dc >> 1);
63 : _mm256_zeroupper();
64 0 : }
65 :
66 0 : static INLINE void load_buffer_16x16(const int16_t *input, int stride,
67 : int flipud, int fliplr, __m256i *in) {
68 0 : if (!flipud) {
69 0 : in[0] = _mm256_loadu_si256((const __m256i *)(input + 0 * stride));
70 0 : in[1] = _mm256_loadu_si256((const __m256i *)(input + 1 * stride));
71 0 : in[2] = _mm256_loadu_si256((const __m256i *)(input + 2 * stride));
72 0 : in[3] = _mm256_loadu_si256((const __m256i *)(input + 3 * stride));
73 0 : in[4] = _mm256_loadu_si256((const __m256i *)(input + 4 * stride));
74 0 : in[5] = _mm256_loadu_si256((const __m256i *)(input + 5 * stride));
75 0 : in[6] = _mm256_loadu_si256((const __m256i *)(input + 6 * stride));
76 0 : in[7] = _mm256_loadu_si256((const __m256i *)(input + 7 * stride));
77 0 : in[8] = _mm256_loadu_si256((const __m256i *)(input + 8 * stride));
78 0 : in[9] = _mm256_loadu_si256((const __m256i *)(input + 9 * stride));
79 0 : in[10] = _mm256_loadu_si256((const __m256i *)(input + 10 * stride));
80 0 : in[11] = _mm256_loadu_si256((const __m256i *)(input + 11 * stride));
81 0 : in[12] = _mm256_loadu_si256((const __m256i *)(input + 12 * stride));
82 0 : in[13] = _mm256_loadu_si256((const __m256i *)(input + 13 * stride));
83 0 : in[14] = _mm256_loadu_si256((const __m256i *)(input + 14 * stride));
84 0 : in[15] = _mm256_loadu_si256((const __m256i *)(input + 15 * stride));
85 : } else {
86 0 : in[0] = _mm256_loadu_si256((const __m256i *)(input + 15 * stride));
87 0 : in[1] = _mm256_loadu_si256((const __m256i *)(input + 14 * stride));
88 0 : in[2] = _mm256_loadu_si256((const __m256i *)(input + 13 * stride));
89 0 : in[3] = _mm256_loadu_si256((const __m256i *)(input + 12 * stride));
90 0 : in[4] = _mm256_loadu_si256((const __m256i *)(input + 11 * stride));
91 0 : in[5] = _mm256_loadu_si256((const __m256i *)(input + 10 * stride));
92 0 : in[6] = _mm256_loadu_si256((const __m256i *)(input + 9 * stride));
93 0 : in[7] = _mm256_loadu_si256((const __m256i *)(input + 8 * stride));
94 0 : in[8] = _mm256_loadu_si256((const __m256i *)(input + 7 * stride));
95 0 : in[9] = _mm256_loadu_si256((const __m256i *)(input + 6 * stride));
96 0 : in[10] = _mm256_loadu_si256((const __m256i *)(input + 5 * stride));
97 0 : in[11] = _mm256_loadu_si256((const __m256i *)(input + 4 * stride));
98 0 : in[12] = _mm256_loadu_si256((const __m256i *)(input + 3 * stride));
99 0 : in[13] = _mm256_loadu_si256((const __m256i *)(input + 2 * stride));
100 0 : in[14] = _mm256_loadu_si256((const __m256i *)(input + 1 * stride));
101 0 : in[15] = _mm256_loadu_si256((const __m256i *)(input + 0 * stride));
102 : }
103 :
104 0 : if (fliplr) {
105 0 : mm256_reverse_epi16(&in[0]);
106 0 : mm256_reverse_epi16(&in[1]);
107 0 : mm256_reverse_epi16(&in[2]);
108 0 : mm256_reverse_epi16(&in[3]);
109 0 : mm256_reverse_epi16(&in[4]);
110 0 : mm256_reverse_epi16(&in[5]);
111 0 : mm256_reverse_epi16(&in[6]);
112 0 : mm256_reverse_epi16(&in[7]);
113 0 : mm256_reverse_epi16(&in[8]);
114 0 : mm256_reverse_epi16(&in[9]);
115 0 : mm256_reverse_epi16(&in[10]);
116 0 : mm256_reverse_epi16(&in[11]);
117 0 : mm256_reverse_epi16(&in[12]);
118 0 : mm256_reverse_epi16(&in[13]);
119 0 : mm256_reverse_epi16(&in[14]);
120 0 : mm256_reverse_epi16(&in[15]);
121 : }
122 :
123 0 : in[0] = _mm256_slli_epi16(in[0], 2);
124 0 : in[1] = _mm256_slli_epi16(in[1], 2);
125 0 : in[2] = _mm256_slli_epi16(in[2], 2);
126 0 : in[3] = _mm256_slli_epi16(in[3], 2);
127 0 : in[4] = _mm256_slli_epi16(in[4], 2);
128 0 : in[5] = _mm256_slli_epi16(in[5], 2);
129 0 : in[6] = _mm256_slli_epi16(in[6], 2);
130 0 : in[7] = _mm256_slli_epi16(in[7], 2);
131 0 : in[8] = _mm256_slli_epi16(in[8], 2);
132 0 : in[9] = _mm256_slli_epi16(in[9], 2);
133 0 : in[10] = _mm256_slli_epi16(in[10], 2);
134 0 : in[11] = _mm256_slli_epi16(in[11], 2);
135 0 : in[12] = _mm256_slli_epi16(in[12], 2);
136 0 : in[13] = _mm256_slli_epi16(in[13], 2);
137 0 : in[14] = _mm256_slli_epi16(in[14], 2);
138 0 : in[15] = _mm256_slli_epi16(in[15], 2);
139 0 : }
140 :
141 0 : static INLINE void write_buffer_16x16(const __m256i *in, tran_low_t *output) {
142 : int i;
143 0 : for (i = 0; i < 16; ++i) {
144 0 : storeu_output_avx2(&in[i], output + (i << 4));
145 : }
146 0 : }
147 :
148 0 : static void right_shift_16x16(__m256i *in) {
149 0 : const __m256i one = _mm256_set1_epi16(1);
150 0 : __m256i s0 = _mm256_srai_epi16(in[0], 15);
151 0 : __m256i s1 = _mm256_srai_epi16(in[1], 15);
152 0 : __m256i s2 = _mm256_srai_epi16(in[2], 15);
153 0 : __m256i s3 = _mm256_srai_epi16(in[3], 15);
154 0 : __m256i s4 = _mm256_srai_epi16(in[4], 15);
155 0 : __m256i s5 = _mm256_srai_epi16(in[5], 15);
156 0 : __m256i s6 = _mm256_srai_epi16(in[6], 15);
157 0 : __m256i s7 = _mm256_srai_epi16(in[7], 15);
158 0 : __m256i s8 = _mm256_srai_epi16(in[8], 15);
159 0 : __m256i s9 = _mm256_srai_epi16(in[9], 15);
160 0 : __m256i s10 = _mm256_srai_epi16(in[10], 15);
161 0 : __m256i s11 = _mm256_srai_epi16(in[11], 15);
162 0 : __m256i s12 = _mm256_srai_epi16(in[12], 15);
163 0 : __m256i s13 = _mm256_srai_epi16(in[13], 15);
164 0 : __m256i s14 = _mm256_srai_epi16(in[14], 15);
165 0 : __m256i s15 = _mm256_srai_epi16(in[15], 15);
166 :
167 0 : in[0] = _mm256_add_epi16(in[0], one);
168 0 : in[1] = _mm256_add_epi16(in[1], one);
169 0 : in[2] = _mm256_add_epi16(in[2], one);
170 0 : in[3] = _mm256_add_epi16(in[3], one);
171 0 : in[4] = _mm256_add_epi16(in[4], one);
172 0 : in[5] = _mm256_add_epi16(in[5], one);
173 0 : in[6] = _mm256_add_epi16(in[6], one);
174 0 : in[7] = _mm256_add_epi16(in[7], one);
175 0 : in[8] = _mm256_add_epi16(in[8], one);
176 0 : in[9] = _mm256_add_epi16(in[9], one);
177 0 : in[10] = _mm256_add_epi16(in[10], one);
178 0 : in[11] = _mm256_add_epi16(in[11], one);
179 0 : in[12] = _mm256_add_epi16(in[12], one);
180 0 : in[13] = _mm256_add_epi16(in[13], one);
181 0 : in[14] = _mm256_add_epi16(in[14], one);
182 0 : in[15] = _mm256_add_epi16(in[15], one);
183 :
184 0 : in[0] = _mm256_sub_epi16(in[0], s0);
185 0 : in[1] = _mm256_sub_epi16(in[1], s1);
186 0 : in[2] = _mm256_sub_epi16(in[2], s2);
187 0 : in[3] = _mm256_sub_epi16(in[3], s3);
188 0 : in[4] = _mm256_sub_epi16(in[4], s4);
189 0 : in[5] = _mm256_sub_epi16(in[5], s5);
190 0 : in[6] = _mm256_sub_epi16(in[6], s6);
191 0 : in[7] = _mm256_sub_epi16(in[7], s7);
192 0 : in[8] = _mm256_sub_epi16(in[8], s8);
193 0 : in[9] = _mm256_sub_epi16(in[9], s9);
194 0 : in[10] = _mm256_sub_epi16(in[10], s10);
195 0 : in[11] = _mm256_sub_epi16(in[11], s11);
196 0 : in[12] = _mm256_sub_epi16(in[12], s12);
197 0 : in[13] = _mm256_sub_epi16(in[13], s13);
198 0 : in[14] = _mm256_sub_epi16(in[14], s14);
199 0 : in[15] = _mm256_sub_epi16(in[15], s15);
200 :
201 0 : in[0] = _mm256_srai_epi16(in[0], 2);
202 0 : in[1] = _mm256_srai_epi16(in[1], 2);
203 0 : in[2] = _mm256_srai_epi16(in[2], 2);
204 0 : in[3] = _mm256_srai_epi16(in[3], 2);
205 0 : in[4] = _mm256_srai_epi16(in[4], 2);
206 0 : in[5] = _mm256_srai_epi16(in[5], 2);
207 0 : in[6] = _mm256_srai_epi16(in[6], 2);
208 0 : in[7] = _mm256_srai_epi16(in[7], 2);
209 0 : in[8] = _mm256_srai_epi16(in[8], 2);
210 0 : in[9] = _mm256_srai_epi16(in[9], 2);
211 0 : in[10] = _mm256_srai_epi16(in[10], 2);
212 0 : in[11] = _mm256_srai_epi16(in[11], 2);
213 0 : in[12] = _mm256_srai_epi16(in[12], 2);
214 0 : in[13] = _mm256_srai_epi16(in[13], 2);
215 0 : in[14] = _mm256_srai_epi16(in[14], 2);
216 0 : in[15] = _mm256_srai_epi16(in[15], 2);
217 0 : }
218 :
219 0 : static void fdct16_avx2(__m256i *in) {
220 : // sequence: cospi_L_H = pairs(L, H) and L first
221 0 : const __m256i cospi_p16_m16 = pair256_set_epi16(cospi_16_64, -cospi_16_64);
222 0 : const __m256i cospi_p16_p16 = pair256_set_epi16(cospi_16_64, cospi_16_64);
223 0 : const __m256i cospi_p24_p08 = pair256_set_epi16(cospi_24_64, cospi_8_64);
224 0 : const __m256i cospi_m08_p24 = pair256_set_epi16(-cospi_8_64, cospi_24_64);
225 0 : const __m256i cospi_m24_m08 = pair256_set_epi16(-cospi_24_64, -cospi_8_64);
226 :
227 0 : const __m256i cospi_p28_p04 = pair256_set_epi16(cospi_28_64, cospi_4_64);
228 0 : const __m256i cospi_m04_p28 = pair256_set_epi16(-cospi_4_64, cospi_28_64);
229 0 : const __m256i cospi_p12_p20 = pair256_set_epi16(cospi_12_64, cospi_20_64);
230 0 : const __m256i cospi_m20_p12 = pair256_set_epi16(-cospi_20_64, cospi_12_64);
231 :
232 0 : const __m256i cospi_p30_p02 = pair256_set_epi16(cospi_30_64, cospi_2_64);
233 0 : const __m256i cospi_m02_p30 = pair256_set_epi16(-cospi_2_64, cospi_30_64);
234 :
235 0 : const __m256i cospi_p14_p18 = pair256_set_epi16(cospi_14_64, cospi_18_64);
236 0 : const __m256i cospi_m18_p14 = pair256_set_epi16(-cospi_18_64, cospi_14_64);
237 :
238 0 : const __m256i cospi_p22_p10 = pair256_set_epi16(cospi_22_64, cospi_10_64);
239 0 : const __m256i cospi_m10_p22 = pair256_set_epi16(-cospi_10_64, cospi_22_64);
240 :
241 0 : const __m256i cospi_p06_p26 = pair256_set_epi16(cospi_6_64, cospi_26_64);
242 0 : const __m256i cospi_m26_p06 = pair256_set_epi16(-cospi_26_64, cospi_6_64);
243 :
244 : __m256i u0, u1, u2, u3, u4, u5, u6, u7;
245 : __m256i s0, s1, s2, s3, s4, s5, s6, s7;
246 : __m256i t0, t1, t2, t3, t4, t5, t6, t7;
247 : __m256i v0, v1, v2, v3;
248 : __m256i x0, x1;
249 :
250 : // 0, 4, 8, 12
251 0 : u0 = _mm256_add_epi16(in[0], in[15]);
252 0 : u1 = _mm256_add_epi16(in[1], in[14]);
253 0 : u2 = _mm256_add_epi16(in[2], in[13]);
254 0 : u3 = _mm256_add_epi16(in[3], in[12]);
255 0 : u4 = _mm256_add_epi16(in[4], in[11]);
256 0 : u5 = _mm256_add_epi16(in[5], in[10]);
257 0 : u6 = _mm256_add_epi16(in[6], in[9]);
258 0 : u7 = _mm256_add_epi16(in[7], in[8]);
259 :
260 0 : s0 = _mm256_add_epi16(u0, u7);
261 0 : s1 = _mm256_add_epi16(u1, u6);
262 0 : s2 = _mm256_add_epi16(u2, u5);
263 0 : s3 = _mm256_add_epi16(u3, u4);
264 :
265 : // 0, 8
266 0 : v0 = _mm256_add_epi16(s0, s3);
267 0 : v1 = _mm256_add_epi16(s1, s2);
268 :
269 0 : x0 = _mm256_unpacklo_epi16(v0, v1);
270 0 : x1 = _mm256_unpackhi_epi16(v0, v1);
271 :
272 0 : t0 = butter_fly(&x0, &x1, &cospi_p16_p16);
273 0 : t1 = butter_fly(&x0, &x1, &cospi_p16_m16);
274 :
275 : // 4, 12
276 0 : v0 = _mm256_sub_epi16(s1, s2);
277 0 : v1 = _mm256_sub_epi16(s0, s3);
278 :
279 0 : x0 = _mm256_unpacklo_epi16(v0, v1);
280 0 : x1 = _mm256_unpackhi_epi16(v0, v1);
281 :
282 0 : t2 = butter_fly(&x0, &x1, &cospi_p24_p08);
283 0 : t3 = butter_fly(&x0, &x1, &cospi_m08_p24);
284 :
285 : // 2, 6, 10, 14
286 0 : s0 = _mm256_sub_epi16(u3, u4);
287 0 : s1 = _mm256_sub_epi16(u2, u5);
288 0 : s2 = _mm256_sub_epi16(u1, u6);
289 0 : s3 = _mm256_sub_epi16(u0, u7);
290 :
291 0 : v0 = s0; // output[4]
292 0 : v3 = s3; // output[7]
293 :
294 0 : x0 = _mm256_unpacklo_epi16(s2, s1);
295 0 : x1 = _mm256_unpackhi_epi16(s2, s1);
296 :
297 0 : v2 = butter_fly(&x0, &x1, &cospi_p16_p16); // output[5]
298 0 : v1 = butter_fly(&x0, &x1, &cospi_p16_m16); // output[6]
299 :
300 0 : s0 = _mm256_add_epi16(v0, v1); // step[4]
301 0 : s1 = _mm256_sub_epi16(v0, v1); // step[5]
302 0 : s2 = _mm256_sub_epi16(v3, v2); // step[6]
303 0 : s3 = _mm256_add_epi16(v3, v2); // step[7]
304 :
305 : // 2, 14
306 0 : x0 = _mm256_unpacklo_epi16(s0, s3);
307 0 : x1 = _mm256_unpackhi_epi16(s0, s3);
308 :
309 0 : t4 = butter_fly(&x0, &x1, &cospi_p28_p04);
310 0 : t5 = butter_fly(&x0, &x1, &cospi_m04_p28);
311 :
312 : // 10, 6
313 0 : x0 = _mm256_unpacklo_epi16(s1, s2);
314 0 : x1 = _mm256_unpackhi_epi16(s1, s2);
315 0 : t6 = butter_fly(&x0, &x1, &cospi_p12_p20);
316 0 : t7 = butter_fly(&x0, &x1, &cospi_m20_p12);
317 :
318 : // 1, 3, 5, 7, 9, 11, 13, 15
319 0 : s0 = _mm256_sub_epi16(in[7], in[8]); // step[8]
320 0 : s1 = _mm256_sub_epi16(in[6], in[9]); // step[9]
321 0 : u2 = _mm256_sub_epi16(in[5], in[10]);
322 0 : u3 = _mm256_sub_epi16(in[4], in[11]);
323 0 : u4 = _mm256_sub_epi16(in[3], in[12]);
324 0 : u5 = _mm256_sub_epi16(in[2], in[13]);
325 0 : s6 = _mm256_sub_epi16(in[1], in[14]); // step[14]
326 0 : s7 = _mm256_sub_epi16(in[0], in[15]); // step[15]
327 :
328 0 : in[0] = t0;
329 0 : in[8] = t1;
330 0 : in[4] = t2;
331 0 : in[12] = t3;
332 0 : in[2] = t4;
333 0 : in[14] = t5;
334 0 : in[10] = t6;
335 0 : in[6] = t7;
336 :
337 0 : x0 = _mm256_unpacklo_epi16(u5, u2);
338 0 : x1 = _mm256_unpackhi_epi16(u5, u2);
339 :
340 0 : s2 = butter_fly(&x0, &x1, &cospi_p16_p16); // step[13]
341 0 : s5 = butter_fly(&x0, &x1, &cospi_p16_m16); // step[10]
342 :
343 0 : x0 = _mm256_unpacklo_epi16(u4, u3);
344 0 : x1 = _mm256_unpackhi_epi16(u4, u3);
345 :
346 0 : s3 = butter_fly(&x0, &x1, &cospi_p16_p16); // step[12]
347 0 : s4 = butter_fly(&x0, &x1, &cospi_p16_m16); // step[11]
348 :
349 0 : u0 = _mm256_add_epi16(s0, s4); // output[8]
350 0 : u1 = _mm256_add_epi16(s1, s5);
351 0 : u2 = _mm256_sub_epi16(s1, s5);
352 0 : u3 = _mm256_sub_epi16(s0, s4);
353 0 : u4 = _mm256_sub_epi16(s7, s3);
354 0 : u5 = _mm256_sub_epi16(s6, s2);
355 0 : u6 = _mm256_add_epi16(s6, s2);
356 0 : u7 = _mm256_add_epi16(s7, s3);
357 :
358 : // stage 4
359 0 : s0 = u0;
360 0 : s3 = u3;
361 0 : s4 = u4;
362 0 : s7 = u7;
363 :
364 0 : x0 = _mm256_unpacklo_epi16(u1, u6);
365 0 : x1 = _mm256_unpackhi_epi16(u1, u6);
366 :
367 0 : s1 = butter_fly(&x0, &x1, &cospi_m08_p24);
368 0 : s6 = butter_fly(&x0, &x1, &cospi_p24_p08);
369 :
370 0 : x0 = _mm256_unpacklo_epi16(u2, u5);
371 0 : x1 = _mm256_unpackhi_epi16(u2, u5);
372 :
373 0 : s2 = butter_fly(&x0, &x1, &cospi_m24_m08);
374 0 : s5 = butter_fly(&x0, &x1, &cospi_m08_p24);
375 :
376 : // stage 5
377 0 : u0 = _mm256_add_epi16(s0, s1);
378 0 : u1 = _mm256_sub_epi16(s0, s1);
379 0 : u2 = _mm256_sub_epi16(s3, s2);
380 0 : u3 = _mm256_add_epi16(s3, s2);
381 0 : u4 = _mm256_add_epi16(s4, s5);
382 0 : u5 = _mm256_sub_epi16(s4, s5);
383 0 : u6 = _mm256_sub_epi16(s7, s6);
384 0 : u7 = _mm256_add_epi16(s7, s6);
385 :
386 : // stage 6
387 0 : x0 = _mm256_unpacklo_epi16(u0, u7);
388 0 : x1 = _mm256_unpackhi_epi16(u0, u7);
389 0 : in[1] = butter_fly(&x0, &x1, &cospi_p30_p02);
390 0 : in[15] = butter_fly(&x0, &x1, &cospi_m02_p30);
391 :
392 0 : x0 = _mm256_unpacklo_epi16(u1, u6);
393 0 : x1 = _mm256_unpackhi_epi16(u1, u6);
394 0 : in[9] = butter_fly(&x0, &x1, &cospi_p14_p18);
395 0 : in[7] = butter_fly(&x0, &x1, &cospi_m18_p14);
396 :
397 0 : x0 = _mm256_unpacklo_epi16(u2, u5);
398 0 : x1 = _mm256_unpackhi_epi16(u2, u5);
399 0 : in[5] = butter_fly(&x0, &x1, &cospi_p22_p10);
400 0 : in[11] = butter_fly(&x0, &x1, &cospi_m10_p22);
401 :
402 0 : x0 = _mm256_unpacklo_epi16(u3, u4);
403 0 : x1 = _mm256_unpackhi_epi16(u3, u4);
404 0 : in[13] = butter_fly(&x0, &x1, &cospi_p06_p26);
405 0 : in[3] = butter_fly(&x0, &x1, &cospi_m26_p06);
406 0 : }
407 :
408 0 : void fadst16_avx2(__m256i *in) {
409 0 : const __m256i cospi_p01_p31 = pair256_set_epi16(cospi_1_64, cospi_31_64);
410 0 : const __m256i cospi_p31_m01 = pair256_set_epi16(cospi_31_64, -cospi_1_64);
411 0 : const __m256i cospi_p05_p27 = pair256_set_epi16(cospi_5_64, cospi_27_64);
412 0 : const __m256i cospi_p27_m05 = pair256_set_epi16(cospi_27_64, -cospi_5_64);
413 0 : const __m256i cospi_p09_p23 = pair256_set_epi16(cospi_9_64, cospi_23_64);
414 0 : const __m256i cospi_p23_m09 = pair256_set_epi16(cospi_23_64, -cospi_9_64);
415 0 : const __m256i cospi_p13_p19 = pair256_set_epi16(cospi_13_64, cospi_19_64);
416 0 : const __m256i cospi_p19_m13 = pair256_set_epi16(cospi_19_64, -cospi_13_64);
417 0 : const __m256i cospi_p17_p15 = pair256_set_epi16(cospi_17_64, cospi_15_64);
418 0 : const __m256i cospi_p15_m17 = pair256_set_epi16(cospi_15_64, -cospi_17_64);
419 0 : const __m256i cospi_p21_p11 = pair256_set_epi16(cospi_21_64, cospi_11_64);
420 0 : const __m256i cospi_p11_m21 = pair256_set_epi16(cospi_11_64, -cospi_21_64);
421 0 : const __m256i cospi_p25_p07 = pair256_set_epi16(cospi_25_64, cospi_7_64);
422 0 : const __m256i cospi_p07_m25 = pair256_set_epi16(cospi_7_64, -cospi_25_64);
423 0 : const __m256i cospi_p29_p03 = pair256_set_epi16(cospi_29_64, cospi_3_64);
424 0 : const __m256i cospi_p03_m29 = pair256_set_epi16(cospi_3_64, -cospi_29_64);
425 0 : const __m256i cospi_p04_p28 = pair256_set_epi16(cospi_4_64, cospi_28_64);
426 0 : const __m256i cospi_p28_m04 = pair256_set_epi16(cospi_28_64, -cospi_4_64);
427 0 : const __m256i cospi_p20_p12 = pair256_set_epi16(cospi_20_64, cospi_12_64);
428 0 : const __m256i cospi_p12_m20 = pair256_set_epi16(cospi_12_64, -cospi_20_64);
429 0 : const __m256i cospi_m28_p04 = pair256_set_epi16(-cospi_28_64, cospi_4_64);
430 0 : const __m256i cospi_m12_p20 = pair256_set_epi16(-cospi_12_64, cospi_20_64);
431 0 : const __m256i cospi_p08_p24 = pair256_set_epi16(cospi_8_64, cospi_24_64);
432 0 : const __m256i cospi_p24_m08 = pair256_set_epi16(cospi_24_64, -cospi_8_64);
433 0 : const __m256i cospi_m24_p08 = pair256_set_epi16(-cospi_24_64, cospi_8_64);
434 0 : const __m256i cospi_m16_m16 = _mm256_set1_epi16((int16_t)-cospi_16_64);
435 0 : const __m256i cospi_p16_p16 = _mm256_set1_epi16((int16_t)cospi_16_64);
436 0 : const __m256i cospi_p16_m16 = pair256_set_epi16(cospi_16_64, -cospi_16_64);
437 0 : const __m256i cospi_m16_p16 = pair256_set_epi16(-cospi_16_64, cospi_16_64);
438 0 : const __m256i zero = _mm256_setzero_si256();
439 0 : const __m256i dct_rounding = _mm256_set1_epi32(DCT_CONST_ROUNDING);
440 : __m256i s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15;
441 : __m256i x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
442 : __m256i u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15;
443 : __m256i v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15;
444 : __m256i y0, y1;
445 :
446 : // stage 1, s takes low 256 bits; x takes high 256 bits
447 0 : y0 = _mm256_unpacklo_epi16(in[15], in[0]);
448 0 : y1 = _mm256_unpackhi_epi16(in[15], in[0]);
449 0 : s0 = _mm256_madd_epi16(y0, cospi_p01_p31);
450 0 : x0 = _mm256_madd_epi16(y1, cospi_p01_p31);
451 0 : s1 = _mm256_madd_epi16(y0, cospi_p31_m01);
452 0 : x1 = _mm256_madd_epi16(y1, cospi_p31_m01);
453 :
454 0 : y0 = _mm256_unpacklo_epi16(in[13], in[2]);
455 0 : y1 = _mm256_unpackhi_epi16(in[13], in[2]);
456 0 : s2 = _mm256_madd_epi16(y0, cospi_p05_p27);
457 0 : x2 = _mm256_madd_epi16(y1, cospi_p05_p27);
458 0 : s3 = _mm256_madd_epi16(y0, cospi_p27_m05);
459 0 : x3 = _mm256_madd_epi16(y1, cospi_p27_m05);
460 :
461 0 : y0 = _mm256_unpacklo_epi16(in[11], in[4]);
462 0 : y1 = _mm256_unpackhi_epi16(in[11], in[4]);
463 0 : s4 = _mm256_madd_epi16(y0, cospi_p09_p23);
464 0 : x4 = _mm256_madd_epi16(y1, cospi_p09_p23);
465 0 : s5 = _mm256_madd_epi16(y0, cospi_p23_m09);
466 0 : x5 = _mm256_madd_epi16(y1, cospi_p23_m09);
467 :
468 0 : y0 = _mm256_unpacklo_epi16(in[9], in[6]);
469 0 : y1 = _mm256_unpackhi_epi16(in[9], in[6]);
470 0 : s6 = _mm256_madd_epi16(y0, cospi_p13_p19);
471 0 : x6 = _mm256_madd_epi16(y1, cospi_p13_p19);
472 0 : s7 = _mm256_madd_epi16(y0, cospi_p19_m13);
473 0 : x7 = _mm256_madd_epi16(y1, cospi_p19_m13);
474 :
475 0 : y0 = _mm256_unpacklo_epi16(in[7], in[8]);
476 0 : y1 = _mm256_unpackhi_epi16(in[7], in[8]);
477 0 : s8 = _mm256_madd_epi16(y0, cospi_p17_p15);
478 0 : x8 = _mm256_madd_epi16(y1, cospi_p17_p15);
479 0 : s9 = _mm256_madd_epi16(y0, cospi_p15_m17);
480 0 : x9 = _mm256_madd_epi16(y1, cospi_p15_m17);
481 :
482 0 : y0 = _mm256_unpacklo_epi16(in[5], in[10]);
483 0 : y1 = _mm256_unpackhi_epi16(in[5], in[10]);
484 0 : s10 = _mm256_madd_epi16(y0, cospi_p21_p11);
485 0 : x10 = _mm256_madd_epi16(y1, cospi_p21_p11);
486 0 : s11 = _mm256_madd_epi16(y0, cospi_p11_m21);
487 0 : x11 = _mm256_madd_epi16(y1, cospi_p11_m21);
488 :
489 0 : y0 = _mm256_unpacklo_epi16(in[3], in[12]);
490 0 : y1 = _mm256_unpackhi_epi16(in[3], in[12]);
491 0 : s12 = _mm256_madd_epi16(y0, cospi_p25_p07);
492 0 : x12 = _mm256_madd_epi16(y1, cospi_p25_p07);
493 0 : s13 = _mm256_madd_epi16(y0, cospi_p07_m25);
494 0 : x13 = _mm256_madd_epi16(y1, cospi_p07_m25);
495 :
496 0 : y0 = _mm256_unpacklo_epi16(in[1], in[14]);
497 0 : y1 = _mm256_unpackhi_epi16(in[1], in[14]);
498 0 : s14 = _mm256_madd_epi16(y0, cospi_p29_p03);
499 0 : x14 = _mm256_madd_epi16(y1, cospi_p29_p03);
500 0 : s15 = _mm256_madd_epi16(y0, cospi_p03_m29);
501 0 : x15 = _mm256_madd_epi16(y1, cospi_p03_m29);
502 :
503 : // u takes low 256 bits; v takes high 256 bits
504 0 : u0 = _mm256_add_epi32(s0, s8);
505 0 : u1 = _mm256_add_epi32(s1, s9);
506 0 : u2 = _mm256_add_epi32(s2, s10);
507 0 : u3 = _mm256_add_epi32(s3, s11);
508 0 : u4 = _mm256_add_epi32(s4, s12);
509 0 : u5 = _mm256_add_epi32(s5, s13);
510 0 : u6 = _mm256_add_epi32(s6, s14);
511 0 : u7 = _mm256_add_epi32(s7, s15);
512 :
513 0 : u8 = _mm256_sub_epi32(s0, s8);
514 0 : u9 = _mm256_sub_epi32(s1, s9);
515 0 : u10 = _mm256_sub_epi32(s2, s10);
516 0 : u11 = _mm256_sub_epi32(s3, s11);
517 0 : u12 = _mm256_sub_epi32(s4, s12);
518 0 : u13 = _mm256_sub_epi32(s5, s13);
519 0 : u14 = _mm256_sub_epi32(s6, s14);
520 0 : u15 = _mm256_sub_epi32(s7, s15);
521 :
522 0 : v0 = _mm256_add_epi32(x0, x8);
523 0 : v1 = _mm256_add_epi32(x1, x9);
524 0 : v2 = _mm256_add_epi32(x2, x10);
525 0 : v3 = _mm256_add_epi32(x3, x11);
526 0 : v4 = _mm256_add_epi32(x4, x12);
527 0 : v5 = _mm256_add_epi32(x5, x13);
528 0 : v6 = _mm256_add_epi32(x6, x14);
529 0 : v7 = _mm256_add_epi32(x7, x15);
530 :
531 0 : v8 = _mm256_sub_epi32(x0, x8);
532 0 : v9 = _mm256_sub_epi32(x1, x9);
533 0 : v10 = _mm256_sub_epi32(x2, x10);
534 0 : v11 = _mm256_sub_epi32(x3, x11);
535 0 : v12 = _mm256_sub_epi32(x4, x12);
536 0 : v13 = _mm256_sub_epi32(x5, x13);
537 0 : v14 = _mm256_sub_epi32(x6, x14);
538 0 : v15 = _mm256_sub_epi32(x7, x15);
539 :
540 : // low 256 bits rounding
541 0 : u8 = _mm256_add_epi32(u8, dct_rounding);
542 0 : u9 = _mm256_add_epi32(u9, dct_rounding);
543 0 : u10 = _mm256_add_epi32(u10, dct_rounding);
544 0 : u11 = _mm256_add_epi32(u11, dct_rounding);
545 0 : u12 = _mm256_add_epi32(u12, dct_rounding);
546 0 : u13 = _mm256_add_epi32(u13, dct_rounding);
547 0 : u14 = _mm256_add_epi32(u14, dct_rounding);
548 0 : u15 = _mm256_add_epi32(u15, dct_rounding);
549 :
550 0 : u8 = _mm256_srai_epi32(u8, DCT_CONST_BITS);
551 0 : u9 = _mm256_srai_epi32(u9, DCT_CONST_BITS);
552 0 : u10 = _mm256_srai_epi32(u10, DCT_CONST_BITS);
553 0 : u11 = _mm256_srai_epi32(u11, DCT_CONST_BITS);
554 0 : u12 = _mm256_srai_epi32(u12, DCT_CONST_BITS);
555 0 : u13 = _mm256_srai_epi32(u13, DCT_CONST_BITS);
556 0 : u14 = _mm256_srai_epi32(u14, DCT_CONST_BITS);
557 0 : u15 = _mm256_srai_epi32(u15, DCT_CONST_BITS);
558 :
559 : // high 256 bits rounding
560 0 : v8 = _mm256_add_epi32(v8, dct_rounding);
561 0 : v9 = _mm256_add_epi32(v9, dct_rounding);
562 0 : v10 = _mm256_add_epi32(v10, dct_rounding);
563 0 : v11 = _mm256_add_epi32(v11, dct_rounding);
564 0 : v12 = _mm256_add_epi32(v12, dct_rounding);
565 0 : v13 = _mm256_add_epi32(v13, dct_rounding);
566 0 : v14 = _mm256_add_epi32(v14, dct_rounding);
567 0 : v15 = _mm256_add_epi32(v15, dct_rounding);
568 :
569 0 : v8 = _mm256_srai_epi32(v8, DCT_CONST_BITS);
570 0 : v9 = _mm256_srai_epi32(v9, DCT_CONST_BITS);
571 0 : v10 = _mm256_srai_epi32(v10, DCT_CONST_BITS);
572 0 : v11 = _mm256_srai_epi32(v11, DCT_CONST_BITS);
573 0 : v12 = _mm256_srai_epi32(v12, DCT_CONST_BITS);
574 0 : v13 = _mm256_srai_epi32(v13, DCT_CONST_BITS);
575 0 : v14 = _mm256_srai_epi32(v14, DCT_CONST_BITS);
576 0 : v15 = _mm256_srai_epi32(v15, DCT_CONST_BITS);
577 :
578 : // Saturation pack 32-bit to 16-bit
579 0 : x8 = _mm256_packs_epi32(u8, v8);
580 0 : x9 = _mm256_packs_epi32(u9, v9);
581 0 : x10 = _mm256_packs_epi32(u10, v10);
582 0 : x11 = _mm256_packs_epi32(u11, v11);
583 0 : x12 = _mm256_packs_epi32(u12, v12);
584 0 : x13 = _mm256_packs_epi32(u13, v13);
585 0 : x14 = _mm256_packs_epi32(u14, v14);
586 0 : x15 = _mm256_packs_epi32(u15, v15);
587 :
588 : // stage 2
589 0 : y0 = _mm256_unpacklo_epi16(x8, x9);
590 0 : y1 = _mm256_unpackhi_epi16(x8, x9);
591 0 : s8 = _mm256_madd_epi16(y0, cospi_p04_p28);
592 0 : x8 = _mm256_madd_epi16(y1, cospi_p04_p28);
593 0 : s9 = _mm256_madd_epi16(y0, cospi_p28_m04);
594 0 : x9 = _mm256_madd_epi16(y1, cospi_p28_m04);
595 :
596 0 : y0 = _mm256_unpacklo_epi16(x10, x11);
597 0 : y1 = _mm256_unpackhi_epi16(x10, x11);
598 0 : s10 = _mm256_madd_epi16(y0, cospi_p20_p12);
599 0 : x10 = _mm256_madd_epi16(y1, cospi_p20_p12);
600 0 : s11 = _mm256_madd_epi16(y0, cospi_p12_m20);
601 0 : x11 = _mm256_madd_epi16(y1, cospi_p12_m20);
602 :
603 0 : y0 = _mm256_unpacklo_epi16(x12, x13);
604 0 : y1 = _mm256_unpackhi_epi16(x12, x13);
605 0 : s12 = _mm256_madd_epi16(y0, cospi_m28_p04);
606 0 : x12 = _mm256_madd_epi16(y1, cospi_m28_p04);
607 0 : s13 = _mm256_madd_epi16(y0, cospi_p04_p28);
608 0 : x13 = _mm256_madd_epi16(y1, cospi_p04_p28);
609 :
610 0 : y0 = _mm256_unpacklo_epi16(x14, x15);
611 0 : y1 = _mm256_unpackhi_epi16(x14, x15);
612 0 : s14 = _mm256_madd_epi16(y0, cospi_m12_p20);
613 0 : x14 = _mm256_madd_epi16(y1, cospi_m12_p20);
614 0 : s15 = _mm256_madd_epi16(y0, cospi_p20_p12);
615 0 : x15 = _mm256_madd_epi16(y1, cospi_p20_p12);
616 :
617 0 : x0 = _mm256_add_epi32(u0, u4);
618 0 : s0 = _mm256_add_epi32(v0, v4);
619 0 : x1 = _mm256_add_epi32(u1, u5);
620 0 : s1 = _mm256_add_epi32(v1, v5);
621 0 : x2 = _mm256_add_epi32(u2, u6);
622 0 : s2 = _mm256_add_epi32(v2, v6);
623 0 : x3 = _mm256_add_epi32(u3, u7);
624 0 : s3 = _mm256_add_epi32(v3, v7);
625 :
626 0 : v8 = _mm256_sub_epi32(u0, u4);
627 0 : v9 = _mm256_sub_epi32(v0, v4);
628 0 : v10 = _mm256_sub_epi32(u1, u5);
629 0 : v11 = _mm256_sub_epi32(v1, v5);
630 0 : v12 = _mm256_sub_epi32(u2, u6);
631 0 : v13 = _mm256_sub_epi32(v2, v6);
632 0 : v14 = _mm256_sub_epi32(u3, u7);
633 0 : v15 = _mm256_sub_epi32(v3, v7);
634 :
635 0 : v8 = _mm256_add_epi32(v8, dct_rounding);
636 0 : v9 = _mm256_add_epi32(v9, dct_rounding);
637 0 : v10 = _mm256_add_epi32(v10, dct_rounding);
638 0 : v11 = _mm256_add_epi32(v11, dct_rounding);
639 0 : v12 = _mm256_add_epi32(v12, dct_rounding);
640 0 : v13 = _mm256_add_epi32(v13, dct_rounding);
641 0 : v14 = _mm256_add_epi32(v14, dct_rounding);
642 0 : v15 = _mm256_add_epi32(v15, dct_rounding);
643 :
644 0 : v8 = _mm256_srai_epi32(v8, DCT_CONST_BITS);
645 0 : v9 = _mm256_srai_epi32(v9, DCT_CONST_BITS);
646 0 : v10 = _mm256_srai_epi32(v10, DCT_CONST_BITS);
647 0 : v11 = _mm256_srai_epi32(v11, DCT_CONST_BITS);
648 0 : v12 = _mm256_srai_epi32(v12, DCT_CONST_BITS);
649 0 : v13 = _mm256_srai_epi32(v13, DCT_CONST_BITS);
650 0 : v14 = _mm256_srai_epi32(v14, DCT_CONST_BITS);
651 0 : v15 = _mm256_srai_epi32(v15, DCT_CONST_BITS);
652 :
653 0 : x4 = _mm256_packs_epi32(v8, v9);
654 0 : x5 = _mm256_packs_epi32(v10, v11);
655 0 : x6 = _mm256_packs_epi32(v12, v13);
656 0 : x7 = _mm256_packs_epi32(v14, v15);
657 :
658 0 : u8 = _mm256_add_epi32(s8, s12);
659 0 : u9 = _mm256_add_epi32(s9, s13);
660 0 : u10 = _mm256_add_epi32(s10, s14);
661 0 : u11 = _mm256_add_epi32(s11, s15);
662 0 : u12 = _mm256_sub_epi32(s8, s12);
663 0 : u13 = _mm256_sub_epi32(s9, s13);
664 0 : u14 = _mm256_sub_epi32(s10, s14);
665 0 : u15 = _mm256_sub_epi32(s11, s15);
666 :
667 0 : v8 = _mm256_add_epi32(x8, x12);
668 0 : v9 = _mm256_add_epi32(x9, x13);
669 0 : v10 = _mm256_add_epi32(x10, x14);
670 0 : v11 = _mm256_add_epi32(x11, x15);
671 0 : v12 = _mm256_sub_epi32(x8, x12);
672 0 : v13 = _mm256_sub_epi32(x9, x13);
673 0 : v14 = _mm256_sub_epi32(x10, x14);
674 0 : v15 = _mm256_sub_epi32(x11, x15);
675 :
676 0 : u12 = _mm256_add_epi32(u12, dct_rounding);
677 0 : u13 = _mm256_add_epi32(u13, dct_rounding);
678 0 : u14 = _mm256_add_epi32(u14, dct_rounding);
679 0 : u15 = _mm256_add_epi32(u15, dct_rounding);
680 :
681 0 : u12 = _mm256_srai_epi32(u12, DCT_CONST_BITS);
682 0 : u13 = _mm256_srai_epi32(u13, DCT_CONST_BITS);
683 0 : u14 = _mm256_srai_epi32(u14, DCT_CONST_BITS);
684 0 : u15 = _mm256_srai_epi32(u15, DCT_CONST_BITS);
685 :
686 0 : v12 = _mm256_add_epi32(v12, dct_rounding);
687 0 : v13 = _mm256_add_epi32(v13, dct_rounding);
688 0 : v14 = _mm256_add_epi32(v14, dct_rounding);
689 0 : v15 = _mm256_add_epi32(v15, dct_rounding);
690 :
691 0 : v12 = _mm256_srai_epi32(v12, DCT_CONST_BITS);
692 0 : v13 = _mm256_srai_epi32(v13, DCT_CONST_BITS);
693 0 : v14 = _mm256_srai_epi32(v14, DCT_CONST_BITS);
694 0 : v15 = _mm256_srai_epi32(v15, DCT_CONST_BITS);
695 :
696 0 : x12 = _mm256_packs_epi32(u12, v12);
697 0 : x13 = _mm256_packs_epi32(u13, v13);
698 0 : x14 = _mm256_packs_epi32(u14, v14);
699 0 : x15 = _mm256_packs_epi32(u15, v15);
700 :
701 : // stage 3
702 0 : y0 = _mm256_unpacklo_epi16(x4, x5);
703 0 : y1 = _mm256_unpackhi_epi16(x4, x5);
704 0 : s4 = _mm256_madd_epi16(y0, cospi_p08_p24);
705 0 : x4 = _mm256_madd_epi16(y1, cospi_p08_p24);
706 0 : s5 = _mm256_madd_epi16(y0, cospi_p24_m08);
707 0 : x5 = _mm256_madd_epi16(y1, cospi_p24_m08);
708 :
709 0 : y0 = _mm256_unpacklo_epi16(x6, x7);
710 0 : y1 = _mm256_unpackhi_epi16(x6, x7);
711 0 : s6 = _mm256_madd_epi16(y0, cospi_m24_p08);
712 0 : x6 = _mm256_madd_epi16(y1, cospi_m24_p08);
713 0 : s7 = _mm256_madd_epi16(y0, cospi_p08_p24);
714 0 : x7 = _mm256_madd_epi16(y1, cospi_p08_p24);
715 :
716 0 : y0 = _mm256_unpacklo_epi16(x12, x13);
717 0 : y1 = _mm256_unpackhi_epi16(x12, x13);
718 0 : s12 = _mm256_madd_epi16(y0, cospi_p08_p24);
719 0 : x12 = _mm256_madd_epi16(y1, cospi_p08_p24);
720 0 : s13 = _mm256_madd_epi16(y0, cospi_p24_m08);
721 0 : x13 = _mm256_madd_epi16(y1, cospi_p24_m08);
722 :
723 0 : y0 = _mm256_unpacklo_epi16(x14, x15);
724 0 : y1 = _mm256_unpackhi_epi16(x14, x15);
725 0 : s14 = _mm256_madd_epi16(y0, cospi_m24_p08);
726 0 : x14 = _mm256_madd_epi16(y1, cospi_m24_p08);
727 0 : s15 = _mm256_madd_epi16(y0, cospi_p08_p24);
728 0 : x15 = _mm256_madd_epi16(y1, cospi_p08_p24);
729 :
730 0 : u0 = _mm256_add_epi32(x0, x2);
731 0 : v0 = _mm256_add_epi32(s0, s2);
732 0 : u1 = _mm256_add_epi32(x1, x3);
733 0 : v1 = _mm256_add_epi32(s1, s3);
734 0 : u2 = _mm256_sub_epi32(x0, x2);
735 0 : v2 = _mm256_sub_epi32(s0, s2);
736 0 : u3 = _mm256_sub_epi32(x1, x3);
737 0 : v3 = _mm256_sub_epi32(s1, s3);
738 :
739 0 : u0 = _mm256_add_epi32(u0, dct_rounding);
740 0 : v0 = _mm256_add_epi32(v0, dct_rounding);
741 0 : u1 = _mm256_add_epi32(u1, dct_rounding);
742 0 : v1 = _mm256_add_epi32(v1, dct_rounding);
743 0 : u2 = _mm256_add_epi32(u2, dct_rounding);
744 0 : v2 = _mm256_add_epi32(v2, dct_rounding);
745 0 : u3 = _mm256_add_epi32(u3, dct_rounding);
746 0 : v3 = _mm256_add_epi32(v3, dct_rounding);
747 :
748 0 : u0 = _mm256_srai_epi32(u0, DCT_CONST_BITS);
749 0 : v0 = _mm256_srai_epi32(v0, DCT_CONST_BITS);
750 0 : u1 = _mm256_srai_epi32(u1, DCT_CONST_BITS);
751 0 : v1 = _mm256_srai_epi32(v1, DCT_CONST_BITS);
752 0 : u2 = _mm256_srai_epi32(u2, DCT_CONST_BITS);
753 0 : v2 = _mm256_srai_epi32(v2, DCT_CONST_BITS);
754 0 : u3 = _mm256_srai_epi32(u3, DCT_CONST_BITS);
755 0 : v3 = _mm256_srai_epi32(v3, DCT_CONST_BITS);
756 :
757 0 : in[0] = _mm256_packs_epi32(u0, v0);
758 0 : x1 = _mm256_packs_epi32(u1, v1);
759 0 : x2 = _mm256_packs_epi32(u2, v2);
760 0 : x3 = _mm256_packs_epi32(u3, v3);
761 :
762 : // Rounding on s4 + s6, s5 + s7, s4 - s6, s5 - s7
763 0 : u4 = _mm256_add_epi32(s4, s6);
764 0 : u5 = _mm256_add_epi32(s5, s7);
765 0 : u6 = _mm256_sub_epi32(s4, s6);
766 0 : u7 = _mm256_sub_epi32(s5, s7);
767 :
768 0 : v4 = _mm256_add_epi32(x4, x6);
769 0 : v5 = _mm256_add_epi32(x5, x7);
770 0 : v6 = _mm256_sub_epi32(x4, x6);
771 0 : v7 = _mm256_sub_epi32(x5, x7);
772 :
773 0 : u4 = _mm256_add_epi32(u4, dct_rounding);
774 0 : u5 = _mm256_add_epi32(u5, dct_rounding);
775 0 : u6 = _mm256_add_epi32(u6, dct_rounding);
776 0 : u7 = _mm256_add_epi32(u7, dct_rounding);
777 :
778 0 : u4 = _mm256_srai_epi32(u4, DCT_CONST_BITS);
779 0 : u5 = _mm256_srai_epi32(u5, DCT_CONST_BITS);
780 0 : u6 = _mm256_srai_epi32(u6, DCT_CONST_BITS);
781 0 : u7 = _mm256_srai_epi32(u7, DCT_CONST_BITS);
782 :
783 0 : v4 = _mm256_add_epi32(v4, dct_rounding);
784 0 : v5 = _mm256_add_epi32(v5, dct_rounding);
785 0 : v6 = _mm256_add_epi32(v6, dct_rounding);
786 0 : v7 = _mm256_add_epi32(v7, dct_rounding);
787 :
788 0 : v4 = _mm256_srai_epi32(v4, DCT_CONST_BITS);
789 0 : v5 = _mm256_srai_epi32(v5, DCT_CONST_BITS);
790 0 : v6 = _mm256_srai_epi32(v6, DCT_CONST_BITS);
791 0 : v7 = _mm256_srai_epi32(v7, DCT_CONST_BITS);
792 :
793 0 : x4 = _mm256_packs_epi32(u4, v4);
794 0 : in[12] = _mm256_packs_epi32(u5, v5);
795 0 : x6 = _mm256_packs_epi32(u6, v6);
796 0 : x7 = _mm256_packs_epi32(u7, v7);
797 :
798 0 : u0 = _mm256_add_epi32(u8, u10);
799 0 : v0 = _mm256_add_epi32(v8, v10);
800 0 : u1 = _mm256_add_epi32(u9, u11);
801 0 : v1 = _mm256_add_epi32(v9, v11);
802 0 : u2 = _mm256_sub_epi32(u8, u10);
803 0 : v2 = _mm256_sub_epi32(v8, v10);
804 0 : u3 = _mm256_sub_epi32(u9, u11);
805 0 : v3 = _mm256_sub_epi32(v9, v11);
806 :
807 0 : u0 = _mm256_add_epi32(u0, dct_rounding);
808 0 : v0 = _mm256_add_epi32(v0, dct_rounding);
809 0 : u1 = _mm256_add_epi32(u1, dct_rounding);
810 0 : v1 = _mm256_add_epi32(v1, dct_rounding);
811 0 : u2 = _mm256_add_epi32(u2, dct_rounding);
812 0 : v2 = _mm256_add_epi32(v2, dct_rounding);
813 0 : u3 = _mm256_add_epi32(u3, dct_rounding);
814 0 : v3 = _mm256_add_epi32(v3, dct_rounding);
815 :
816 0 : u0 = _mm256_srai_epi32(u0, DCT_CONST_BITS);
817 0 : v0 = _mm256_srai_epi32(v0, DCT_CONST_BITS);
818 0 : u1 = _mm256_srai_epi32(u1, DCT_CONST_BITS);
819 0 : v1 = _mm256_srai_epi32(v1, DCT_CONST_BITS);
820 0 : u2 = _mm256_srai_epi32(u2, DCT_CONST_BITS);
821 0 : v2 = _mm256_srai_epi32(v2, DCT_CONST_BITS);
822 0 : u3 = _mm256_srai_epi32(u3, DCT_CONST_BITS);
823 0 : v3 = _mm256_srai_epi32(v3, DCT_CONST_BITS);
824 :
825 0 : x8 = _mm256_packs_epi32(u0, v0);
826 0 : in[14] = _mm256_packs_epi32(u1, v1);
827 0 : x10 = _mm256_packs_epi32(u2, v2);
828 0 : x11 = _mm256_packs_epi32(u3, v3);
829 :
830 : // Rounding on s12 + s14, s13 + s15, s12 - s14, s13 - s15
831 0 : u12 = _mm256_add_epi32(s12, s14);
832 0 : u13 = _mm256_add_epi32(s13, s15);
833 0 : u14 = _mm256_sub_epi32(s12, s14);
834 0 : u15 = _mm256_sub_epi32(s13, s15);
835 :
836 0 : v12 = _mm256_add_epi32(x12, x14);
837 0 : v13 = _mm256_add_epi32(x13, x15);
838 0 : v14 = _mm256_sub_epi32(x12, x14);
839 0 : v15 = _mm256_sub_epi32(x13, x15);
840 :
841 0 : u12 = _mm256_add_epi32(u12, dct_rounding);
842 0 : u13 = _mm256_add_epi32(u13, dct_rounding);
843 0 : u14 = _mm256_add_epi32(u14, dct_rounding);
844 0 : u15 = _mm256_add_epi32(u15, dct_rounding);
845 :
846 0 : u12 = _mm256_srai_epi32(u12, DCT_CONST_BITS);
847 0 : u13 = _mm256_srai_epi32(u13, DCT_CONST_BITS);
848 0 : u14 = _mm256_srai_epi32(u14, DCT_CONST_BITS);
849 0 : u15 = _mm256_srai_epi32(u15, DCT_CONST_BITS);
850 :
851 0 : v12 = _mm256_add_epi32(v12, dct_rounding);
852 0 : v13 = _mm256_add_epi32(v13, dct_rounding);
853 0 : v14 = _mm256_add_epi32(v14, dct_rounding);
854 0 : v15 = _mm256_add_epi32(v15, dct_rounding);
855 :
856 0 : v12 = _mm256_srai_epi32(v12, DCT_CONST_BITS);
857 0 : v13 = _mm256_srai_epi32(v13, DCT_CONST_BITS);
858 0 : v14 = _mm256_srai_epi32(v14, DCT_CONST_BITS);
859 0 : v15 = _mm256_srai_epi32(v15, DCT_CONST_BITS);
860 :
861 0 : x12 = _mm256_packs_epi32(u12, v12);
862 0 : x13 = _mm256_packs_epi32(u13, v13);
863 0 : x14 = _mm256_packs_epi32(u14, v14);
864 0 : x15 = _mm256_packs_epi32(u15, v15);
865 0 : in[2] = x12;
866 :
867 : // stage 4
868 0 : y0 = _mm256_unpacklo_epi16(x2, x3);
869 0 : y1 = _mm256_unpackhi_epi16(x2, x3);
870 0 : s2 = _mm256_madd_epi16(y0, cospi_m16_m16);
871 0 : x2 = _mm256_madd_epi16(y1, cospi_m16_m16);
872 0 : s3 = _mm256_madd_epi16(y0, cospi_p16_m16);
873 0 : x3 = _mm256_madd_epi16(y1, cospi_p16_m16);
874 :
875 0 : y0 = _mm256_unpacklo_epi16(x6, x7);
876 0 : y1 = _mm256_unpackhi_epi16(x6, x7);
877 0 : s6 = _mm256_madd_epi16(y0, cospi_p16_p16);
878 0 : x6 = _mm256_madd_epi16(y1, cospi_p16_p16);
879 0 : s7 = _mm256_madd_epi16(y0, cospi_m16_p16);
880 0 : x7 = _mm256_madd_epi16(y1, cospi_m16_p16);
881 :
882 0 : y0 = _mm256_unpacklo_epi16(x10, x11);
883 0 : y1 = _mm256_unpackhi_epi16(x10, x11);
884 0 : s10 = _mm256_madd_epi16(y0, cospi_p16_p16);
885 0 : x10 = _mm256_madd_epi16(y1, cospi_p16_p16);
886 0 : s11 = _mm256_madd_epi16(y0, cospi_m16_p16);
887 0 : x11 = _mm256_madd_epi16(y1, cospi_m16_p16);
888 :
889 0 : y0 = _mm256_unpacklo_epi16(x14, x15);
890 0 : y1 = _mm256_unpackhi_epi16(x14, x15);
891 0 : s14 = _mm256_madd_epi16(y0, cospi_m16_m16);
892 0 : x14 = _mm256_madd_epi16(y1, cospi_m16_m16);
893 0 : s15 = _mm256_madd_epi16(y0, cospi_p16_m16);
894 0 : x15 = _mm256_madd_epi16(y1, cospi_p16_m16);
895 :
896 : // Rounding
897 0 : u2 = _mm256_add_epi32(s2, dct_rounding);
898 0 : u3 = _mm256_add_epi32(s3, dct_rounding);
899 0 : u6 = _mm256_add_epi32(s6, dct_rounding);
900 0 : u7 = _mm256_add_epi32(s7, dct_rounding);
901 :
902 0 : u10 = _mm256_add_epi32(s10, dct_rounding);
903 0 : u11 = _mm256_add_epi32(s11, dct_rounding);
904 0 : u14 = _mm256_add_epi32(s14, dct_rounding);
905 0 : u15 = _mm256_add_epi32(s15, dct_rounding);
906 :
907 0 : u2 = _mm256_srai_epi32(u2, DCT_CONST_BITS);
908 0 : u3 = _mm256_srai_epi32(u3, DCT_CONST_BITS);
909 0 : u6 = _mm256_srai_epi32(u6, DCT_CONST_BITS);
910 0 : u7 = _mm256_srai_epi32(u7, DCT_CONST_BITS);
911 :
912 0 : u10 = _mm256_srai_epi32(u10, DCT_CONST_BITS);
913 0 : u11 = _mm256_srai_epi32(u11, DCT_CONST_BITS);
914 0 : u14 = _mm256_srai_epi32(u14, DCT_CONST_BITS);
915 0 : u15 = _mm256_srai_epi32(u15, DCT_CONST_BITS);
916 :
917 0 : v2 = _mm256_add_epi32(x2, dct_rounding);
918 0 : v3 = _mm256_add_epi32(x3, dct_rounding);
919 0 : v6 = _mm256_add_epi32(x6, dct_rounding);
920 0 : v7 = _mm256_add_epi32(x7, dct_rounding);
921 :
922 0 : v10 = _mm256_add_epi32(x10, dct_rounding);
923 0 : v11 = _mm256_add_epi32(x11, dct_rounding);
924 0 : v14 = _mm256_add_epi32(x14, dct_rounding);
925 0 : v15 = _mm256_add_epi32(x15, dct_rounding);
926 :
927 0 : v2 = _mm256_srai_epi32(v2, DCT_CONST_BITS);
928 0 : v3 = _mm256_srai_epi32(v3, DCT_CONST_BITS);
929 0 : v6 = _mm256_srai_epi32(v6, DCT_CONST_BITS);
930 0 : v7 = _mm256_srai_epi32(v7, DCT_CONST_BITS);
931 :
932 0 : v10 = _mm256_srai_epi32(v10, DCT_CONST_BITS);
933 0 : v11 = _mm256_srai_epi32(v11, DCT_CONST_BITS);
934 0 : v14 = _mm256_srai_epi32(v14, DCT_CONST_BITS);
935 0 : v15 = _mm256_srai_epi32(v15, DCT_CONST_BITS);
936 :
937 0 : in[7] = _mm256_packs_epi32(u2, v2);
938 0 : in[8] = _mm256_packs_epi32(u3, v3);
939 :
940 0 : in[4] = _mm256_packs_epi32(u6, v6);
941 0 : in[11] = _mm256_packs_epi32(u7, v7);
942 :
943 0 : in[6] = _mm256_packs_epi32(u10, v10);
944 0 : in[9] = _mm256_packs_epi32(u11, v11);
945 :
946 0 : in[5] = _mm256_packs_epi32(u14, v14);
947 0 : in[10] = _mm256_packs_epi32(u15, v15);
948 :
949 0 : in[1] = _mm256_sub_epi16(zero, x8);
950 0 : in[3] = _mm256_sub_epi16(zero, x4);
951 0 : in[13] = _mm256_sub_epi16(zero, x13);
952 0 : in[15] = _mm256_sub_epi16(zero, x1);
953 0 : }
954 :
955 : #if CONFIG_EXT_TX
956 0 : static void fidtx16_avx2(__m256i *in) {
957 0 : txfm_scaling16_avx2((int16_t)Sqrt2, in);
958 0 : }
959 : #endif
960 :
961 0 : void av1_fht16x16_avx2(const int16_t *input, tran_low_t *output, int stride,
962 : int tx_type) {
963 : __m256i in[16];
964 :
965 0 : switch (tx_type) {
966 : case DCT_DCT:
967 0 : load_buffer_16x16(input, stride, 0, 0, in);
968 0 : fdct16_avx2(in);
969 0 : mm256_transpose_16x16(in, in);
970 0 : right_shift_16x16(in);
971 0 : fdct16_avx2(in);
972 0 : break;
973 : case ADST_DCT:
974 0 : load_buffer_16x16(input, stride, 0, 0, in);
975 0 : fadst16_avx2(in);
976 0 : mm256_transpose_16x16(in, in);
977 0 : right_shift_16x16(in);
978 0 : fdct16_avx2(in);
979 0 : break;
980 : case DCT_ADST:
981 0 : load_buffer_16x16(input, stride, 0, 0, in);
982 0 : fdct16_avx2(in);
983 0 : mm256_transpose_16x16(in, in);
984 0 : right_shift_16x16(in);
985 0 : fadst16_avx2(in);
986 0 : break;
987 : case ADST_ADST:
988 0 : load_buffer_16x16(input, stride, 0, 0, in);
989 0 : fadst16_avx2(in);
990 0 : mm256_transpose_16x16(in, in);
991 0 : right_shift_16x16(in);
992 0 : fadst16_avx2(in);
993 0 : break;
994 : #if CONFIG_EXT_TX
995 : case FLIPADST_DCT:
996 0 : load_buffer_16x16(input, stride, 1, 0, in);
997 0 : fadst16_avx2(in);
998 0 : mm256_transpose_16x16(in, in);
999 0 : right_shift_16x16(in);
1000 0 : fdct16_avx2(in);
1001 0 : break;
1002 : case DCT_FLIPADST:
1003 0 : load_buffer_16x16(input, stride, 0, 1, in);
1004 0 : fdct16_avx2(in);
1005 0 : mm256_transpose_16x16(in, in);
1006 0 : right_shift_16x16(in);
1007 0 : fadst16_avx2(in);
1008 0 : break;
1009 : case FLIPADST_FLIPADST:
1010 0 : load_buffer_16x16(input, stride, 1, 1, in);
1011 0 : fadst16_avx2(in);
1012 0 : mm256_transpose_16x16(in, in);
1013 0 : right_shift_16x16(in);
1014 0 : fadst16_avx2(in);
1015 0 : break;
1016 : case ADST_FLIPADST:
1017 0 : load_buffer_16x16(input, stride, 0, 1, in);
1018 0 : fadst16_avx2(in);
1019 0 : mm256_transpose_16x16(in, in);
1020 0 : right_shift_16x16(in);
1021 0 : fadst16_avx2(in);
1022 0 : break;
1023 : case FLIPADST_ADST:
1024 0 : load_buffer_16x16(input, stride, 1, 0, in);
1025 0 : fadst16_avx2(in);
1026 0 : mm256_transpose_16x16(in, in);
1027 0 : right_shift_16x16(in);
1028 0 : fadst16_avx2(in);
1029 0 : break;
1030 : case IDTX:
1031 0 : load_buffer_16x16(input, stride, 0, 0, in);
1032 0 : fidtx16_avx2(in);
1033 0 : mm256_transpose_16x16(in, in);
1034 0 : right_shift_16x16(in);
1035 0 : fidtx16_avx2(in);
1036 0 : break;
1037 : case V_DCT:
1038 0 : load_buffer_16x16(input, stride, 0, 0, in);
1039 0 : fdct16_avx2(in);
1040 0 : mm256_transpose_16x16(in, in);
1041 0 : right_shift_16x16(in);
1042 0 : fidtx16_avx2(in);
1043 0 : break;
1044 : case H_DCT:
1045 0 : load_buffer_16x16(input, stride, 0, 0, in);
1046 0 : fidtx16_avx2(in);
1047 0 : mm256_transpose_16x16(in, in);
1048 0 : right_shift_16x16(in);
1049 0 : fdct16_avx2(in);
1050 0 : break;
1051 : case V_ADST:
1052 0 : load_buffer_16x16(input, stride, 0, 0, in);
1053 0 : fadst16_avx2(in);
1054 0 : mm256_transpose_16x16(in, in);
1055 0 : right_shift_16x16(in);
1056 0 : fidtx16_avx2(in);
1057 0 : break;
1058 : case H_ADST:
1059 0 : load_buffer_16x16(input, stride, 0, 0, in);
1060 0 : fidtx16_avx2(in);
1061 0 : mm256_transpose_16x16(in, in);
1062 0 : right_shift_16x16(in);
1063 0 : fadst16_avx2(in);
1064 0 : break;
1065 : case V_FLIPADST:
1066 0 : load_buffer_16x16(input, stride, 1, 0, in);
1067 0 : fadst16_avx2(in);
1068 0 : mm256_transpose_16x16(in, in);
1069 0 : right_shift_16x16(in);
1070 0 : fidtx16_avx2(in);
1071 0 : break;
1072 : case H_FLIPADST:
1073 0 : load_buffer_16x16(input, stride, 0, 1, in);
1074 0 : fidtx16_avx2(in);
1075 0 : mm256_transpose_16x16(in, in);
1076 0 : right_shift_16x16(in);
1077 0 : fadst16_avx2(in);
1078 0 : break;
1079 : #endif // CONFIG_EXT_TX
1080 0 : default: assert(0); break;
1081 : }
1082 0 : mm256_transpose_16x16(in, in);
1083 0 : write_buffer_16x16(in, output);
1084 : _mm256_zeroupper();
1085 0 : }
1086 :
1087 0 : void aom_fdct32x32_1_avx2(const int16_t *input, tran_low_t *output,
1088 : int stride) {
1089 : // left and upper corner
1090 0 : int32_t sum = get_16x16_sum(input, stride);
1091 : // right and upper corner
1092 0 : sum += get_16x16_sum(input + 16, stride);
1093 : // left and lower corner
1094 0 : sum += get_16x16_sum(input + (stride << 4), stride);
1095 : // right and lower corner
1096 0 : sum += get_16x16_sum(input + (stride << 4) + 16, stride);
1097 :
1098 0 : sum >>= 3;
1099 0 : output[0] = (tran_low_t)sum;
1100 : _mm256_zeroupper();
1101 0 : }
1102 :
1103 0 : static void mm256_vectors_swap(__m256i *a0, __m256i *a1, const int size) {
1104 0 : int i = 0;
1105 : __m256i temp;
1106 0 : while (i < size) {
1107 0 : temp = a0[i];
1108 0 : a0[i] = a1[i];
1109 0 : a1[i] = temp;
1110 0 : i++;
1111 : }
1112 0 : }
1113 :
1114 0 : static void mm256_transpose_32x32(__m256i *in0, __m256i *in1) {
1115 0 : mm256_transpose_16x16(in0, in0);
1116 0 : mm256_transpose_16x16(&in0[16], &in0[16]);
1117 0 : mm256_transpose_16x16(in1, in1);
1118 0 : mm256_transpose_16x16(&in1[16], &in1[16]);
1119 0 : mm256_vectors_swap(&in0[16], in1, 16);
1120 0 : }
1121 :
1122 0 : static void prepare_16x16_even(const __m256i *in, __m256i *even) {
1123 0 : even[0] = _mm256_add_epi16(in[0], in[31]);
1124 0 : even[1] = _mm256_add_epi16(in[1], in[30]);
1125 0 : even[2] = _mm256_add_epi16(in[2], in[29]);
1126 0 : even[3] = _mm256_add_epi16(in[3], in[28]);
1127 0 : even[4] = _mm256_add_epi16(in[4], in[27]);
1128 0 : even[5] = _mm256_add_epi16(in[5], in[26]);
1129 0 : even[6] = _mm256_add_epi16(in[6], in[25]);
1130 0 : even[7] = _mm256_add_epi16(in[7], in[24]);
1131 0 : even[8] = _mm256_add_epi16(in[8], in[23]);
1132 0 : even[9] = _mm256_add_epi16(in[9], in[22]);
1133 0 : even[10] = _mm256_add_epi16(in[10], in[21]);
1134 0 : even[11] = _mm256_add_epi16(in[11], in[20]);
1135 0 : even[12] = _mm256_add_epi16(in[12], in[19]);
1136 0 : even[13] = _mm256_add_epi16(in[13], in[18]);
1137 0 : even[14] = _mm256_add_epi16(in[14], in[17]);
1138 0 : even[15] = _mm256_add_epi16(in[15], in[16]);
1139 0 : }
1140 :
1141 0 : static void prepare_16x16_odd(const __m256i *in, __m256i *odd) {
1142 0 : odd[0] = _mm256_sub_epi16(in[15], in[16]);
1143 0 : odd[1] = _mm256_sub_epi16(in[14], in[17]);
1144 0 : odd[2] = _mm256_sub_epi16(in[13], in[18]);
1145 0 : odd[3] = _mm256_sub_epi16(in[12], in[19]);
1146 0 : odd[4] = _mm256_sub_epi16(in[11], in[20]);
1147 0 : odd[5] = _mm256_sub_epi16(in[10], in[21]);
1148 0 : odd[6] = _mm256_sub_epi16(in[9], in[22]);
1149 0 : odd[7] = _mm256_sub_epi16(in[8], in[23]);
1150 0 : odd[8] = _mm256_sub_epi16(in[7], in[24]);
1151 0 : odd[9] = _mm256_sub_epi16(in[6], in[25]);
1152 0 : odd[10] = _mm256_sub_epi16(in[5], in[26]);
1153 0 : odd[11] = _mm256_sub_epi16(in[4], in[27]);
1154 0 : odd[12] = _mm256_sub_epi16(in[3], in[28]);
1155 0 : odd[13] = _mm256_sub_epi16(in[2], in[29]);
1156 0 : odd[14] = _mm256_sub_epi16(in[1], in[30]);
1157 0 : odd[15] = _mm256_sub_epi16(in[0], in[31]);
1158 0 : }
1159 :
1160 0 : static void collect_16col(const __m256i *even, const __m256i *odd,
1161 : __m256i *out) {
1162 : // fdct16_avx2() already maps the output
1163 0 : out[0] = even[0];
1164 0 : out[2] = even[1];
1165 0 : out[4] = even[2];
1166 0 : out[6] = even[3];
1167 0 : out[8] = even[4];
1168 0 : out[10] = even[5];
1169 0 : out[12] = even[6];
1170 0 : out[14] = even[7];
1171 0 : out[16] = even[8];
1172 0 : out[18] = even[9];
1173 0 : out[20] = even[10];
1174 0 : out[22] = even[11];
1175 0 : out[24] = even[12];
1176 0 : out[26] = even[13];
1177 0 : out[28] = even[14];
1178 0 : out[30] = even[15];
1179 :
1180 0 : out[1] = odd[0];
1181 0 : out[17] = odd[1];
1182 0 : out[9] = odd[2];
1183 0 : out[25] = odd[3];
1184 0 : out[5] = odd[4];
1185 0 : out[21] = odd[5];
1186 0 : out[13] = odd[6];
1187 0 : out[29] = odd[7];
1188 0 : out[3] = odd[8];
1189 0 : out[19] = odd[9];
1190 0 : out[11] = odd[10];
1191 0 : out[27] = odd[11];
1192 0 : out[7] = odd[12];
1193 0 : out[23] = odd[13];
1194 0 : out[15] = odd[14];
1195 0 : out[31] = odd[15];
1196 0 : }
1197 :
1198 0 : static void collect_coeffs(const __m256i *first_16col_even,
1199 : const __m256i *first_16col_odd,
1200 : const __m256i *second_16col_even,
1201 : const __m256i *second_16col_odd, __m256i *in0,
1202 : __m256i *in1) {
1203 0 : collect_16col(first_16col_even, first_16col_odd, in0);
1204 0 : collect_16col(second_16col_even, second_16col_odd, in1);
1205 0 : }
1206 :
1207 0 : static void fdct16_odd_avx2(__m256i *in) {
1208 : // sequence: cospi_L_H = pairs(L, H) and L first
1209 0 : const __m256i cospi_p16_p16 = pair256_set_epi16(cospi_16_64, cospi_16_64);
1210 0 : const __m256i cospi_m16_p16 = pair256_set_epi16(-cospi_16_64, cospi_16_64);
1211 0 : const __m256i cospi_m08_p24 = pair256_set_epi16(-cospi_8_64, cospi_24_64);
1212 0 : const __m256i cospi_p24_p08 = pair256_set_epi16(cospi_24_64, cospi_8_64);
1213 0 : const __m256i cospi_m24_m08 = pair256_set_epi16(-cospi_24_64, -cospi_8_64);
1214 0 : const __m256i cospi_m04_p28 = pair256_set_epi16(-cospi_4_64, cospi_28_64);
1215 0 : const __m256i cospi_p28_p04 = pair256_set_epi16(cospi_28_64, cospi_4_64);
1216 0 : const __m256i cospi_m28_m04 = pair256_set_epi16(-cospi_28_64, -cospi_4_64);
1217 0 : const __m256i cospi_m20_p12 = pair256_set_epi16(-cospi_20_64, cospi_12_64);
1218 0 : const __m256i cospi_p12_p20 = pair256_set_epi16(cospi_12_64, cospi_20_64);
1219 0 : const __m256i cospi_m12_m20 = pair256_set_epi16(-cospi_12_64, -cospi_20_64);
1220 :
1221 0 : const __m256i cospi_p31_p01 = pair256_set_epi16(cospi_31_64, cospi_1_64);
1222 0 : const __m256i cospi_m01_p31 = pair256_set_epi16(-cospi_1_64, cospi_31_64);
1223 0 : const __m256i cospi_p15_p17 = pair256_set_epi16(cospi_15_64, cospi_17_64);
1224 0 : const __m256i cospi_m17_p15 = pair256_set_epi16(-cospi_17_64, cospi_15_64);
1225 0 : const __m256i cospi_p23_p09 = pair256_set_epi16(cospi_23_64, cospi_9_64);
1226 0 : const __m256i cospi_m09_p23 = pair256_set_epi16(-cospi_9_64, cospi_23_64);
1227 0 : const __m256i cospi_p07_p25 = pair256_set_epi16(cospi_7_64, cospi_25_64);
1228 0 : const __m256i cospi_m25_p07 = pair256_set_epi16(-cospi_25_64, cospi_7_64);
1229 0 : const __m256i cospi_p27_p05 = pair256_set_epi16(cospi_27_64, cospi_5_64);
1230 0 : const __m256i cospi_m05_p27 = pair256_set_epi16(-cospi_5_64, cospi_27_64);
1231 0 : const __m256i cospi_p11_p21 = pair256_set_epi16(cospi_11_64, cospi_21_64);
1232 0 : const __m256i cospi_m21_p11 = pair256_set_epi16(-cospi_21_64, cospi_11_64);
1233 0 : const __m256i cospi_p19_p13 = pair256_set_epi16(cospi_19_64, cospi_13_64);
1234 0 : const __m256i cospi_m13_p19 = pair256_set_epi16(-cospi_13_64, cospi_19_64);
1235 0 : const __m256i cospi_p03_p29 = pair256_set_epi16(cospi_3_64, cospi_29_64);
1236 0 : const __m256i cospi_m29_p03 = pair256_set_epi16(-cospi_29_64, cospi_3_64);
1237 :
1238 : __m256i x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
1239 : __m256i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, y15;
1240 : __m256i u0, u1;
1241 :
1242 : // stage 1 is in prepare_16x16_odd()
1243 :
1244 : // stage 2
1245 0 : y0 = in[0];
1246 0 : y1 = in[1];
1247 0 : y2 = in[2];
1248 0 : y3 = in[3];
1249 :
1250 0 : u0 = _mm256_unpacklo_epi16(in[4], in[11]);
1251 0 : u1 = _mm256_unpackhi_epi16(in[4], in[11]);
1252 0 : y4 = butter_fly(&u0, &u1, &cospi_m16_p16);
1253 0 : y11 = butter_fly(&u0, &u1, &cospi_p16_p16);
1254 :
1255 0 : u0 = _mm256_unpacklo_epi16(in[5], in[10]);
1256 0 : u1 = _mm256_unpackhi_epi16(in[5], in[10]);
1257 0 : y5 = butter_fly(&u0, &u1, &cospi_m16_p16);
1258 0 : y10 = butter_fly(&u0, &u1, &cospi_p16_p16);
1259 :
1260 0 : u0 = _mm256_unpacklo_epi16(in[6], in[9]);
1261 0 : u1 = _mm256_unpackhi_epi16(in[6], in[9]);
1262 0 : y6 = butter_fly(&u0, &u1, &cospi_m16_p16);
1263 0 : y9 = butter_fly(&u0, &u1, &cospi_p16_p16);
1264 :
1265 0 : u0 = _mm256_unpacklo_epi16(in[7], in[8]);
1266 0 : u1 = _mm256_unpackhi_epi16(in[7], in[8]);
1267 0 : y7 = butter_fly(&u0, &u1, &cospi_m16_p16);
1268 0 : y8 = butter_fly(&u0, &u1, &cospi_p16_p16);
1269 :
1270 0 : y12 = in[12];
1271 0 : y13 = in[13];
1272 0 : y14 = in[14];
1273 0 : y15 = in[15];
1274 :
1275 : // stage 3
1276 0 : x0 = _mm256_add_epi16(y0, y7);
1277 0 : x1 = _mm256_add_epi16(y1, y6);
1278 0 : x2 = _mm256_add_epi16(y2, y5);
1279 0 : x3 = _mm256_add_epi16(y3, y4);
1280 0 : x4 = _mm256_sub_epi16(y3, y4);
1281 0 : x5 = _mm256_sub_epi16(y2, y5);
1282 0 : x6 = _mm256_sub_epi16(y1, y6);
1283 0 : x7 = _mm256_sub_epi16(y0, y7);
1284 0 : x8 = _mm256_sub_epi16(y15, y8);
1285 0 : x9 = _mm256_sub_epi16(y14, y9);
1286 0 : x10 = _mm256_sub_epi16(y13, y10);
1287 0 : x11 = _mm256_sub_epi16(y12, y11);
1288 0 : x12 = _mm256_add_epi16(y12, y11);
1289 0 : x13 = _mm256_add_epi16(y13, y10);
1290 0 : x14 = _mm256_add_epi16(y14, y9);
1291 0 : x15 = _mm256_add_epi16(y15, y8);
1292 :
1293 : // stage 4
1294 0 : y0 = x0;
1295 0 : y1 = x1;
1296 0 : y6 = x6;
1297 0 : y7 = x7;
1298 0 : y8 = x8;
1299 0 : y9 = x9;
1300 0 : y14 = x14;
1301 0 : y15 = x15;
1302 :
1303 0 : u0 = _mm256_unpacklo_epi16(x2, x13);
1304 0 : u1 = _mm256_unpackhi_epi16(x2, x13);
1305 0 : y2 = butter_fly(&u0, &u1, &cospi_m08_p24);
1306 0 : y13 = butter_fly(&u0, &u1, &cospi_p24_p08);
1307 :
1308 0 : u0 = _mm256_unpacklo_epi16(x3, x12);
1309 0 : u1 = _mm256_unpackhi_epi16(x3, x12);
1310 0 : y3 = butter_fly(&u0, &u1, &cospi_m08_p24);
1311 0 : y12 = butter_fly(&u0, &u1, &cospi_p24_p08);
1312 :
1313 0 : u0 = _mm256_unpacklo_epi16(x4, x11);
1314 0 : u1 = _mm256_unpackhi_epi16(x4, x11);
1315 0 : y4 = butter_fly(&u0, &u1, &cospi_m24_m08);
1316 0 : y11 = butter_fly(&u0, &u1, &cospi_m08_p24);
1317 :
1318 0 : u0 = _mm256_unpacklo_epi16(x5, x10);
1319 0 : u1 = _mm256_unpackhi_epi16(x5, x10);
1320 0 : y5 = butter_fly(&u0, &u1, &cospi_m24_m08);
1321 0 : y10 = butter_fly(&u0, &u1, &cospi_m08_p24);
1322 :
1323 : // stage 5
1324 0 : x0 = _mm256_add_epi16(y0, y3);
1325 0 : x1 = _mm256_add_epi16(y1, y2);
1326 0 : x2 = _mm256_sub_epi16(y1, y2);
1327 0 : x3 = _mm256_sub_epi16(y0, y3);
1328 0 : x4 = _mm256_sub_epi16(y7, y4);
1329 0 : x5 = _mm256_sub_epi16(y6, y5);
1330 0 : x6 = _mm256_add_epi16(y6, y5);
1331 0 : x7 = _mm256_add_epi16(y7, y4);
1332 :
1333 0 : x8 = _mm256_add_epi16(y8, y11);
1334 0 : x9 = _mm256_add_epi16(y9, y10);
1335 0 : x10 = _mm256_sub_epi16(y9, y10);
1336 0 : x11 = _mm256_sub_epi16(y8, y11);
1337 0 : x12 = _mm256_sub_epi16(y15, y12);
1338 0 : x13 = _mm256_sub_epi16(y14, y13);
1339 0 : x14 = _mm256_add_epi16(y14, y13);
1340 0 : x15 = _mm256_add_epi16(y15, y12);
1341 :
1342 : // stage 6
1343 0 : y0 = x0;
1344 0 : y3 = x3;
1345 0 : y4 = x4;
1346 0 : y7 = x7;
1347 0 : y8 = x8;
1348 0 : y11 = x11;
1349 0 : y12 = x12;
1350 0 : y15 = x15;
1351 :
1352 0 : u0 = _mm256_unpacklo_epi16(x1, x14);
1353 0 : u1 = _mm256_unpackhi_epi16(x1, x14);
1354 0 : y1 = butter_fly(&u0, &u1, &cospi_m04_p28);
1355 0 : y14 = butter_fly(&u0, &u1, &cospi_p28_p04);
1356 :
1357 0 : u0 = _mm256_unpacklo_epi16(x2, x13);
1358 0 : u1 = _mm256_unpackhi_epi16(x2, x13);
1359 0 : y2 = butter_fly(&u0, &u1, &cospi_m28_m04);
1360 0 : y13 = butter_fly(&u0, &u1, &cospi_m04_p28);
1361 :
1362 0 : u0 = _mm256_unpacklo_epi16(x5, x10);
1363 0 : u1 = _mm256_unpackhi_epi16(x5, x10);
1364 0 : y5 = butter_fly(&u0, &u1, &cospi_m20_p12);
1365 0 : y10 = butter_fly(&u0, &u1, &cospi_p12_p20);
1366 :
1367 0 : u0 = _mm256_unpacklo_epi16(x6, x9);
1368 0 : u1 = _mm256_unpackhi_epi16(x6, x9);
1369 0 : y6 = butter_fly(&u0, &u1, &cospi_m12_m20);
1370 0 : y9 = butter_fly(&u0, &u1, &cospi_m20_p12);
1371 :
1372 : // stage 7
1373 0 : x0 = _mm256_add_epi16(y0, y1);
1374 0 : x1 = _mm256_sub_epi16(y0, y1);
1375 0 : x2 = _mm256_sub_epi16(y3, y2);
1376 0 : x3 = _mm256_add_epi16(y3, y2);
1377 0 : x4 = _mm256_add_epi16(y4, y5);
1378 0 : x5 = _mm256_sub_epi16(y4, y5);
1379 0 : x6 = _mm256_sub_epi16(y7, y6);
1380 0 : x7 = _mm256_add_epi16(y7, y6);
1381 :
1382 0 : x8 = _mm256_add_epi16(y8, y9);
1383 0 : x9 = _mm256_sub_epi16(y8, y9);
1384 0 : x10 = _mm256_sub_epi16(y11, y10);
1385 0 : x11 = _mm256_add_epi16(y11, y10);
1386 0 : x12 = _mm256_add_epi16(y12, y13);
1387 0 : x13 = _mm256_sub_epi16(y12, y13);
1388 0 : x14 = _mm256_sub_epi16(y15, y14);
1389 0 : x15 = _mm256_add_epi16(y15, y14);
1390 :
1391 : // stage 8
1392 0 : u0 = _mm256_unpacklo_epi16(x0, x15);
1393 0 : u1 = _mm256_unpackhi_epi16(x0, x15);
1394 0 : in[0] = butter_fly(&u0, &u1, &cospi_p31_p01);
1395 0 : in[15] = butter_fly(&u0, &u1, &cospi_m01_p31);
1396 :
1397 0 : u0 = _mm256_unpacklo_epi16(x1, x14);
1398 0 : u1 = _mm256_unpackhi_epi16(x1, x14);
1399 0 : in[1] = butter_fly(&u0, &u1, &cospi_p15_p17);
1400 0 : in[14] = butter_fly(&u0, &u1, &cospi_m17_p15);
1401 :
1402 0 : u0 = _mm256_unpacklo_epi16(x2, x13);
1403 0 : u1 = _mm256_unpackhi_epi16(x2, x13);
1404 0 : in[2] = butter_fly(&u0, &u1, &cospi_p23_p09);
1405 0 : in[13] = butter_fly(&u0, &u1, &cospi_m09_p23);
1406 :
1407 0 : u0 = _mm256_unpacklo_epi16(x3, x12);
1408 0 : u1 = _mm256_unpackhi_epi16(x3, x12);
1409 0 : in[3] = butter_fly(&u0, &u1, &cospi_p07_p25);
1410 0 : in[12] = butter_fly(&u0, &u1, &cospi_m25_p07);
1411 :
1412 0 : u0 = _mm256_unpacklo_epi16(x4, x11);
1413 0 : u1 = _mm256_unpackhi_epi16(x4, x11);
1414 0 : in[4] = butter_fly(&u0, &u1, &cospi_p27_p05);
1415 0 : in[11] = butter_fly(&u0, &u1, &cospi_m05_p27);
1416 :
1417 0 : u0 = _mm256_unpacklo_epi16(x5, x10);
1418 0 : u1 = _mm256_unpackhi_epi16(x5, x10);
1419 0 : in[5] = butter_fly(&u0, &u1, &cospi_p11_p21);
1420 0 : in[10] = butter_fly(&u0, &u1, &cospi_m21_p11);
1421 :
1422 0 : u0 = _mm256_unpacklo_epi16(x6, x9);
1423 0 : u1 = _mm256_unpackhi_epi16(x6, x9);
1424 0 : in[6] = butter_fly(&u0, &u1, &cospi_p19_p13);
1425 0 : in[9] = butter_fly(&u0, &u1, &cospi_m13_p19);
1426 :
1427 0 : u0 = _mm256_unpacklo_epi16(x7, x8);
1428 0 : u1 = _mm256_unpackhi_epi16(x7, x8);
1429 0 : in[7] = butter_fly(&u0, &u1, &cospi_p03_p29);
1430 0 : in[8] = butter_fly(&u0, &u1, &cospi_m29_p03);
1431 0 : }
1432 :
1433 0 : static void fdct32_avx2(__m256i *in0, __m256i *in1) {
1434 : __m256i even0[16], even1[16], odd0[16], odd1[16];
1435 0 : prepare_16x16_even(in0, even0);
1436 0 : fdct16_avx2(even0);
1437 :
1438 0 : prepare_16x16_odd(in0, odd0);
1439 0 : fdct16_odd_avx2(odd0);
1440 :
1441 0 : prepare_16x16_even(in1, even1);
1442 0 : fdct16_avx2(even1);
1443 :
1444 0 : prepare_16x16_odd(in1, odd1);
1445 0 : fdct16_odd_avx2(odd1);
1446 :
1447 0 : collect_coeffs(even0, odd0, even1, odd1, in0, in1);
1448 :
1449 0 : mm256_transpose_32x32(in0, in1);
1450 0 : }
1451 :
1452 0 : static INLINE void write_buffer_32x32(const __m256i *in0, const __m256i *in1,
1453 : tran_low_t *output) {
1454 0 : int i = 0;
1455 0 : const int stride = 32;
1456 0 : tran_low_t *coeff = output;
1457 0 : while (i < 32) {
1458 0 : storeu_output_avx2(&in0[i], coeff);
1459 0 : storeu_output_avx2(&in1[i], coeff + 16);
1460 0 : coeff += stride;
1461 0 : i += 1;
1462 : }
1463 0 : }
1464 :
1465 : #if CONFIG_EXT_TX
1466 0 : static void fhalfright32_16col_avx2(__m256i *in) {
1467 0 : int i = 0;
1468 0 : const __m256i zero = _mm256_setzero_si256();
1469 0 : const __m256i sqrt2 = _mm256_set1_epi16((int16_t)Sqrt2);
1470 0 : const __m256i dct_rounding = _mm256_set1_epi32(DCT_CONST_ROUNDING);
1471 : __m256i x0, x1;
1472 :
1473 0 : while (i < 16) {
1474 0 : in[i] = _mm256_slli_epi16(in[i], 2);
1475 0 : x0 = _mm256_unpacklo_epi16(in[i + 16], zero);
1476 0 : x1 = _mm256_unpackhi_epi16(in[i + 16], zero);
1477 0 : x0 = _mm256_madd_epi16(x0, sqrt2);
1478 0 : x1 = _mm256_madd_epi16(x1, sqrt2);
1479 0 : x0 = _mm256_add_epi32(x0, dct_rounding);
1480 0 : x1 = _mm256_add_epi32(x1, dct_rounding);
1481 0 : x0 = _mm256_srai_epi32(x0, DCT_CONST_BITS);
1482 0 : x1 = _mm256_srai_epi32(x1, DCT_CONST_BITS);
1483 0 : in[i + 16] = _mm256_packs_epi32(x0, x1);
1484 0 : i += 1;
1485 : }
1486 0 : fdct16_avx2(&in[16]);
1487 0 : }
1488 :
1489 0 : static void fhalfright32_avx2(__m256i *in0, __m256i *in1) {
1490 0 : fhalfright32_16col_avx2(in0);
1491 0 : fhalfright32_16col_avx2(in1);
1492 0 : mm256_vectors_swap(in0, &in0[16], 16);
1493 0 : mm256_vectors_swap(in1, &in1[16], 16);
1494 0 : mm256_transpose_32x32(in0, in1);
1495 0 : }
1496 : #endif // CONFIG_EXT_TX
1497 :
1498 0 : static INLINE void load_buffer_32x32(const int16_t *input, int stride,
1499 : int flipud, int fliplr, __m256i *in0,
1500 : __m256i *in1) {
1501 : // Load 4 16x16 blocks
1502 0 : const int16_t *topL = input;
1503 0 : const int16_t *topR = input + 16;
1504 0 : const int16_t *botL = input + 16 * stride;
1505 0 : const int16_t *botR = input + 16 * stride + 16;
1506 :
1507 : const int16_t *tmp;
1508 :
1509 0 : if (flipud) {
1510 : // Swap left columns
1511 0 : tmp = topL;
1512 0 : topL = botL;
1513 0 : botL = tmp;
1514 : // Swap right columns
1515 0 : tmp = topR;
1516 0 : topR = botR;
1517 0 : botR = tmp;
1518 : }
1519 :
1520 0 : if (fliplr) {
1521 : // Swap top rows
1522 0 : tmp = topL;
1523 0 : topL = topR;
1524 0 : topR = tmp;
1525 : // Swap bottom rows
1526 0 : tmp = botL;
1527 0 : botL = botR;
1528 0 : botR = tmp;
1529 : }
1530 :
1531 : // load first 16 columns
1532 0 : load_buffer_16x16(topL, stride, flipud, fliplr, in0);
1533 0 : load_buffer_16x16(botL, stride, flipud, fliplr, in0 + 16);
1534 :
1535 : // load second 16 columns
1536 0 : load_buffer_16x16(topR, stride, flipud, fliplr, in1);
1537 0 : load_buffer_16x16(botR, stride, flipud, fliplr, in1 + 16);
1538 0 : }
1539 :
1540 0 : static INLINE void right_shift_32x32_16col(int bit, __m256i *in) {
1541 0 : int i = 0;
1542 0 : const __m256i rounding = _mm256_set1_epi16((1 << bit) >> 1);
1543 : __m256i sign;
1544 0 : while (i < 32) {
1545 0 : sign = _mm256_srai_epi16(in[i], 15);
1546 0 : in[i] = _mm256_add_epi16(in[i], rounding);
1547 0 : in[i] = _mm256_add_epi16(in[i], sign);
1548 0 : in[i] = _mm256_srai_epi16(in[i], bit);
1549 0 : i += 1;
1550 : }
1551 0 : }
1552 :
1553 : // Positive rounding
1554 0 : static INLINE void right_shift_32x32(__m256i *in0, __m256i *in1) {
1555 0 : const int bit = 4;
1556 0 : right_shift_32x32_16col(bit, in0);
1557 0 : right_shift_32x32_16col(bit, in1);
1558 0 : }
1559 :
1560 : #if CONFIG_EXT_TX
1561 0 : static void fidtx32_avx2(__m256i *in0, __m256i *in1) {
1562 0 : int i = 0;
1563 0 : while (i < 32) {
1564 0 : in0[i] = _mm256_slli_epi16(in0[i], 2);
1565 0 : in1[i] = _mm256_slli_epi16(in1[i], 2);
1566 0 : i += 1;
1567 : }
1568 0 : mm256_transpose_32x32(in0, in1);
1569 0 : }
1570 : #endif
1571 :
1572 0 : void av1_fht32x32_avx2(const int16_t *input, tran_low_t *output, int stride,
1573 : int tx_type) {
1574 : __m256i in0[32]; // left 32 columns
1575 : __m256i in1[32]; // right 32 columns
1576 :
1577 0 : switch (tx_type) {
1578 : case DCT_DCT:
1579 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1580 0 : fdct32_avx2(in0, in1);
1581 0 : right_shift_32x32(in0, in1);
1582 0 : fdct32_avx2(in0, in1);
1583 0 : break;
1584 : #if CONFIG_EXT_TX
1585 : case ADST_DCT:
1586 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1587 0 : fhalfright32_avx2(in0, in1);
1588 0 : right_shift_32x32(in0, in1);
1589 0 : fdct32_avx2(in0, in1);
1590 0 : break;
1591 : case DCT_ADST:
1592 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1593 0 : fdct32_avx2(in0, in1);
1594 0 : right_shift_32x32(in0, in1);
1595 0 : fhalfright32_avx2(in0, in1);
1596 0 : break;
1597 : case ADST_ADST:
1598 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1599 0 : fhalfright32_avx2(in0, in1);
1600 0 : right_shift_32x32(in0, in1);
1601 0 : fhalfright32_avx2(in0, in1);
1602 0 : break;
1603 : case FLIPADST_DCT:
1604 0 : load_buffer_32x32(input, stride, 1, 0, in0, in1);
1605 0 : fhalfright32_avx2(in0, in1);
1606 0 : right_shift_32x32(in0, in1);
1607 0 : fdct32_avx2(in0, in1);
1608 0 : break;
1609 : case DCT_FLIPADST:
1610 0 : load_buffer_32x32(input, stride, 0, 1, in0, in1);
1611 0 : fdct32_avx2(in0, in1);
1612 0 : right_shift_32x32(in0, in1);
1613 0 : fhalfright32_avx2(in0, in1);
1614 0 : break;
1615 : case FLIPADST_FLIPADST:
1616 0 : load_buffer_32x32(input, stride, 1, 1, in0, in1);
1617 0 : fhalfright32_avx2(in0, in1);
1618 0 : right_shift_32x32(in0, in1);
1619 0 : fhalfright32_avx2(in0, in1);
1620 0 : break;
1621 : case ADST_FLIPADST:
1622 0 : load_buffer_32x32(input, stride, 0, 1, in0, in1);
1623 0 : fhalfright32_avx2(in0, in1);
1624 0 : right_shift_32x32(in0, in1);
1625 0 : fhalfright32_avx2(in0, in1);
1626 0 : break;
1627 : case FLIPADST_ADST:
1628 0 : load_buffer_32x32(input, stride, 1, 0, in0, in1);
1629 0 : fhalfright32_avx2(in0, in1);
1630 0 : right_shift_32x32(in0, in1);
1631 0 : fhalfright32_avx2(in0, in1);
1632 0 : break;
1633 : case IDTX:
1634 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1635 0 : fidtx32_avx2(in0, in1);
1636 0 : right_shift_32x32(in0, in1);
1637 0 : fidtx32_avx2(in0, in1);
1638 0 : break;
1639 : case V_DCT:
1640 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1641 0 : fdct32_avx2(in0, in1);
1642 0 : right_shift_32x32(in0, in1);
1643 0 : fidtx32_avx2(in0, in1);
1644 0 : break;
1645 : case H_DCT:
1646 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1647 0 : fidtx32_avx2(in0, in1);
1648 0 : right_shift_32x32(in0, in1);
1649 0 : fdct32_avx2(in0, in1);
1650 0 : break;
1651 : case V_ADST:
1652 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1653 0 : fhalfright32_avx2(in0, in1);
1654 0 : right_shift_32x32(in0, in1);
1655 0 : fidtx32_avx2(in0, in1);
1656 0 : break;
1657 : case H_ADST:
1658 0 : load_buffer_32x32(input, stride, 0, 0, in0, in1);
1659 0 : fidtx32_avx2(in0, in1);
1660 0 : right_shift_32x32(in0, in1);
1661 0 : fhalfright32_avx2(in0, in1);
1662 0 : break;
1663 : case V_FLIPADST:
1664 0 : load_buffer_32x32(input, stride, 1, 0, in0, in1);
1665 0 : fhalfright32_avx2(in0, in1);
1666 0 : right_shift_32x32(in0, in1);
1667 0 : fidtx32_avx2(in0, in1);
1668 0 : break;
1669 : case H_FLIPADST:
1670 0 : load_buffer_32x32(input, stride, 0, 1, in0, in1);
1671 0 : fidtx32_avx2(in0, in1);
1672 0 : right_shift_32x32(in0, in1);
1673 0 : fhalfright32_avx2(in0, in1);
1674 0 : break;
1675 : #endif // CONFIG_EXT_TX
1676 0 : default: assert(0); break;
1677 : }
1678 0 : write_buffer_32x32(in0, in1, output);
1679 : _mm256_zeroupper();
1680 0 : }
|