Line data Source code
1 : /*
2 : * Copyright (c) 2017, 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 "EbDefinitions.h"
13 : #include <immintrin.h>
14 :
15 : #include "aom_dsp_rtcd.h"
16 :
17 : // Note: TranHigh is the datatype used for intermediate transform stages.
18 : typedef int64_t TranHigh;
19 :
20 321487000 : static INLINE void init_one_qp(const __m128i *p, __m256i *qp) {
21 321487000 : const __m128i sign = _mm_srai_epi16(*p, 15);
22 321487000 : const __m128i dc = _mm_unpacklo_epi16(*p, sign);
23 321487000 : const __m128i ac = _mm_unpackhi_epi16(*p, sign);
24 321487000 : *qp = _mm256_insertf128_si256(_mm256_castsi128_si256(dc), ac, 1);
25 321487000 : }
26 :
27 64447100 : static INLINE void update_qp(__m256i *qp) {
28 : int32_t i;
29 386659000 : for (i = 0; i < 5; ++i)
30 322212000 : qp[i] = _mm256_permute2x128_si256(qp[i], qp[i], 0x11);
31 64447100 : }
32 :
33 56350200 : static INLINE void init_qp(const int16_t *zbin_ptr, const int16_t *round_ptr,
34 : const int16_t *quant_ptr, const int16_t *dequant_ptr,
35 : const int16_t *quant_shift_ptr, __m256i *qp) {
36 56350200 : const __m128i zbin = _mm_loadu_si128((const __m128i *)zbin_ptr);
37 56350200 : const __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
38 56350200 : const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
39 56350200 : const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);
40 56350200 : const __m128i quant_shift = _mm_loadu_si128((const __m128i *)quant_shift_ptr);
41 56350200 : init_one_qp(&zbin, &qp[0]);
42 56338500 : init_one_qp(&round, &qp[1]);
43 56321200 : init_one_qp(&quant, &qp[2]);
44 56328100 : init_one_qp(&dequant, &qp[3]);
45 56339800 : init_one_qp(&quant_shift, &qp[4]);
46 56356200 : }
47 :
48 : // Note:
49 : // *x is vector multiplied by *y which is 16 int32_t parallel multiplication
50 : // and right shift 16. The output, 16 int32_t is save in *p.
51 224461000 : static INLINE void mm256_mul_shift_epi32(const __m256i *x, const __m256i *y,
52 : __m256i *p) {
53 224461000 : __m256i prod_lo = _mm256_mul_epi32(*x, *y);
54 224461000 : __m256i prod_hi = _mm256_srli_epi64(*x, 32);
55 448922000 : const __m256i mult_hi = _mm256_srli_epi64(*y, 32);
56 224461000 : prod_hi = _mm256_mul_epi32(prod_hi, mult_hi);
57 :
58 224461000 : prod_lo = _mm256_srli_epi64(prod_lo, 16);
59 224461000 : const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
60 224461000 : prod_lo = _mm256_and_si256(prod_lo, mask);
61 224461000 : prod_hi = _mm256_srli_epi64(prod_hi, 16);
62 :
63 224461000 : prod_hi = _mm256_slli_epi64(prod_hi, 32);
64 224461000 : *p = _mm256_or_si256(prod_lo, prod_hi);
65 224461000 : }
66 :
67 136325000 : static INLINE void clamp_epi32(__m256i *x, __m256i min, __m256i max) {
68 136325000 : *x = _mm256_min_epi32(*x, max);
69 136325000 : *x = _mm256_max_epi32(*x, min);
70 136325000 : }
71 :
72 722333000 : static INLINE void quantize(const __m256i *qp, __m256i *c,
73 : const int16_t *iscan_ptr, TranLow *qcoeff,
74 : TranLow *dqcoeff, __m256i *eob, __m256i min, __m256i max)
75 : {
76 722333000 : const __m256i abs = _mm256_abs_epi32(*c);
77 722333000 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
78 1444670000 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
79 722333000 : flag2 = _mm256_or_si256(flag1, flag2);
80 722333000 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
81 :
82 722333000 : if (LIKELY(nzflag)) {
83 88490800 : __m256i q = _mm256_add_epi32(abs, qp[1]);
84 88490800 : clamp_epi32(&q, min, max);
85 : __m256i tmp;
86 88517900 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
87 88559700 : q = _mm256_add_epi32(tmp, q);
88 :
89 88559700 : mm256_mul_shift_epi32(&q, &qp[4], &q);
90 88527700 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
91 :
92 88527700 : q = _mm256_sign_epi32(q, *c);
93 88527700 : dq = _mm256_sign_epi32(dq, *c);
94 177055000 : q = _mm256_and_si256(q, flag2);
95 88527700 : dq = _mm256_and_si256(dq, flag2);
96 :
97 88527700 : _mm256_storeu_si256((__m256i *)qcoeff, q);
98 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
99 :
100 88527700 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
101 88527700 : const __m128i zr = _mm_setzero_si128();
102 88527700 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
103 88527700 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
104 88527700 : const __m256i iscan =
105 177055000 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
106 :
107 88527700 : const __m256i zero = _mm256_setzero_si256();
108 88527700 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
109 88527700 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
110 88527700 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
111 88527700 : cur_eob = _mm256_and_si256(cur_eob, nz);
112 177055000 : *eob = _mm256_max_epi32(cur_eob, *eob);
113 : }
114 : else {
115 633842000 : const __m256i zero = _mm256_setzero_si256();
116 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
117 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
118 : }
119 722370000 : }
120 :
121 56352600 : void eb_aom_quantize_b_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
122 : int32_t skip_block, const int16_t *zbin_ptr,
123 : const int16_t *round_ptr,
124 : const int16_t *quant_ptr,
125 : const int16_t *quant_shift_ptr,
126 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
127 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
128 : const int16_t *scan, const int16_t *iscan) {
129 : (void)scan;
130 56352600 : const uint32_t step = 8;
131 :
132 56352600 : if (LIKELY(!skip_block)) {
133 : __m256i qp[5], coeff;
134 56356100 : init_qp(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
135 56360500 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
136 :
137 56360500 : __m256i eob = _mm256_setzero_si256();
138 56360500 : __m256i min = _mm256_set1_epi32(INT16_MIN);
139 56360500 : __m256i max = _mm256_set1_epi32(INT16_MAX);
140 56360500 : quantize(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
141 :
142 56384200 : coeff_ptr += step;
143 56384200 : qcoeff_ptr += step;
144 56384200 : dqcoeff_ptr += step;
145 56384200 : iscan += step;
146 56384200 : n_coeffs -= step;
147 :
148 56384200 : update_qp(qp);
149 :
150 724542000 : while (n_coeffs > 0) {
151 668159000 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
152 668159000 : quantize(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
153 :
154 667120000 : coeff_ptr += step;
155 667120000 : qcoeff_ptr += step;
156 667120000 : dqcoeff_ptr += step;
157 667120000 : iscan += step;
158 667120000 : n_coeffs -= step;
159 : }
160 : {
161 : __m256i eob_s;
162 56383600 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
163 56383600 : eob = _mm256_max_epi16(eob, eob_s);
164 56383600 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
165 56383600 : eob = _mm256_max_epi16(eob, eob_s);
166 56383600 : eob_s = _mm256_shufflelo_epi16(eob, 1);
167 56383600 : eob = _mm256_max_epi16(eob, eob_s);
168 56383600 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
169 56383600 : _mm256_extractf128_si256(eob, 1));
170 56383600 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
171 : }
172 : }
173 : else {
174 : do {
175 0 : const __m256i zero = _mm256_setzero_si256();
176 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
177 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
178 0 : qcoeff_ptr += step;
179 0 : dqcoeff_ptr += step;
180 0 : n_coeffs -= step;
181 0 : } while (n_coeffs > 0);
182 0 : *eob_ptr = 0;
183 : }
184 56380200 : }
185 :
186 0 : static INLINE void quantize_highbd(const __m256i *qp, __m256i *c,
187 : const int16_t *iscan_ptr, TranLow *qcoeff,
188 : TranLow *dqcoeff, __m256i *eob) {
189 0 : const __m256i abs = _mm256_abs_epi32(*c);
190 0 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
191 0 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
192 0 : flag2 = _mm256_or_si256(flag1, flag2);
193 0 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
194 :
195 0 : if (LIKELY(nzflag)) {
196 0 : __m256i q = _mm256_add_epi32(abs, qp[1]);
197 : __m256i tmp;
198 0 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
199 0 : q = _mm256_add_epi32(tmp, q);
200 :
201 0 : mm256_mul_shift_epi32(&q, &qp[4], &q);
202 0 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
203 :
204 0 : q = _mm256_sign_epi32(q, *c);
205 0 : dq = _mm256_sign_epi32(dq, *c);
206 0 : q = _mm256_and_si256(q, flag2);
207 0 : dq = _mm256_and_si256(dq, flag2);
208 :
209 0 : _mm256_storeu_si256((__m256i *)qcoeff, q);
210 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
211 :
212 0 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
213 0 : const __m128i zr = _mm_setzero_si128();
214 0 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
215 0 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
216 0 : const __m256i iscan =
217 0 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
218 :
219 0 : const __m256i zero = _mm256_setzero_si256();
220 0 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
221 0 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
222 0 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
223 0 : cur_eob = _mm256_and_si256(cur_eob, nz);
224 0 : *eob = _mm256_max_epi32(cur_eob, *eob);
225 : }
226 : else {
227 0 : const __m256i zero = _mm256_setzero_si256();
228 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
229 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
230 : }
231 0 : }
232 :
233 0 : void eb_aom_highbd_quantize_b_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
234 : int32_t skip_block, const int16_t *zbin_ptr,
235 : const int16_t *round_ptr,
236 : const int16_t *quant_ptr,
237 : const int16_t *quant_shift_ptr,
238 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
239 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
240 : const int16_t *scan, const int16_t *iscan) {
241 : (void)scan;
242 0 : const uint32_t step = 8;
243 :
244 0 : if (LIKELY(!skip_block)) {
245 : __m256i qp[5], coeff;
246 0 : init_qp(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
247 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
248 :
249 0 : __m256i eob = _mm256_setzero_si256();
250 0 : quantize_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
251 :
252 0 : coeff_ptr += step;
253 0 : qcoeff_ptr += step;
254 0 : dqcoeff_ptr += step;
255 0 : iscan += step;
256 0 : n_coeffs -= step;
257 :
258 0 : update_qp(qp);
259 :
260 0 : while (n_coeffs > 0) {
261 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
262 0 : quantize_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
263 :
264 0 : coeff_ptr += step;
265 0 : qcoeff_ptr += step;
266 0 : dqcoeff_ptr += step;
267 0 : iscan += step;
268 0 : n_coeffs -= step;
269 : }
270 : {
271 : __m256i eob_s;
272 0 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
273 0 : eob = _mm256_max_epi16(eob, eob_s);
274 0 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
275 0 : eob = _mm256_max_epi16(eob, eob_s);
276 0 : eob_s = _mm256_shufflelo_epi16(eob, 1);
277 0 : eob = _mm256_max_epi16(eob, eob_s);
278 0 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
279 0 : _mm256_extractf128_si256(eob, 1));
280 0 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
281 : }
282 : }
283 : else {
284 : do {
285 0 : const __m256i zero = _mm256_setzero_si256();
286 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
287 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
288 0 : qcoeff_ptr += step;
289 0 : dqcoeff_ptr += step;
290 0 : n_coeffs -= step;
291 0 : } while (n_coeffs > 0);
292 0 : *eob_ptr = 0;
293 : }
294 0 : }
295 :
296 1367340 : static INLINE void init_qp_64x64(const int16_t *zbin_ptr, const int16_t *round_ptr,
297 : const int16_t *quant_ptr, const int16_t *dequant_ptr,
298 : const int16_t *quant_shift_ptr, __m256i *qp) {
299 1367340 : __m128i zbin = _mm_loadu_si128((const __m128i *)zbin_ptr);
300 1367340 : __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
301 1367340 : const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
302 1367340 : const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);
303 1367340 : const __m128i quant_shift = _mm_loadu_si128((const __m128i *)quant_shift_ptr);
304 1367340 : const __m128i add = _mm_set_epi16(2, 2, 2, 2, 2, 2, 2, 2);
305 1367340 : zbin = _mm_add_epi16(zbin, add);
306 1367340 : round = _mm_add_epi16(round, add);
307 1367340 : zbin = _mm_srli_epi16(zbin, 2);
308 1367340 : round = _mm_srli_epi16(round, 2);
309 1367340 : init_one_qp(&zbin, &qp[0]);
310 1367340 : init_one_qp(&round, &qp[1]);
311 1367350 : init_one_qp(&quant, &qp[2]);
312 1367350 : init_one_qp(&dequant, &qp[3]);
313 1367360 : init_one_qp(&quant_shift, &qp[4]);
314 1367360 : }
315 :
316 14941800 : static INLINE void mm256_mul_shift_epi32_64X64(const __m256i *x, const __m256i *y,
317 : __m256i *p) {
318 14941800 : __m256i prod_lo = _mm256_mul_epi32(*x, *y);
319 14941800 : __m256i prod_hi = _mm256_srli_epi64(*x, 32);
320 29883700 : const __m256i mult_hi = _mm256_srli_epi64(*y, 32);
321 14941800 : prod_hi = _mm256_mul_epi32(prod_hi, mult_hi);
322 :
323 14941800 : prod_lo = _mm256_srli_epi64(prod_lo, 14);
324 14941800 : const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
325 14941800 : prod_lo = _mm256_and_si256(prod_lo, mask);
326 14941800 : prod_hi = _mm256_srli_epi64(prod_hi, 14);
327 :
328 14941800 : prod_hi = _mm256_slli_epi64(prod_hi, 32);
329 14941800 : *p = _mm256_or_si256(prod_lo, prod_hi);
330 14941800 : }
331 :
332 174483000 : static INLINE void quantize_64X64(const __m256i *qp, __m256i *c,
333 : const int16_t *iscan_ptr, TranLow *qcoeff,
334 : TranLow *dqcoeff, __m256i *eob, __m256i min, __m256i max) {
335 174483000 : const __m256i abs = _mm256_abs_epi32(*c);
336 174483000 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
337 348965000 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
338 174483000 : flag2 = _mm256_or_si256(flag1, flag2);
339 174483000 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
340 :
341 174483000 : if (LIKELY(nzflag)) {
342 14941100 : __m256i q = _mm256_add_epi32(abs, qp[1]);
343 14941100 : clamp_epi32(&q, min, max);
344 : __m256i tmp;
345 14938200 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
346 14941400 : q = _mm256_add_epi32(tmp, q);
347 :
348 14941400 : mm256_mul_shift_epi32_64X64(&q, &qp[4], &q);
349 29890200 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
350 14945100 : dq = _mm256_srli_epi32(dq, 2);
351 :
352 14945100 : q = _mm256_sign_epi32(q, *c);
353 14945100 : dq = _mm256_sign_epi32(dq, *c);
354 29890200 : q = _mm256_and_si256(q, flag2);
355 14945100 : dq = _mm256_and_si256(dq, flag2);
356 :
357 14945100 : _mm256_storeu_si256((__m256i *)qcoeff, q);
358 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
359 :
360 14945100 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
361 14945100 : const __m128i zr = _mm_setzero_si128();
362 14945100 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
363 14945100 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
364 14945100 : const __m256i iscan =
365 29890200 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
366 :
367 14945100 : const __m256i zero = _mm256_setzero_si256();
368 14945100 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
369 14945100 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
370 14945100 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
371 14945100 : cur_eob = _mm256_and_si256(cur_eob, nz);
372 29890200 : *eob = _mm256_max_epi32(cur_eob, *eob);
373 : }
374 : else {
375 159541000 : const __m256i zero = _mm256_setzero_si256();
376 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
377 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
378 : }
379 174487000 : }
380 :
381 1367340 : void eb_aom_quantize_b_64x64_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
382 : int32_t skip_block, const int16_t *zbin_ptr,
383 : const int16_t *round_ptr,
384 : const int16_t *quant_ptr,
385 : const int16_t *quant_shift_ptr,
386 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
387 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
388 : const int16_t *scan, const int16_t *iscan) {
389 : (void)scan;
390 1367340 : const uint32_t step = 8;
391 :
392 1367340 : if (LIKELY(!skip_block)) {
393 : __m256i qp[5], coeff;
394 1367350 : init_qp_64x64(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
395 1367360 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
396 :
397 1367360 : __m256i eob = _mm256_setzero_si256();
398 1367360 : __m256i min = _mm256_set1_epi32(INT16_MIN);
399 1367360 : __m256i max = _mm256_set1_epi32(INT16_MAX);
400 1367360 : quantize_64X64(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
401 :
402 1367350 : coeff_ptr += step;
403 1367350 : qcoeff_ptr += step;
404 1367350 : dqcoeff_ptr += step;
405 1367350 : iscan += step;
406 1367350 : n_coeffs -= step;
407 :
408 1367350 : update_qp(qp);
409 :
410 174645000 : while (n_coeffs > 0) {
411 173278000 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
412 173278000 : quantize_64X64(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
413 :
414 173149000 : coeff_ptr += step;
415 173149000 : qcoeff_ptr += step;
416 173149000 : dqcoeff_ptr += step;
417 173149000 : iscan += step;
418 173149000 : n_coeffs -= step;
419 : }
420 : {
421 : __m256i eob_s;
422 1367380 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
423 1367380 : eob = _mm256_max_epi16(eob, eob_s);
424 1367380 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
425 1367380 : eob = _mm256_max_epi16(eob, eob_s);
426 1367380 : eob_s = _mm256_shufflelo_epi16(eob, 1);
427 1367380 : eob = _mm256_max_epi16(eob, eob_s);
428 1367380 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
429 1367380 : _mm256_extractf128_si256(eob, 1));
430 1367380 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
431 : }
432 : }
433 : else {
434 : do {
435 0 : const __m256i zero = _mm256_setzero_si256();
436 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
437 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
438 0 : qcoeff_ptr += step;
439 0 : dqcoeff_ptr += step;
440 0 : n_coeffs -= step;
441 0 : } while (n_coeffs > 0);
442 0 : *eob_ptr = 0;
443 : }
444 1367380 : }
445 0 : static INLINE void quantize_64X64_highbd(const __m256i *qp, __m256i *c,
446 : const int16_t *iscan_ptr, TranLow *qcoeff,
447 : TranLow *dqcoeff, __m256i *eob) {
448 0 : const __m256i abs = _mm256_abs_epi32(*c);
449 0 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
450 0 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
451 0 : flag2 = _mm256_or_si256(flag1, flag2);
452 0 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
453 :
454 0 : if (LIKELY(nzflag)) {
455 0 : __m256i q = _mm256_add_epi32(abs, qp[1]);
456 : __m256i tmp;
457 0 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
458 0 : q = _mm256_add_epi32(tmp, q);
459 :
460 0 : mm256_mul_shift_epi32_64X64(&q, &qp[4], &q);
461 0 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
462 0 : dq = _mm256_srli_epi32(dq, 2);
463 :
464 0 : q = _mm256_sign_epi32(q, *c);
465 0 : dq = _mm256_sign_epi32(dq, *c);
466 0 : q = _mm256_and_si256(q, flag2);
467 0 : dq = _mm256_and_si256(dq, flag2);
468 :
469 0 : _mm256_storeu_si256((__m256i *)qcoeff, q);
470 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
471 :
472 0 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
473 0 : const __m128i zr = _mm_setzero_si128();
474 0 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
475 0 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
476 0 : const __m256i iscan =
477 0 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
478 :
479 0 : const __m256i zero = _mm256_setzero_si256();
480 0 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
481 0 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
482 0 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
483 0 : cur_eob = _mm256_and_si256(cur_eob, nz);
484 0 : *eob = _mm256_max_epi32(cur_eob, *eob);
485 : }
486 : else {
487 0 : const __m256i zero = _mm256_setzero_si256();
488 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
489 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
490 : }
491 0 : }
492 :
493 0 : void eb_aom_highbd_quantize_b_64x64_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
494 : int32_t skip_block, const int16_t *zbin_ptr,
495 : const int16_t *round_ptr,
496 : const int16_t *quant_ptr,
497 : const int16_t *quant_shift_ptr,
498 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
499 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
500 : const int16_t *scan, const int16_t *iscan) {
501 : (void)scan;
502 0 : const uint32_t step = 8;
503 :
504 0 : if (LIKELY(!skip_block)) {
505 : __m256i qp[5], coeff;
506 0 : init_qp_64x64(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
507 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
508 :
509 0 : __m256i eob = _mm256_setzero_si256();
510 0 : quantize_64X64_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
511 :
512 0 : coeff_ptr += step;
513 0 : qcoeff_ptr += step;
514 0 : dqcoeff_ptr += step;
515 0 : iscan += step;
516 0 : n_coeffs -= step;
517 :
518 0 : update_qp(qp);
519 :
520 0 : while (n_coeffs > 0) {
521 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
522 0 : quantize_64X64_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
523 :
524 0 : coeff_ptr += step;
525 0 : qcoeff_ptr += step;
526 0 : dqcoeff_ptr += step;
527 0 : iscan += step;
528 0 : n_coeffs -= step;
529 : }
530 : {
531 : __m256i eob_s;
532 0 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
533 0 : eob = _mm256_max_epi16(eob, eob_s);
534 0 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
535 0 : eob = _mm256_max_epi16(eob, eob_s);
536 0 : eob_s = _mm256_shufflelo_epi16(eob, 1);
537 0 : eob = _mm256_max_epi16(eob, eob_s);
538 0 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
539 0 : _mm256_extractf128_si256(eob, 1));
540 0 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
541 : }
542 : }
543 : else {
544 : do {
545 0 : const __m256i zero = _mm256_setzero_si256();
546 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
547 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
548 0 : qcoeff_ptr += step;
549 0 : dqcoeff_ptr += step;
550 0 : n_coeffs -= step;
551 0 : } while (n_coeffs > 0);
552 0 : *eob_ptr = 0;
553 : }
554 0 : }
555 6721180 : static INLINE void init_qp_32x32(const int16_t *zbin_ptr, const int16_t *round_ptr,
556 : const int16_t *quant_ptr, const int16_t *dequant_ptr,
557 : const int16_t *quant_shift_ptr, __m256i *qp) {
558 6721180 : __m128i zbin = _mm_loadu_si128((const __m128i *)zbin_ptr);
559 6721180 : __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
560 6721180 : const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
561 6721180 : const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);
562 6721180 : const __m128i quant_shift = _mm_loadu_si128((const __m128i *)quant_shift_ptr);
563 6721180 : const __m128i add = _mm_set_epi16(1, 1, 1, 1, 1, 1, 1, 1);
564 6721180 : zbin = _mm_add_epi16(zbin, add);
565 6721180 : round = _mm_add_epi16(round, add);
566 6721180 : zbin = _mm_srli_epi16(zbin, 1);
567 6721180 : round = _mm_srli_epi16(round, 1);
568 6721180 : init_one_qp(&zbin, &qp[0]);
569 6720970 : init_one_qp(&round, &qp[1]);
570 6720920 : init_one_qp(&quant, &qp[2]);
571 6721060 : init_one_qp(&dequant, &qp[3]);
572 6721150 : init_one_qp(&quant_shift, &qp[4]);
573 6721090 : }
574 :
575 33120900 : static INLINE void mm256_mul_shift_epi32_32x32(const __m256i *x, const __m256i *y,
576 : __m256i *p) {
577 33120900 : __m256i prod_lo = _mm256_mul_epi32(*x, *y);
578 33120900 : __m256i prod_hi = _mm256_srli_epi64(*x, 32);
579 66241700 : const __m256i mult_hi = _mm256_srli_epi64(*y, 32);
580 33120900 : prod_hi = _mm256_mul_epi32(prod_hi, mult_hi);
581 :
582 33120900 : prod_lo = _mm256_srli_epi64(prod_lo, 15);
583 33120900 : const __m256i mask = _mm256_set_epi32(0, -1, 0, -1, 0, -1, 0, -1);
584 33120900 : prod_lo = _mm256_and_si256(prod_lo, mask);
585 33120900 : prod_hi = _mm256_srli_epi64(prod_hi, 15);
586 :
587 33120900 : prod_hi = _mm256_slli_epi64(prod_hi, 32);
588 33120900 : *p = _mm256_or_si256(prod_lo, prod_hi);
589 33120900 : }
590 :
591 525620000 : static INLINE void quantize_32x32(const __m256i *qp, __m256i *c,
592 : const int16_t *iscan_ptr, TranLow *qcoeff,
593 : TranLow *dqcoeff, __m256i *eob, __m256i min, __m256i max) {
594 525620000 : const __m256i abs = _mm256_abs_epi32(*c);
595 525620000 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
596 1051240000 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
597 525620000 : flag2 = _mm256_or_si256(flag1, flag2);
598 525620000 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
599 :
600 525620000 : if (LIKELY(nzflag)) {
601 33118600 : __m256i q = _mm256_add_epi32(abs, qp[1]);
602 33118600 : clamp_epi32(&q, min, max);
603 : __m256i tmp;
604 33113400 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
605 33120500 : q = _mm256_add_epi32(tmp, q);
606 :
607 33120500 : mm256_mul_shift_epi32_32x32(&q, &qp[4], &q);
608 66255700 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
609 33127800 : dq = _mm256_srli_epi32(dq, 1);
610 :
611 33127800 : q = _mm256_sign_epi32(q, *c);
612 33127800 : dq = _mm256_sign_epi32(dq, *c);
613 66255700 : q = _mm256_and_si256(q, flag2);
614 33127800 : dq = _mm256_and_si256(dq, flag2);
615 :
616 33127800 : _mm256_storeu_si256((__m256i *)qcoeff, q);
617 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
618 :
619 33127800 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
620 33127800 : const __m128i zr = _mm_setzero_si128();
621 33127800 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
622 33127800 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
623 33127800 : const __m256i iscan =
624 66255700 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
625 :
626 33127800 : const __m256i zero = _mm256_setzero_si256();
627 33127800 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
628 33127800 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
629 33127800 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
630 33127800 : cur_eob = _mm256_and_si256(cur_eob, nz);
631 66255700 : *eob = _mm256_max_epi32(cur_eob, *eob);
632 : }
633 : else {
634 492501000 : const __m256i zero = _mm256_setzero_si256();
635 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
636 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
637 : }
638 525629000 : }
639 :
640 6721170 : void eb_aom_quantize_b_32x32_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
641 : int skip_block, const int16_t *zbin_ptr,
642 : const int16_t *round_ptr,
643 : const int16_t *quant_ptr,
644 : const int16_t *quant_shift_ptr,
645 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
646 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
647 : const int16_t *scan, const int16_t *iscan) {
648 : (void)scan;
649 6721170 : const unsigned int step = 8;
650 :
651 6721170 : if (LIKELY(!skip_block)) {
652 : __m256i qp[5], coeff;
653 6721290 : init_qp_32x32(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
654 6721230 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
655 :
656 6721230 : __m256i eob = _mm256_setzero_si256();
657 6721230 : __m256i min = _mm256_set1_epi32(INT16_MIN);
658 6721230 : __m256i max = _mm256_set1_epi32(INT16_MAX);
659 6721230 : quantize_32x32(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
660 :
661 6721630 : coeff_ptr += step;
662 6721630 : qcoeff_ptr += step;
663 6721630 : dqcoeff_ptr += step;
664 6721630 : iscan += step;
665 6721630 : n_coeffs -= step;
666 :
667 6721630 : update_qp(qp);
668 :
669 526558000 : while (n_coeffs > 0) {
670 519836000 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
671 519836000 : quantize_32x32(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob, min, max);
672 :
673 519072000 : coeff_ptr += step;
674 519072000 : qcoeff_ptr += step;
675 519072000 : dqcoeff_ptr += step;
676 519072000 : iscan += step;
677 519072000 : n_coeffs -= step;
678 : }
679 : {
680 : __m256i eob_s;
681 6721940 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
682 6721940 : eob = _mm256_max_epi16(eob, eob_s);
683 6721940 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
684 6721940 : eob = _mm256_max_epi16(eob, eob_s);
685 6721940 : eob_s = _mm256_shufflelo_epi16(eob, 1);
686 6721940 : eob = _mm256_max_epi16(eob, eob_s);
687 6721940 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
688 6721940 : _mm256_extractf128_si256(eob, 1));
689 6721940 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
690 : }
691 : }
692 : else {
693 : do {
694 0 : const __m256i zero = _mm256_setzero_si256();
695 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
696 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
697 0 : qcoeff_ptr += step;
698 0 : dqcoeff_ptr += step;
699 0 : n_coeffs -= step;
700 0 : } while (n_coeffs > 0);
701 0 : *eob_ptr = 0;
702 : }
703 6721820 : }
704 :
705 0 : static INLINE void quantize_32x32_highbd(const __m256i *qp, __m256i *c,
706 : const int16_t *iscan_ptr, TranLow *qcoeff,
707 : TranLow *dqcoeff, __m256i *eob) {
708 0 : const __m256i abs = _mm256_abs_epi32(*c);
709 0 : const __m256i flag1 = _mm256_cmpgt_epi32(abs, qp[0]);
710 0 : __m256i flag2 = _mm256_cmpeq_epi32(abs, qp[0]);
711 0 : flag2 = _mm256_or_si256(flag1, flag2);
712 0 : const int32_t nzflag = _mm256_movemask_epi8(flag2);
713 :
714 0 : if (LIKELY(nzflag)) {
715 0 : __m256i q = _mm256_add_epi32(abs, qp[1]);
716 : __m256i tmp;
717 0 : mm256_mul_shift_epi32(&q, &qp[2], &tmp);
718 0 : q = _mm256_add_epi32(tmp, q);
719 :
720 0 : mm256_mul_shift_epi32_32x32(&q, &qp[4], &q);
721 0 : __m256i dq = _mm256_mullo_epi32(q, qp[3]);
722 0 : dq = _mm256_srli_epi32(dq, 1);
723 :
724 0 : q = _mm256_sign_epi32(q, *c);
725 0 : dq = _mm256_sign_epi32(dq, *c);
726 0 : q = _mm256_and_si256(q, flag2);
727 0 : dq = _mm256_and_si256(dq, flag2);
728 :
729 0 : _mm256_storeu_si256((__m256i *)qcoeff, q);
730 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
731 :
732 0 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
733 0 : const __m128i zr = _mm_setzero_si128();
734 0 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
735 0 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
736 0 : const __m256i iscan =
737 0 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
738 :
739 0 : const __m256i zero = _mm256_setzero_si256();
740 0 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
741 0 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
742 0 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
743 0 : cur_eob = _mm256_and_si256(cur_eob, nz);
744 0 : *eob = _mm256_max_epi32(cur_eob, *eob);
745 : }
746 : else {
747 0 : const __m256i zero = _mm256_setzero_si256();
748 : _mm256_storeu_si256((__m256i *)qcoeff, zero);
749 : _mm256_storeu_si256((__m256i *)dqcoeff, zero);
750 : }
751 0 : }
752 :
753 0 : void eb_aom_highbd_quantize_b_32x32_avx2(const TranLow *coeff_ptr, intptr_t n_coeffs,
754 : int skip_block, const int16_t *zbin_ptr,
755 : const int16_t *round_ptr,
756 : const int16_t *quant_ptr,
757 : const int16_t *quant_shift_ptr,
758 : TranLow *qcoeff_ptr, TranLow *dqcoeff_ptr,
759 : const int16_t *dequant_ptr, uint16_t *eob_ptr,
760 : const int16_t *scan, const int16_t *iscan) {
761 : (void)scan;
762 0 : const unsigned int step = 8;
763 :
764 0 : if (LIKELY(!skip_block)) {
765 : __m256i qp[5], coeff;
766 0 : init_qp_32x32(zbin_ptr, round_ptr, quant_ptr, dequant_ptr, quant_shift_ptr, qp);
767 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
768 :
769 0 : __m256i eob = _mm256_setzero_si256();
770 0 : quantize_32x32_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
771 :
772 0 : coeff_ptr += step;
773 0 : qcoeff_ptr += step;
774 0 : dqcoeff_ptr += step;
775 0 : iscan += step;
776 0 : n_coeffs -= step;
777 :
778 0 : update_qp(qp);
779 :
780 0 : while (n_coeffs > 0) {
781 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
782 0 : quantize_32x32_highbd(qp, &coeff, iscan, qcoeff_ptr, dqcoeff_ptr, &eob);
783 :
784 0 : coeff_ptr += step;
785 0 : qcoeff_ptr += step;
786 0 : dqcoeff_ptr += step;
787 0 : iscan += step;
788 0 : n_coeffs -= step;
789 : }
790 : {
791 : __m256i eob_s;
792 0 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
793 0 : eob = _mm256_max_epi16(eob, eob_s);
794 0 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
795 0 : eob = _mm256_max_epi16(eob, eob_s);
796 0 : eob_s = _mm256_shufflelo_epi16(eob, 1);
797 0 : eob = _mm256_max_epi16(eob, eob_s);
798 0 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
799 0 : _mm256_extractf128_si256(eob, 1));
800 0 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
801 : }
802 : }
803 : else {
804 : do {
805 0 : const __m256i zero = _mm256_setzero_si256();
806 : _mm256_storeu_si256((__m256i *)qcoeff_ptr, zero);
807 : _mm256_storeu_si256((__m256i *)dqcoeff_ptr, zero);
808 0 : qcoeff_ptr += step;
809 0 : dqcoeff_ptr += step;
810 0 : n_coeffs -= step;
811 0 : } while (n_coeffs > 0);
812 0 : *eob_ptr = 0;
813 : }
814 0 : }
815 :
816 0 : static INLINE void init_qp_fp(const int16_t *round_ptr, const int16_t *quant_ptr,
817 : const int16_t *dequant_ptr, int log_scale,
818 : __m256i *qp) {
819 0 : __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
820 0 : if (log_scale) {
821 0 : const __m128i round_scale = _mm_set1_epi16(1 << (15 - log_scale));
822 0 : round = _mm_mulhrs_epi16(round, round_scale);
823 : }
824 0 : const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
825 0 : const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);
826 :
827 0 : init_one_qp(&round, &qp[0]);
828 0 : init_one_qp(&quant, &qp[1]);
829 0 : init_one_qp(&dequant, &qp[2]);
830 0 : }
831 :
832 0 : static INLINE void quantize_highbd_fp(
833 : const __m256i *qp,
834 : __m256i *c,
835 : const int16_t *iscan_ptr,
836 : int log_scale,
837 : TranLow *qcoeff,
838 : TranLow *dqcoeff,
839 : __m256i *eob)
840 : {
841 0 : const __m256i abs_coeff = _mm256_abs_epi32(*c);
842 0 : __m256i q = _mm256_add_epi32(abs_coeff, qp[0]);
843 :
844 0 : __m256i q_lo = _mm256_mul_epi32(q, qp[1]);
845 0 : __m256i q_hi = _mm256_srli_epi64(q, 32);
846 0 : const __m256i qp_hi = _mm256_srli_epi64(qp[1], 32);
847 0 : q_hi = _mm256_mul_epi32(q_hi, qp_hi);
848 0 : q_lo = _mm256_srli_epi64(q_lo, 16 - log_scale);
849 0 : q_hi = _mm256_srli_epi64(q_hi, 16 - log_scale);
850 0 : q_hi = _mm256_slli_epi64(q_hi, 32);
851 0 : q = _mm256_or_si256(q_lo, q_hi);
852 0 : const __m256i abs_s = _mm256_slli_epi32(abs_coeff, 1 + log_scale);
853 0 : const __m256i mask = _mm256_cmpgt_epi32(qp[2], abs_s);
854 0 : q = _mm256_andnot_si256(mask, q);
855 :
856 0 : __m256i dq = _mm256_mullo_epi32(q, qp[2]);
857 0 : dq = _mm256_srai_epi32(dq, log_scale);
858 0 : q = _mm256_sign_epi32(q, *c);
859 0 : dq = _mm256_sign_epi32(dq, *c);
860 :
861 : _mm256_storeu_si256((__m256i *)qcoeff, q);
862 : _mm256_storeu_si256((__m256i *)dqcoeff, dq);
863 :
864 0 : const __m128i isc = _mm_loadu_si128((const __m128i *)iscan_ptr);
865 0 : const __m128i zr = _mm_setzero_si128();
866 0 : const __m128i lo = _mm_unpacklo_epi16(isc, zr);
867 0 : const __m128i hi = _mm_unpackhi_epi16(isc, zr);
868 0 : const __m256i iscan =
869 0 : _mm256_insertf128_si256(_mm256_castsi128_si256(lo), hi, 1);
870 :
871 0 : const __m256i zero = _mm256_setzero_si256();
872 0 : const __m256i zc = _mm256_cmpeq_epi32(dq, zero);
873 0 : const __m256i nz = _mm256_cmpeq_epi32(zc, zero);
874 0 : __m256i cur_eob = _mm256_sub_epi32(iscan, nz);
875 0 : cur_eob = _mm256_and_si256(cur_eob, nz);
876 0 : *eob = _mm256_max_epi32(cur_eob, *eob);
877 0 : }
878 :
879 0 : void eb_av1_highbd_quantize_fp_avx2(
880 : const TranLow *coeff_ptr,
881 : intptr_t n_coeffs,
882 : const int16_t *zbin_ptr,
883 : const int16_t *round_ptr,
884 : const int16_t *quant_ptr,
885 : const int16_t *quant_shift_ptr,
886 : TranLow *qcoeff_ptr,
887 : TranLow *dqcoeff_ptr,
888 : const int16_t *dequant_ptr,
889 : uint16_t *eob_ptr,
890 : const int16_t *scan,
891 : const int16_t *iscan,
892 : int16_t log_scale)
893 : {
894 : (void)scan;
895 : (void)zbin_ptr;
896 : (void)quant_shift_ptr;
897 0 : const unsigned int step = 8;
898 : __m256i qp[3], coeff;
899 :
900 0 : init_qp_fp(round_ptr, quant_ptr, dequant_ptr, log_scale, qp);
901 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
902 :
903 0 : __m256i eob = _mm256_setzero_si256();
904 0 : quantize_highbd_fp(qp, &coeff, iscan, log_scale, qcoeff_ptr, dqcoeff_ptr, &eob);
905 :
906 0 : coeff_ptr += step;
907 0 : qcoeff_ptr += step;
908 0 : dqcoeff_ptr += step;
909 0 : iscan += step;
910 0 : n_coeffs -= step;
911 :
912 0 : update_qp(qp);
913 0 : while (n_coeffs > 0) {
914 0 : coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
915 0 : quantize_highbd_fp(qp, &coeff, iscan, log_scale, qcoeff_ptr, dqcoeff_ptr, &eob);
916 :
917 0 : coeff_ptr += step;
918 0 : qcoeff_ptr += step;
919 0 : dqcoeff_ptr += step;
920 0 : iscan += step;
921 0 : n_coeffs -= step;
922 : }
923 :
924 : {
925 : __m256i eob_s;
926 0 : eob_s = _mm256_shuffle_epi32(eob, 0xe);
927 0 : eob = _mm256_max_epi16(eob, eob_s);
928 0 : eob_s = _mm256_shufflelo_epi16(eob, 0xe);
929 0 : eob = _mm256_max_epi16(eob, eob_s);
930 0 : eob_s = _mm256_shufflelo_epi16(eob, 1);
931 0 : eob = _mm256_max_epi16(eob, eob_s);
932 0 : const __m128i final_eob = _mm_max_epi16(_mm256_castsi256_si128(eob),
933 0 : _mm256_extractf128_si256(eob, 1));
934 0 : *eob_ptr = _mm_extract_epi16(final_eob, 0);
935 : }
936 0 : }
|