LCOV - code coverage report
Current view: top level - ASM_AVX2 - highbd_quantize_intrin_avx2.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 293 589 49.7 %
Date: 2019-11-25 17:38:06 Functions: 15 24 62.5 %

          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 : }

Generated by: LCOV version 1.14