LCOV - code coverage report
Current view: top level - third_party/aom/aom_dsp/x86 - sad_highbd_avx2.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 529 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016, Alliance for Open Media. All rights reserved
       3             :  *
       4             :  * This source code is subject to the terms of the BSD 2 Clause License and
       5             :  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
       6             :  * was not distributed with this source code in the LICENSE file, you can
       7             :  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
       8             :  * Media Patent License 1.0 was not distributed with this source code in the
       9             :  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
      10             :  */
      11             : 
      12             : #include <immintrin.h>
      13             : 
      14             : #include "./aom_config.h"
      15             : #include "./aom_dsp_rtcd.h"
      16             : 
      17             : #include "aom/aom_integer.h"
      18             : #include "aom_ports/mem.h"
      19             : 
      20             : // SAD
      21           0 : static INLINE unsigned int get_sad_from_mm256_epi32(const __m256i *v) {
      22             :   // input 8 32-bit summation
      23             :   __m128i lo128, hi128;
      24           0 :   __m256i u = _mm256_srli_si256(*v, 8);
      25           0 :   u = _mm256_add_epi32(u, *v);
      26             : 
      27             :   // 4 32-bit summation
      28           0 :   hi128 = _mm256_extracti128_si256(u, 1);
      29           0 :   lo128 = _mm256_castsi256_si128(u);
      30           0 :   lo128 = _mm_add_epi32(hi128, lo128);
      31             : 
      32             :   // 2 32-bit summation
      33           0 :   hi128 = _mm_srli_si128(lo128, 4);
      34           0 :   lo128 = _mm_add_epi32(lo128, hi128);
      35             : 
      36           0 :   return (unsigned int)_mm_cvtsi128_si32(lo128);
      37             : }
      38             : 
      39           0 : unsigned int aom_highbd_sad16x8_avx2(const uint8_t *src, int src_stride,
      40             :                                      const uint8_t *ref, int ref_stride) {
      41           0 :   const uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src);
      42           0 :   const uint16_t *ref_ptr = CONVERT_TO_SHORTPTR(ref);
      43             : 
      44             :   // first 4 rows
      45           0 :   __m256i s0 = _mm256_loadu_si256((const __m256i *)src_ptr);
      46           0 :   __m256i s1 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
      47           0 :   __m256i s2 = _mm256_loadu_si256((const __m256i *)(src_ptr + 2 * src_stride));
      48           0 :   __m256i s3 = _mm256_loadu_si256((const __m256i *)(src_ptr + 3 * src_stride));
      49             : 
      50           0 :   __m256i r0 = _mm256_loadu_si256((const __m256i *)ref_ptr);
      51           0 :   __m256i r1 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
      52           0 :   __m256i r2 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 2 * ref_stride));
      53           0 :   __m256i r3 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 3 * ref_stride));
      54             : 
      55           0 :   __m256i u0 = _mm256_sub_epi16(s0, r0);
      56           0 :   __m256i u1 = _mm256_sub_epi16(s1, r1);
      57           0 :   __m256i u2 = _mm256_sub_epi16(s2, r2);
      58           0 :   __m256i u3 = _mm256_sub_epi16(s3, r3);
      59           0 :   __m256i zero = _mm256_setzero_si256();
      60             :   __m256i sum0, sum1;
      61             : 
      62           0 :   u0 = _mm256_abs_epi16(u0);
      63           0 :   u1 = _mm256_abs_epi16(u1);
      64           0 :   u2 = _mm256_abs_epi16(u2);
      65           0 :   u3 = _mm256_abs_epi16(u3);
      66             : 
      67           0 :   sum0 = _mm256_add_epi16(u0, u1);
      68           0 :   sum0 = _mm256_add_epi16(sum0, u2);
      69           0 :   sum0 = _mm256_add_epi16(sum0, u3);
      70             : 
      71             :   // second 4 rows
      72           0 :   src_ptr += src_stride << 2;
      73           0 :   ref_ptr += ref_stride << 2;
      74           0 :   s0 = _mm256_loadu_si256((const __m256i *)src_ptr);
      75           0 :   s1 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
      76           0 :   s2 = _mm256_loadu_si256((const __m256i *)(src_ptr + 2 * src_stride));
      77           0 :   s3 = _mm256_loadu_si256((const __m256i *)(src_ptr + 3 * src_stride));
      78             : 
      79           0 :   r0 = _mm256_loadu_si256((const __m256i *)ref_ptr);
      80           0 :   r1 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
      81           0 :   r2 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 2 * ref_stride));
      82           0 :   r3 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 3 * ref_stride));
      83             : 
      84           0 :   u0 = _mm256_sub_epi16(s0, r0);
      85           0 :   u1 = _mm256_sub_epi16(s1, r1);
      86           0 :   u2 = _mm256_sub_epi16(s2, r2);
      87           0 :   u3 = _mm256_sub_epi16(s3, r3);
      88             : 
      89           0 :   u0 = _mm256_abs_epi16(u0);
      90           0 :   u1 = _mm256_abs_epi16(u1);
      91           0 :   u2 = _mm256_abs_epi16(u2);
      92           0 :   u3 = _mm256_abs_epi16(u3);
      93             : 
      94           0 :   sum1 = _mm256_add_epi16(u0, u1);
      95           0 :   sum1 = _mm256_add_epi16(sum1, u2);
      96           0 :   sum1 = _mm256_add_epi16(sum1, u3);
      97             : 
      98             :   // find out the SAD
      99           0 :   s0 = _mm256_unpacklo_epi16(sum0, zero);
     100           0 :   s1 = _mm256_unpackhi_epi16(sum0, zero);
     101           0 :   r0 = _mm256_unpacklo_epi16(sum1, zero);
     102           0 :   r1 = _mm256_unpackhi_epi16(sum1, zero);
     103           0 :   s0 = _mm256_add_epi32(s0, s1);
     104           0 :   r0 = _mm256_add_epi32(r0, r1);
     105           0 :   sum0 = _mm256_add_epi32(s0, r0);
     106             :   // 8 32-bit summation
     107             : 
     108           0 :   return (unsigned int)get_sad_from_mm256_epi32(&sum0);
     109             : }
     110             : 
     111           0 : unsigned int aom_highbd_sad16x16_avx2(const uint8_t *src, int src_stride,
     112             :                                       const uint8_t *ref, int ref_stride) {
     113           0 :   const uint16_t *src_ptr = CONVERT_TO_SHORTPTR(src);
     114           0 :   const uint16_t *ref_ptr = CONVERT_TO_SHORTPTR(ref);
     115             :   __m256i s0, s1, s2, s3, r0, r1, r2, r3, u0, u1, u2, u3;
     116             :   __m256i sum0;
     117           0 :   __m256i sum = _mm256_setzero_si256();
     118           0 :   const __m256i zero = _mm256_setzero_si256();
     119           0 :   int row = 0;
     120             : 
     121             :   // Loop for every 4 rows
     122           0 :   while (row < 16) {
     123           0 :     s0 = _mm256_loadu_si256((const __m256i *)src_ptr);
     124           0 :     s1 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
     125           0 :     s2 = _mm256_loadu_si256((const __m256i *)(src_ptr + 2 * src_stride));
     126           0 :     s3 = _mm256_loadu_si256((const __m256i *)(src_ptr + 3 * src_stride));
     127             : 
     128           0 :     r0 = _mm256_loadu_si256((const __m256i *)ref_ptr);
     129           0 :     r1 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
     130           0 :     r2 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 2 * ref_stride));
     131           0 :     r3 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 3 * ref_stride));
     132             : 
     133           0 :     u0 = _mm256_sub_epi16(s0, r0);
     134           0 :     u1 = _mm256_sub_epi16(s1, r1);
     135           0 :     u2 = _mm256_sub_epi16(s2, r2);
     136           0 :     u3 = _mm256_sub_epi16(s3, r3);
     137             : 
     138           0 :     u0 = _mm256_abs_epi16(u0);
     139           0 :     u1 = _mm256_abs_epi16(u1);
     140           0 :     u2 = _mm256_abs_epi16(u2);
     141           0 :     u3 = _mm256_abs_epi16(u3);
     142             : 
     143           0 :     sum0 = _mm256_add_epi16(u0, u1);
     144           0 :     sum0 = _mm256_add_epi16(sum0, u2);
     145           0 :     sum0 = _mm256_add_epi16(sum0, u3);
     146             : 
     147           0 :     s0 = _mm256_unpacklo_epi16(sum0, zero);
     148           0 :     s1 = _mm256_unpackhi_epi16(sum0, zero);
     149           0 :     sum = _mm256_add_epi32(sum, s0);
     150           0 :     sum = _mm256_add_epi32(sum, s1);
     151             :     // 8 32-bit summation
     152             : 
     153           0 :     row += 4;
     154           0 :     src_ptr += src_stride << 2;
     155           0 :     ref_ptr += ref_stride << 2;
     156             :   }
     157           0 :   return get_sad_from_mm256_epi32(&sum);
     158             : }
     159             : 
     160           0 : static void sad32x4(const uint16_t *src_ptr, int src_stride,
     161             :                     const uint16_t *ref_ptr, int ref_stride,
     162             :                     const uint16_t *sec_ptr, __m256i *sad_acc) {
     163             :   __m256i s0, s1, s2, s3, r0, r1, r2, r3;
     164           0 :   const __m256i zero = _mm256_setzero_si256();
     165           0 :   int row_sections = 0;
     166             : 
     167           0 :   while (row_sections < 2) {
     168           0 :     s0 = _mm256_loadu_si256((const __m256i *)src_ptr);
     169           0 :     s1 = _mm256_loadu_si256((const __m256i *)(src_ptr + 16));
     170           0 :     s2 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
     171           0 :     s3 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride + 16));
     172             : 
     173           0 :     r0 = _mm256_loadu_si256((const __m256i *)ref_ptr);
     174           0 :     r1 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 16));
     175           0 :     r2 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
     176           0 :     r3 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride + 16));
     177             : 
     178           0 :     if (sec_ptr) {
     179           0 :       r0 = _mm256_avg_epu16(r0, _mm256_loadu_si256((const __m256i *)sec_ptr));
     180           0 :       r1 = _mm256_avg_epu16(
     181           0 :           r1, _mm256_loadu_si256((const __m256i *)(sec_ptr + 16)));
     182           0 :       r2 = _mm256_avg_epu16(
     183           0 :           r2, _mm256_loadu_si256((const __m256i *)(sec_ptr + 32)));
     184           0 :       r3 = _mm256_avg_epu16(
     185           0 :           r3, _mm256_loadu_si256((const __m256i *)(sec_ptr + 48)));
     186             :     }
     187           0 :     s0 = _mm256_sub_epi16(s0, r0);
     188           0 :     s1 = _mm256_sub_epi16(s1, r1);
     189           0 :     s2 = _mm256_sub_epi16(s2, r2);
     190           0 :     s3 = _mm256_sub_epi16(s3, r3);
     191             : 
     192           0 :     s0 = _mm256_abs_epi16(s0);
     193           0 :     s1 = _mm256_abs_epi16(s1);
     194           0 :     s2 = _mm256_abs_epi16(s2);
     195           0 :     s3 = _mm256_abs_epi16(s3);
     196             : 
     197           0 :     s0 = _mm256_add_epi16(s0, s1);
     198           0 :     s0 = _mm256_add_epi16(s0, s2);
     199           0 :     s0 = _mm256_add_epi16(s0, s3);
     200             : 
     201           0 :     r0 = _mm256_unpacklo_epi16(s0, zero);
     202           0 :     r1 = _mm256_unpackhi_epi16(s0, zero);
     203             : 
     204           0 :     r0 = _mm256_add_epi32(r0, r1);
     205           0 :     *sad_acc = _mm256_add_epi32(*sad_acc, r0);
     206             : 
     207           0 :     row_sections += 1;
     208           0 :     src_ptr += src_stride << 1;
     209           0 :     ref_ptr += ref_stride << 1;
     210           0 :     if (sec_ptr) sec_ptr += 32 << 1;
     211             :   }
     212           0 : }
     213             : 
     214           0 : unsigned int aom_highbd_sad32x16_avx2(const uint8_t *src, int src_stride,
     215             :                                       const uint8_t *ref, int ref_stride) {
     216           0 :   __m256i sad = _mm256_setzero_si256();
     217           0 :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     218           0 :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     219           0 :   const int left_shift = 2;
     220           0 :   int row_section = 0;
     221             : 
     222           0 :   while (row_section < 4) {
     223           0 :     sad32x4(srcp, src_stride, refp, ref_stride, NULL, &sad);
     224           0 :     srcp += src_stride << left_shift;
     225           0 :     refp += ref_stride << left_shift;
     226           0 :     row_section += 1;
     227             :   }
     228           0 :   return get_sad_from_mm256_epi32(&sad);
     229             : }
     230             : 
     231           0 : unsigned int aom_highbd_sad16x32_avx2(const uint8_t *src, int src_stride,
     232             :                                       const uint8_t *ref, int ref_stride) {
     233           0 :   uint32_t sum = aom_highbd_sad16x16_avx2(src, src_stride, ref, ref_stride);
     234           0 :   src += src_stride << 4;
     235           0 :   ref += ref_stride << 4;
     236           0 :   sum += aom_highbd_sad16x16_avx2(src, src_stride, ref, ref_stride);
     237           0 :   return sum;
     238             : }
     239             : 
     240           0 : unsigned int aom_highbd_sad32x32_avx2(const uint8_t *src, int src_stride,
     241             :                                       const uint8_t *ref, int ref_stride) {
     242           0 :   uint32_t sum = aom_highbd_sad32x16_avx2(src, src_stride, ref, ref_stride);
     243           0 :   src += src_stride << 4;
     244           0 :   ref += ref_stride << 4;
     245           0 :   sum += aom_highbd_sad32x16_avx2(src, src_stride, ref, ref_stride);
     246           0 :   return sum;
     247             : }
     248             : 
     249           0 : unsigned int aom_highbd_sad32x64_avx2(const uint8_t *src, int src_stride,
     250             :                                       const uint8_t *ref, int ref_stride) {
     251           0 :   uint32_t sum = aom_highbd_sad32x32_avx2(src, src_stride, ref, ref_stride);
     252           0 :   src += src_stride << 5;
     253           0 :   ref += ref_stride << 5;
     254           0 :   sum += aom_highbd_sad32x32_avx2(src, src_stride, ref, ref_stride);
     255           0 :   return sum;
     256             : }
     257             : 
     258           0 : static void sad64x2(const uint16_t *src_ptr, int src_stride,
     259             :                     const uint16_t *ref_ptr, int ref_stride,
     260             :                     const uint16_t *sec_ptr, __m256i *sad_acc) {
     261             :   __m256i s[8], r[8];
     262           0 :   const __m256i zero = _mm256_setzero_si256();
     263             : 
     264           0 :   s[0] = _mm256_loadu_si256((const __m256i *)src_ptr);
     265           0 :   s[1] = _mm256_loadu_si256((const __m256i *)(src_ptr + 16));
     266           0 :   s[2] = _mm256_loadu_si256((const __m256i *)(src_ptr + 32));
     267           0 :   s[3] = _mm256_loadu_si256((const __m256i *)(src_ptr + 48));
     268           0 :   s[4] = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
     269           0 :   s[5] = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride + 16));
     270           0 :   s[6] = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride + 32));
     271           0 :   s[7] = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride + 48));
     272             : 
     273           0 :   r[0] = _mm256_loadu_si256((const __m256i *)ref_ptr);
     274           0 :   r[1] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 16));
     275           0 :   r[2] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 32));
     276           0 :   r[3] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 48));
     277           0 :   r[4] = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
     278           0 :   r[5] = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride + 16));
     279           0 :   r[6] = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride + 32));
     280           0 :   r[7] = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride + 48));
     281             : 
     282           0 :   if (sec_ptr) {
     283           0 :     r[0] = _mm256_avg_epu16(r[0], _mm256_loadu_si256((const __m256i *)sec_ptr));
     284           0 :     r[1] = _mm256_avg_epu16(
     285           0 :         r[1], _mm256_loadu_si256((const __m256i *)(sec_ptr + 16)));
     286           0 :     r[2] = _mm256_avg_epu16(
     287           0 :         r[2], _mm256_loadu_si256((const __m256i *)(sec_ptr + 32)));
     288           0 :     r[3] = _mm256_avg_epu16(
     289           0 :         r[3], _mm256_loadu_si256((const __m256i *)(sec_ptr + 48)));
     290           0 :     r[4] = _mm256_avg_epu16(
     291           0 :         r[4], _mm256_loadu_si256((const __m256i *)(sec_ptr + 64)));
     292           0 :     r[5] = _mm256_avg_epu16(
     293           0 :         r[5], _mm256_loadu_si256((const __m256i *)(sec_ptr + 80)));
     294           0 :     r[6] = _mm256_avg_epu16(
     295           0 :         r[6], _mm256_loadu_si256((const __m256i *)(sec_ptr + 96)));
     296           0 :     r[7] = _mm256_avg_epu16(
     297           0 :         r[7], _mm256_loadu_si256((const __m256i *)(sec_ptr + 112)));
     298             :   }
     299             : 
     300           0 :   s[0] = _mm256_sub_epi16(s[0], r[0]);
     301           0 :   s[1] = _mm256_sub_epi16(s[1], r[1]);
     302           0 :   s[2] = _mm256_sub_epi16(s[2], r[2]);
     303           0 :   s[3] = _mm256_sub_epi16(s[3], r[3]);
     304           0 :   s[4] = _mm256_sub_epi16(s[4], r[4]);
     305           0 :   s[5] = _mm256_sub_epi16(s[5], r[5]);
     306           0 :   s[6] = _mm256_sub_epi16(s[6], r[6]);
     307           0 :   s[7] = _mm256_sub_epi16(s[7], r[7]);
     308             : 
     309           0 :   s[0] = _mm256_abs_epi16(s[0]);
     310           0 :   s[1] = _mm256_abs_epi16(s[1]);
     311           0 :   s[2] = _mm256_abs_epi16(s[2]);
     312           0 :   s[3] = _mm256_abs_epi16(s[3]);
     313           0 :   s[4] = _mm256_abs_epi16(s[4]);
     314           0 :   s[5] = _mm256_abs_epi16(s[5]);
     315           0 :   s[6] = _mm256_abs_epi16(s[6]);
     316           0 :   s[7] = _mm256_abs_epi16(s[7]);
     317             : 
     318           0 :   s[0] = _mm256_add_epi16(s[0], s[1]);
     319           0 :   s[0] = _mm256_add_epi16(s[0], s[2]);
     320           0 :   s[0] = _mm256_add_epi16(s[0], s[3]);
     321             : 
     322           0 :   s[4] = _mm256_add_epi16(s[4], s[5]);
     323           0 :   s[4] = _mm256_add_epi16(s[4], s[6]);
     324           0 :   s[4] = _mm256_add_epi16(s[4], s[7]);
     325             : 
     326           0 :   r[0] = _mm256_unpacklo_epi16(s[0], zero);
     327           0 :   r[1] = _mm256_unpackhi_epi16(s[0], zero);
     328           0 :   r[2] = _mm256_unpacklo_epi16(s[4], zero);
     329           0 :   r[3] = _mm256_unpackhi_epi16(s[4], zero);
     330             : 
     331           0 :   r[0] = _mm256_add_epi32(r[0], r[1]);
     332           0 :   r[0] = _mm256_add_epi32(r[0], r[2]);
     333           0 :   r[0] = _mm256_add_epi32(r[0], r[3]);
     334           0 :   *sad_acc = _mm256_add_epi32(*sad_acc, r[0]);
     335           0 : }
     336             : 
     337           0 : unsigned int aom_highbd_sad64x32_avx2(const uint8_t *src, int src_stride,
     338             :                                       const uint8_t *ref, int ref_stride) {
     339           0 :   __m256i sad = _mm256_setzero_si256();
     340           0 :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     341           0 :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     342           0 :   const int left_shift = 1;
     343           0 :   int row_section = 0;
     344             : 
     345           0 :   while (row_section < 16) {
     346           0 :     sad64x2(srcp, src_stride, refp, ref_stride, NULL, &sad);
     347           0 :     srcp += src_stride << left_shift;
     348           0 :     refp += ref_stride << left_shift;
     349           0 :     row_section += 1;
     350             :   }
     351           0 :   return get_sad_from_mm256_epi32(&sad);
     352             : }
     353             : 
     354           0 : unsigned int aom_highbd_sad64x64_avx2(const uint8_t *src, int src_stride,
     355             :                                       const uint8_t *ref, int ref_stride) {
     356           0 :   uint32_t sum = aom_highbd_sad64x32_avx2(src, src_stride, ref, ref_stride);
     357           0 :   src += src_stride << 5;
     358           0 :   ref += ref_stride << 5;
     359           0 :   sum += aom_highbd_sad64x32_avx2(src, src_stride, ref, ref_stride);
     360           0 :   return sum;
     361             : }
     362             : 
     363             : #if CONFIG_EXT_PARTITION
     364             : static void sad128x1(const uint16_t *src_ptr, const uint16_t *ref_ptr,
     365             :                      const uint16_t *sec_ptr, __m256i *sad_acc) {
     366             :   __m256i s[8], r[8];
     367             :   const __m256i zero = _mm256_setzero_si256();
     368             : 
     369             :   s[0] = _mm256_loadu_si256((const __m256i *)src_ptr);
     370             :   s[1] = _mm256_loadu_si256((const __m256i *)(src_ptr + 16));
     371             :   s[2] = _mm256_loadu_si256((const __m256i *)(src_ptr + 32));
     372             :   s[3] = _mm256_loadu_si256((const __m256i *)(src_ptr + 48));
     373             :   s[4] = _mm256_loadu_si256((const __m256i *)(src_ptr + 64));
     374             :   s[5] = _mm256_loadu_si256((const __m256i *)(src_ptr + 80));
     375             :   s[6] = _mm256_loadu_si256((const __m256i *)(src_ptr + 96));
     376             :   s[7] = _mm256_loadu_si256((const __m256i *)(src_ptr + 112));
     377             : 
     378             :   r[0] = _mm256_loadu_si256((const __m256i *)ref_ptr);
     379             :   r[1] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 16));
     380             :   r[2] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 32));
     381             :   r[3] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 48));
     382             :   r[4] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 64));
     383             :   r[5] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 80));
     384             :   r[6] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 96));
     385             :   r[7] = _mm256_loadu_si256((const __m256i *)(ref_ptr + 112));
     386             : 
     387             :   if (sec_ptr) {
     388             :     r[0] = _mm256_avg_epu16(r[0], _mm256_loadu_si256((const __m256i *)sec_ptr));
     389             :     r[1] = _mm256_avg_epu16(
     390             :         r[1], _mm256_loadu_si256((const __m256i *)(sec_ptr + 16)));
     391             :     r[2] = _mm256_avg_epu16(
     392             :         r[2], _mm256_loadu_si256((const __m256i *)(sec_ptr + 32)));
     393             :     r[3] = _mm256_avg_epu16(
     394             :         r[3], _mm256_loadu_si256((const __m256i *)(sec_ptr + 48)));
     395             :     r[4] = _mm256_avg_epu16(
     396             :         r[4], _mm256_loadu_si256((const __m256i *)(sec_ptr + 64)));
     397             :     r[5] = _mm256_avg_epu16(
     398             :         r[5], _mm256_loadu_si256((const __m256i *)(sec_ptr + 80)));
     399             :     r[6] = _mm256_avg_epu16(
     400             :         r[6], _mm256_loadu_si256((const __m256i *)(sec_ptr + 96)));
     401             :     r[7] = _mm256_avg_epu16(
     402             :         r[7], _mm256_loadu_si256((const __m256i *)(sec_ptr + 112)));
     403             :   }
     404             : 
     405             :   s[0] = _mm256_sub_epi16(s[0], r[0]);
     406             :   s[1] = _mm256_sub_epi16(s[1], r[1]);
     407             :   s[2] = _mm256_sub_epi16(s[2], r[2]);
     408             :   s[3] = _mm256_sub_epi16(s[3], r[3]);
     409             :   s[4] = _mm256_sub_epi16(s[4], r[4]);
     410             :   s[5] = _mm256_sub_epi16(s[5], r[5]);
     411             :   s[6] = _mm256_sub_epi16(s[6], r[6]);
     412             :   s[7] = _mm256_sub_epi16(s[7], r[7]);
     413             : 
     414             :   s[0] = _mm256_abs_epi16(s[0]);
     415             :   s[1] = _mm256_abs_epi16(s[1]);
     416             :   s[2] = _mm256_abs_epi16(s[2]);
     417             :   s[3] = _mm256_abs_epi16(s[3]);
     418             :   s[4] = _mm256_abs_epi16(s[4]);
     419             :   s[5] = _mm256_abs_epi16(s[5]);
     420             :   s[6] = _mm256_abs_epi16(s[6]);
     421             :   s[7] = _mm256_abs_epi16(s[7]);
     422             : 
     423             :   s[0] = _mm256_add_epi16(s[0], s[1]);
     424             :   s[0] = _mm256_add_epi16(s[0], s[2]);
     425             :   s[0] = _mm256_add_epi16(s[0], s[3]);
     426             : 
     427             :   s[4] = _mm256_add_epi16(s[4], s[5]);
     428             :   s[4] = _mm256_add_epi16(s[4], s[6]);
     429             :   s[4] = _mm256_add_epi16(s[4], s[7]);
     430             : 
     431             :   r[0] = _mm256_unpacklo_epi16(s[0], zero);
     432             :   r[1] = _mm256_unpackhi_epi16(s[0], zero);
     433             :   r[2] = _mm256_unpacklo_epi16(s[4], zero);
     434             :   r[3] = _mm256_unpackhi_epi16(s[4], zero);
     435             : 
     436             :   r[0] = _mm256_add_epi32(r[0], r[1]);
     437             :   r[0] = _mm256_add_epi32(r[0], r[2]);
     438             :   r[0] = _mm256_add_epi32(r[0], r[3]);
     439             :   *sad_acc = _mm256_add_epi32(*sad_acc, r[0]);
     440             : }
     441             : 
     442             : unsigned int aom_highbd_sad128x64_avx2(const uint8_t *src, int src_stride,
     443             :                                        const uint8_t *ref, int ref_stride) {
     444             :   __m256i sad = _mm256_setzero_si256();
     445             :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     446             :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     447             :   int row = 0;
     448             :   while (row < 64) {
     449             :     sad128x1(srcp, refp, NULL, &sad);
     450             :     srcp += src_stride;
     451             :     refp += ref_stride;
     452             :     row += 1;
     453             :   }
     454             :   return get_sad_from_mm256_epi32(&sad);
     455             : }
     456             : 
     457             : unsigned int aom_highbd_sad64x128_avx2(const uint8_t *src, int src_stride,
     458             :                                        const uint8_t *ref, int ref_stride) {
     459             :   uint32_t sum = aom_highbd_sad64x64_avx2(src, src_stride, ref, ref_stride);
     460             :   src += src_stride << 6;
     461             :   ref += ref_stride << 6;
     462             :   sum += aom_highbd_sad64x64_avx2(src, src_stride, ref, ref_stride);
     463             :   return sum;
     464             : }
     465             : 
     466             : unsigned int aom_highbd_sad128x128_avx2(const uint8_t *src, int src_stride,
     467             :                                         const uint8_t *ref, int ref_stride) {
     468             :   uint32_t sum = aom_highbd_sad128x64_avx2(src, src_stride, ref, ref_stride);
     469             :   src += src_stride << 6;
     470             :   ref += ref_stride << 6;
     471             :   sum += aom_highbd_sad128x64_avx2(src, src_stride, ref, ref_stride);
     472             :   return sum;
     473             : }
     474             : #endif  // CONFIG_EXT_PARTITION
     475             : 
     476             : // If sec_ptr = 0, calculate regular SAD. Otherwise, calculate average SAD.
     477           0 : static INLINE void sad16x4(const uint16_t *src_ptr, int src_stride,
     478             :                            const uint16_t *ref_ptr, int ref_stride,
     479             :                            const uint16_t *sec_ptr, __m256i *sad_acc) {
     480             :   __m256i s0, s1, s2, s3, r0, r1, r2, r3;
     481           0 :   const __m256i zero = _mm256_setzero_si256();
     482             : 
     483           0 :   s0 = _mm256_loadu_si256((const __m256i *)src_ptr);
     484           0 :   s1 = _mm256_loadu_si256((const __m256i *)(src_ptr + src_stride));
     485           0 :   s2 = _mm256_loadu_si256((const __m256i *)(src_ptr + 2 * src_stride));
     486           0 :   s3 = _mm256_loadu_si256((const __m256i *)(src_ptr + 3 * src_stride));
     487             : 
     488           0 :   r0 = _mm256_loadu_si256((const __m256i *)ref_ptr);
     489           0 :   r1 = _mm256_loadu_si256((const __m256i *)(ref_ptr + ref_stride));
     490           0 :   r2 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 2 * ref_stride));
     491           0 :   r3 = _mm256_loadu_si256((const __m256i *)(ref_ptr + 3 * ref_stride));
     492             : 
     493           0 :   if (sec_ptr) {
     494           0 :     r0 = _mm256_avg_epu16(r0, _mm256_loadu_si256((const __m256i *)sec_ptr));
     495           0 :     r1 = _mm256_avg_epu16(r1,
     496           0 :                           _mm256_loadu_si256((const __m256i *)(sec_ptr + 16)));
     497           0 :     r2 = _mm256_avg_epu16(r2,
     498           0 :                           _mm256_loadu_si256((const __m256i *)(sec_ptr + 32)));
     499           0 :     r3 = _mm256_avg_epu16(r3,
     500           0 :                           _mm256_loadu_si256((const __m256i *)(sec_ptr + 48)));
     501             :   }
     502             : 
     503           0 :   s0 = _mm256_sub_epi16(s0, r0);
     504           0 :   s1 = _mm256_sub_epi16(s1, r1);
     505           0 :   s2 = _mm256_sub_epi16(s2, r2);
     506           0 :   s3 = _mm256_sub_epi16(s3, r3);
     507             : 
     508           0 :   s0 = _mm256_abs_epi16(s0);
     509           0 :   s1 = _mm256_abs_epi16(s1);
     510           0 :   s2 = _mm256_abs_epi16(s2);
     511           0 :   s3 = _mm256_abs_epi16(s3);
     512             : 
     513           0 :   s0 = _mm256_add_epi16(s0, s1);
     514           0 :   s0 = _mm256_add_epi16(s0, s2);
     515           0 :   s0 = _mm256_add_epi16(s0, s3);
     516             : 
     517           0 :   r0 = _mm256_unpacklo_epi16(s0, zero);
     518           0 :   r1 = _mm256_unpackhi_epi16(s0, zero);
     519             : 
     520           0 :   r0 = _mm256_add_epi32(r0, r1);
     521           0 :   *sad_acc = _mm256_add_epi32(*sad_acc, r0);
     522           0 : }
     523             : 
     524           0 : unsigned int aom_highbd_sad16x8_avg_avx2(const uint8_t *src, int src_stride,
     525             :                                          const uint8_t *ref, int ref_stride,
     526             :                                          const uint8_t *second_pred) {
     527           0 :   __m256i sad = _mm256_setzero_si256();
     528           0 :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     529           0 :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     530           0 :   uint16_t *secp = CONVERT_TO_SHORTPTR(second_pred);
     531             : 
     532           0 :   sad16x4(srcp, src_stride, refp, ref_stride, secp, &sad);
     533             : 
     534             :   // Next 4 rows
     535           0 :   srcp += src_stride << 2;
     536           0 :   refp += ref_stride << 2;
     537           0 :   secp += 64;
     538           0 :   sad16x4(srcp, src_stride, refp, ref_stride, secp, &sad);
     539           0 :   return get_sad_from_mm256_epi32(&sad);
     540             : }
     541             : 
     542           0 : unsigned int aom_highbd_sad16x16_avg_avx2(const uint8_t *src, int src_stride,
     543             :                                           const uint8_t *ref, int ref_stride,
     544             :                                           const uint8_t *second_pred) {
     545           0 :   const int left_shift = 3;
     546           0 :   uint32_t sum = aom_highbd_sad16x8_avg_avx2(src, src_stride, ref, ref_stride,
     547             :                                              second_pred);
     548           0 :   src += src_stride << left_shift;
     549           0 :   ref += ref_stride << left_shift;
     550           0 :   second_pred += 16 << left_shift;
     551           0 :   sum += aom_highbd_sad16x8_avg_avx2(src, src_stride, ref, ref_stride,
     552             :                                      second_pred);
     553           0 :   return sum;
     554             : }
     555             : 
     556           0 : unsigned int aom_highbd_sad16x32_avg_avx2(const uint8_t *src, int src_stride,
     557             :                                           const uint8_t *ref, int ref_stride,
     558             :                                           const uint8_t *second_pred) {
     559           0 :   const int left_shift = 4;
     560           0 :   uint32_t sum = aom_highbd_sad16x16_avg_avx2(src, src_stride, ref, ref_stride,
     561             :                                               second_pred);
     562           0 :   src += src_stride << left_shift;
     563           0 :   ref += ref_stride << left_shift;
     564           0 :   second_pred += 16 << left_shift;
     565           0 :   sum += aom_highbd_sad16x16_avg_avx2(src, src_stride, ref, ref_stride,
     566             :                                       second_pred);
     567           0 :   return sum;
     568             : }
     569             : 
     570           0 : unsigned int aom_highbd_sad32x16_avg_avx2(const uint8_t *src, int src_stride,
     571             :                                           const uint8_t *ref, int ref_stride,
     572             :                                           const uint8_t *second_pred) {
     573           0 :   __m256i sad = _mm256_setzero_si256();
     574           0 :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     575           0 :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     576           0 :   uint16_t *secp = CONVERT_TO_SHORTPTR(second_pred);
     577           0 :   const int left_shift = 2;
     578           0 :   int row_section = 0;
     579             : 
     580           0 :   while (row_section < 4) {
     581           0 :     sad32x4(srcp, src_stride, refp, ref_stride, secp, &sad);
     582           0 :     srcp += src_stride << left_shift;
     583           0 :     refp += ref_stride << left_shift;
     584           0 :     secp += 32 << left_shift;
     585           0 :     row_section += 1;
     586             :   }
     587           0 :   return get_sad_from_mm256_epi32(&sad);
     588             : }
     589             : 
     590           0 : unsigned int aom_highbd_sad32x32_avg_avx2(const uint8_t *src, int src_stride,
     591             :                                           const uint8_t *ref, int ref_stride,
     592             :                                           const uint8_t *second_pred) {
     593           0 :   const int left_shift = 4;
     594           0 :   uint32_t sum = aom_highbd_sad32x16_avg_avx2(src, src_stride, ref, ref_stride,
     595             :                                               second_pred);
     596           0 :   src += src_stride << left_shift;
     597           0 :   ref += ref_stride << left_shift;
     598           0 :   second_pred += 32 << left_shift;
     599           0 :   sum += aom_highbd_sad32x16_avg_avx2(src, src_stride, ref, ref_stride,
     600             :                                       second_pred);
     601           0 :   return sum;
     602             : }
     603             : 
     604           0 : unsigned int aom_highbd_sad32x64_avg_avx2(const uint8_t *src, int src_stride,
     605             :                                           const uint8_t *ref, int ref_stride,
     606             :                                           const uint8_t *second_pred) {
     607           0 :   const int left_shift = 5;
     608           0 :   uint32_t sum = aom_highbd_sad32x32_avg_avx2(src, src_stride, ref, ref_stride,
     609             :                                               second_pred);
     610           0 :   src += src_stride << left_shift;
     611           0 :   ref += ref_stride << left_shift;
     612           0 :   second_pred += 32 << left_shift;
     613           0 :   sum += aom_highbd_sad32x32_avg_avx2(src, src_stride, ref, ref_stride,
     614             :                                       second_pred);
     615           0 :   return sum;
     616             : }
     617             : 
     618           0 : unsigned int aom_highbd_sad64x32_avg_avx2(const uint8_t *src, int src_stride,
     619             :                                           const uint8_t *ref, int ref_stride,
     620             :                                           const uint8_t *second_pred) {
     621           0 :   __m256i sad = _mm256_setzero_si256();
     622           0 :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     623           0 :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     624           0 :   uint16_t *secp = CONVERT_TO_SHORTPTR(second_pred);
     625           0 :   const int left_shift = 1;
     626           0 :   int row_section = 0;
     627             : 
     628           0 :   while (row_section < 16) {
     629           0 :     sad64x2(srcp, src_stride, refp, ref_stride, secp, &sad);
     630           0 :     srcp += src_stride << left_shift;
     631           0 :     refp += ref_stride << left_shift;
     632           0 :     secp += 64 << left_shift;
     633           0 :     row_section += 1;
     634             :   }
     635           0 :   return get_sad_from_mm256_epi32(&sad);
     636             : }
     637             : 
     638           0 : unsigned int aom_highbd_sad64x64_avg_avx2(const uint8_t *src, int src_stride,
     639             :                                           const uint8_t *ref, int ref_stride,
     640             :                                           const uint8_t *second_pred) {
     641           0 :   const int left_shift = 5;
     642           0 :   uint32_t sum = aom_highbd_sad64x32_avg_avx2(src, src_stride, ref, ref_stride,
     643             :                                               second_pred);
     644           0 :   src += src_stride << left_shift;
     645           0 :   ref += ref_stride << left_shift;
     646           0 :   second_pred += 64 << left_shift;
     647           0 :   sum += aom_highbd_sad64x32_avg_avx2(src, src_stride, ref, ref_stride,
     648             :                                       second_pred);
     649           0 :   return sum;
     650             : }
     651             : 
     652             : #if CONFIG_EXT_PARTITION
     653             : unsigned int aom_highbd_sad64x128_avg_avx2(const uint8_t *src, int src_stride,
     654             :                                            const uint8_t *ref, int ref_stride,
     655             :                                            const uint8_t *second_pred) {
     656             :   const int left_shift = 6;
     657             :   uint32_t sum = aom_highbd_sad64x64_avg_avx2(src, src_stride, ref, ref_stride,
     658             :                                               second_pred);
     659             :   src += src_stride << left_shift;
     660             :   ref += ref_stride << left_shift;
     661             :   second_pred += 64 << left_shift;
     662             :   sum += aom_highbd_sad64x64_avg_avx2(src, src_stride, ref, ref_stride,
     663             :                                       second_pred);
     664             :   return sum;
     665             : }
     666             : 
     667             : unsigned int aom_highbd_sad128x64_avg_avx2(const uint8_t *src, int src_stride,
     668             :                                            const uint8_t *ref, int ref_stride,
     669             :                                            const uint8_t *second_pred) {
     670             :   __m256i sad = _mm256_setzero_si256();
     671             :   uint16_t *srcp = CONVERT_TO_SHORTPTR(src);
     672             :   uint16_t *refp = CONVERT_TO_SHORTPTR(ref);
     673             :   uint16_t *secp = CONVERT_TO_SHORTPTR(second_pred);
     674             :   int row = 0;
     675             :   while (row < 64) {
     676             :     sad128x1(srcp, refp, secp, &sad);
     677             :     srcp += src_stride;
     678             :     refp += ref_stride;
     679             :     secp += 16 << 3;
     680             :     row += 1;
     681             :   }
     682             :   return get_sad_from_mm256_epi32(&sad);
     683             : }
     684             : 
     685             : unsigned int aom_highbd_sad128x128_avg_avx2(const uint8_t *src, int src_stride,
     686             :                                             const uint8_t *ref, int ref_stride,
     687             :                                             const uint8_t *second_pred) {
     688             :   unsigned int sum;
     689             :   const int left_shift = 6;
     690             : 
     691             :   sum = aom_highbd_sad128x64_avg_avx2(src, src_stride, ref, ref_stride,
     692             :                                       second_pred);
     693             :   src += src_stride << left_shift;
     694             :   ref += ref_stride << left_shift;
     695             :   second_pred += 128 << left_shift;
     696             :   sum += aom_highbd_sad128x64_avg_avx2(src, src_stride, ref, ref_stride,
     697             :                                        second_pred);
     698             :   return sum;
     699             : }
     700             : #endif  // CONFIG_EXT_PARTITION
     701             : 
     702             : // SAD 4D
     703             : // Combine 4 __m256i vectors to uint32_t result[4]
     704           0 : static INLINE void get_4d_sad_from_mm256_epi32(const __m256i *v,
     705             :                                                uint32_t *res) {
     706             :   __m256i u0, u1, u2, u3;
     707           0 :   const __m256i mask = _mm256_set1_epi64x(UINT32_MAX);
     708             :   __m128i sad;
     709             : 
     710             :   // 8 32-bit summation
     711           0 :   u0 = _mm256_srli_si256(v[0], 4);
     712           0 :   u1 = _mm256_srli_si256(v[1], 4);
     713           0 :   u2 = _mm256_srli_si256(v[2], 4);
     714           0 :   u3 = _mm256_srli_si256(v[3], 4);
     715             : 
     716           0 :   u0 = _mm256_add_epi32(u0, v[0]);
     717           0 :   u1 = _mm256_add_epi32(u1, v[1]);
     718           0 :   u2 = _mm256_add_epi32(u2, v[2]);
     719           0 :   u3 = _mm256_add_epi32(u3, v[3]);
     720             : 
     721           0 :   u0 = _mm256_and_si256(u0, mask);
     722           0 :   u1 = _mm256_and_si256(u1, mask);
     723           0 :   u2 = _mm256_and_si256(u2, mask);
     724           0 :   u3 = _mm256_and_si256(u3, mask);
     725             :   // 4 32-bit summation, evenly positioned
     726             : 
     727           0 :   u1 = _mm256_slli_si256(u1, 4);
     728           0 :   u3 = _mm256_slli_si256(u3, 4);
     729             : 
     730           0 :   u0 = _mm256_or_si256(u0, u1);
     731           0 :   u2 = _mm256_or_si256(u2, u3);
     732             :   // 8 32-bit summation, interleaved
     733             : 
     734           0 :   u1 = _mm256_unpacklo_epi64(u0, u2);
     735           0 :   u3 = _mm256_unpackhi_epi64(u0, u2);
     736             : 
     737           0 :   u0 = _mm256_add_epi32(u1, u3);
     738           0 :   sad = _mm_add_epi32(_mm256_extractf128_si256(u0, 1),
     739             :                       _mm256_castsi256_si128(u0));
     740             :   _mm_storeu_si128((__m128i *)res, sad);
     741           0 : }
     742             : 
     743           0 : static void convert_pointers(const uint8_t *const ref8[],
     744             :                              const uint16_t *ref[]) {
     745           0 :   ref[0] = CONVERT_TO_SHORTPTR(ref8[0]);
     746           0 :   ref[1] = CONVERT_TO_SHORTPTR(ref8[1]);
     747           0 :   ref[2] = CONVERT_TO_SHORTPTR(ref8[2]);
     748           0 :   ref[3] = CONVERT_TO_SHORTPTR(ref8[3]);
     749           0 : }
     750             : 
     751           0 : static void init_sad(__m256i *s) {
     752           0 :   s[0] = _mm256_setzero_si256();
     753           0 :   s[1] = _mm256_setzero_si256();
     754           0 :   s[2] = _mm256_setzero_si256();
     755           0 :   s[3] = _mm256_setzero_si256();
     756           0 : }
     757             : 
     758           0 : void aom_highbd_sad16x8x4d_avx2(const uint8_t *src, int src_stride,
     759             :                                 const uint8_t *const ref_array[],
     760             :                                 int ref_stride, uint32_t *sad_array) {
     761             :   __m256i sad_vec[4];
     762             :   const uint16_t *refp[4];
     763           0 :   const uint16_t *keep = CONVERT_TO_SHORTPTR(src);
     764             :   const uint16_t *srcp;
     765           0 :   const int shift_for_4_rows = 2;
     766             :   int i;
     767             : 
     768           0 :   init_sad(sad_vec);
     769           0 :   convert_pointers(ref_array, refp);
     770             : 
     771           0 :   for (i = 0; i < 4; ++i) {
     772           0 :     srcp = keep;
     773           0 :     sad16x4(srcp, src_stride, refp[i], ref_stride, 0, &sad_vec[i]);
     774           0 :     srcp += src_stride << shift_for_4_rows;
     775           0 :     refp[i] += ref_stride << shift_for_4_rows;
     776           0 :     sad16x4(srcp, src_stride, refp[i], ref_stride, 0, &sad_vec[i]);
     777             :   }
     778           0 :   get_4d_sad_from_mm256_epi32(sad_vec, sad_array);
     779           0 : }
     780             : 
     781           0 : void aom_highbd_sad16x16x4d_avx2(const uint8_t *src, int src_stride,
     782             :                                  const uint8_t *const ref_array[],
     783             :                                  int ref_stride, uint32_t *sad_array) {
     784             :   uint32_t first8rows[4];
     785             :   uint32_t second8rows[4];
     786             :   const uint8_t *ref[4];
     787           0 :   const int shift_for_8_rows = 3;
     788             : 
     789           0 :   ref[0] = ref_array[0];
     790           0 :   ref[1] = ref_array[1];
     791           0 :   ref[2] = ref_array[2];
     792           0 :   ref[3] = ref_array[3];
     793             : 
     794           0 :   aom_highbd_sad16x8x4d_avx2(src, src_stride, ref, ref_stride, first8rows);
     795           0 :   src += src_stride << shift_for_8_rows;
     796           0 :   ref[0] += ref_stride << shift_for_8_rows;
     797           0 :   ref[1] += ref_stride << shift_for_8_rows;
     798           0 :   ref[2] += ref_stride << shift_for_8_rows;
     799           0 :   ref[3] += ref_stride << shift_for_8_rows;
     800           0 :   aom_highbd_sad16x8x4d_avx2(src, src_stride, ref, ref_stride, second8rows);
     801           0 :   sad_array[0] = first8rows[0] + second8rows[0];
     802           0 :   sad_array[1] = first8rows[1] + second8rows[1];
     803           0 :   sad_array[2] = first8rows[2] + second8rows[2];
     804           0 :   sad_array[3] = first8rows[3] + second8rows[3];
     805           0 : }
     806             : 
     807           0 : void aom_highbd_sad16x32x4d_avx2(const uint8_t *src, int src_stride,
     808             :                                  const uint8_t *const ref_array[],
     809             :                                  int ref_stride, uint32_t *sad_array) {
     810             :   uint32_t first_half[4];
     811             :   uint32_t second_half[4];
     812             :   const uint8_t *ref[4];
     813           0 :   const int shift_for_rows = 4;
     814             : 
     815           0 :   ref[0] = ref_array[0];
     816           0 :   ref[1] = ref_array[1];
     817           0 :   ref[2] = ref_array[2];
     818           0 :   ref[3] = ref_array[3];
     819             : 
     820           0 :   aom_highbd_sad16x16x4d_avx2(src, src_stride, ref, ref_stride, first_half);
     821           0 :   src += src_stride << shift_for_rows;
     822           0 :   ref[0] += ref_stride << shift_for_rows;
     823           0 :   ref[1] += ref_stride << shift_for_rows;
     824           0 :   ref[2] += ref_stride << shift_for_rows;
     825           0 :   ref[3] += ref_stride << shift_for_rows;
     826           0 :   aom_highbd_sad16x16x4d_avx2(src, src_stride, ref, ref_stride, second_half);
     827           0 :   sad_array[0] = first_half[0] + second_half[0];
     828           0 :   sad_array[1] = first_half[1] + second_half[1];
     829           0 :   sad_array[2] = first_half[2] + second_half[2];
     830           0 :   sad_array[3] = first_half[3] + second_half[3];
     831           0 : }
     832             : 
     833           0 : void aom_highbd_sad32x16x4d_avx2(const uint8_t *src, int src_stride,
     834             :                                  const uint8_t *const ref_array[],
     835             :                                  int ref_stride, uint32_t *sad_array) {
     836             :   __m256i sad_vec[4];
     837             :   const uint16_t *refp[4];
     838           0 :   const uint16_t *keep = CONVERT_TO_SHORTPTR(src);
     839             :   const uint16_t *srcp;
     840           0 :   const int shift_for_4_rows = 2;
     841             :   int i;
     842             :   int rows_section;
     843             : 
     844           0 :   init_sad(sad_vec);
     845           0 :   convert_pointers(ref_array, refp);
     846             : 
     847           0 :   for (i = 0; i < 4; ++i) {
     848           0 :     srcp = keep;
     849           0 :     rows_section = 0;
     850           0 :     while (rows_section < 4) {
     851           0 :       sad32x4(srcp, src_stride, refp[i], ref_stride, 0, &sad_vec[i]);
     852           0 :       srcp += src_stride << shift_for_4_rows;
     853           0 :       refp[i] += ref_stride << shift_for_4_rows;
     854           0 :       rows_section++;
     855             :     }
     856             :   }
     857           0 :   get_4d_sad_from_mm256_epi32(sad_vec, sad_array);
     858           0 : }
     859             : 
     860           0 : void aom_highbd_sad32x32x4d_avx2(const uint8_t *src, int src_stride,
     861             :                                  const uint8_t *const ref_array[],
     862             :                                  int ref_stride, uint32_t *sad_array) {
     863             :   uint32_t first_half[4];
     864             :   uint32_t second_half[4];
     865             :   const uint8_t *ref[4];
     866           0 :   const int shift_for_rows = 4;
     867             : 
     868           0 :   ref[0] = ref_array[0];
     869           0 :   ref[1] = ref_array[1];
     870           0 :   ref[2] = ref_array[2];
     871           0 :   ref[3] = ref_array[3];
     872             : 
     873           0 :   aom_highbd_sad32x16x4d_avx2(src, src_stride, ref, ref_stride, first_half);
     874           0 :   src += src_stride << shift_for_rows;
     875           0 :   ref[0] += ref_stride << shift_for_rows;
     876           0 :   ref[1] += ref_stride << shift_for_rows;
     877           0 :   ref[2] += ref_stride << shift_for_rows;
     878           0 :   ref[3] += ref_stride << shift_for_rows;
     879           0 :   aom_highbd_sad32x16x4d_avx2(src, src_stride, ref, ref_stride, second_half);
     880           0 :   sad_array[0] = first_half[0] + second_half[0];
     881           0 :   sad_array[1] = first_half[1] + second_half[1];
     882           0 :   sad_array[2] = first_half[2] + second_half[2];
     883           0 :   sad_array[3] = first_half[3] + second_half[3];
     884           0 : }
     885             : 
     886           0 : void aom_highbd_sad32x64x4d_avx2(const uint8_t *src, int src_stride,
     887             :                                  const uint8_t *const ref_array[],
     888             :                                  int ref_stride, uint32_t *sad_array) {
     889             :   uint32_t first_half[4];
     890             :   uint32_t second_half[4];
     891             :   const uint8_t *ref[4];
     892           0 :   const int shift_for_rows = 5;
     893             : 
     894           0 :   ref[0] = ref_array[0];
     895           0 :   ref[1] = ref_array[1];
     896           0 :   ref[2] = ref_array[2];
     897           0 :   ref[3] = ref_array[3];
     898             : 
     899           0 :   aom_highbd_sad32x32x4d_avx2(src, src_stride, ref, ref_stride, first_half);
     900           0 :   src += src_stride << shift_for_rows;
     901           0 :   ref[0] += ref_stride << shift_for_rows;
     902           0 :   ref[1] += ref_stride << shift_for_rows;
     903           0 :   ref[2] += ref_stride << shift_for_rows;
     904           0 :   ref[3] += ref_stride << shift_for_rows;
     905           0 :   aom_highbd_sad32x32x4d_avx2(src, src_stride, ref, ref_stride, second_half);
     906           0 :   sad_array[0] = first_half[0] + second_half[0];
     907           0 :   sad_array[1] = first_half[1] + second_half[1];
     908           0 :   sad_array[2] = first_half[2] + second_half[2];
     909           0 :   sad_array[3] = first_half[3] + second_half[3];
     910           0 : }
     911             : 
     912           0 : void aom_highbd_sad64x32x4d_avx2(const uint8_t *src, int src_stride,
     913             :                                  const uint8_t *const ref_array[],
     914             :                                  int ref_stride, uint32_t *sad_array) {
     915             :   __m256i sad_vec[4];
     916             :   const uint16_t *refp[4];
     917           0 :   const uint16_t *keep = CONVERT_TO_SHORTPTR(src);
     918             :   const uint16_t *srcp;
     919           0 :   const int shift_for_rows = 1;
     920             :   int i;
     921             :   int rows_section;
     922             : 
     923           0 :   init_sad(sad_vec);
     924           0 :   convert_pointers(ref_array, refp);
     925             : 
     926           0 :   for (i = 0; i < 4; ++i) {
     927           0 :     srcp = keep;
     928           0 :     rows_section = 0;
     929           0 :     while (rows_section < 16) {
     930           0 :       sad64x2(srcp, src_stride, refp[i], ref_stride, NULL, &sad_vec[i]);
     931           0 :       srcp += src_stride << shift_for_rows;
     932           0 :       refp[i] += ref_stride << shift_for_rows;
     933           0 :       rows_section++;
     934             :     }
     935             :   }
     936           0 :   get_4d_sad_from_mm256_epi32(sad_vec, sad_array);
     937           0 : }
     938             : 
     939           0 : void aom_highbd_sad64x64x4d_avx2(const uint8_t *src, int src_stride,
     940             :                                  const uint8_t *const ref_array[],
     941             :                                  int ref_stride, uint32_t *sad_array) {
     942             :   uint32_t first_half[4];
     943             :   uint32_t second_half[4];
     944             :   const uint8_t *ref[4];
     945           0 :   const int shift_for_rows = 5;
     946             : 
     947           0 :   ref[0] = ref_array[0];
     948           0 :   ref[1] = ref_array[1];
     949           0 :   ref[2] = ref_array[2];
     950           0 :   ref[3] = ref_array[3];
     951             : 
     952           0 :   aom_highbd_sad64x32x4d_avx2(src, src_stride, ref, ref_stride, first_half);
     953           0 :   src += src_stride << shift_for_rows;
     954           0 :   ref[0] += ref_stride << shift_for_rows;
     955           0 :   ref[1] += ref_stride << shift_for_rows;
     956           0 :   ref[2] += ref_stride << shift_for_rows;
     957           0 :   ref[3] += ref_stride << shift_for_rows;
     958           0 :   aom_highbd_sad64x32x4d_avx2(src, src_stride, ref, ref_stride, second_half);
     959           0 :   sad_array[0] = first_half[0] + second_half[0];
     960           0 :   sad_array[1] = first_half[1] + second_half[1];
     961           0 :   sad_array[2] = first_half[2] + second_half[2];
     962           0 :   sad_array[3] = first_half[3] + second_half[3];
     963           0 : }
     964             : 
     965             : #if CONFIG_EXT_PARTITION
     966             : void aom_highbd_sad64x128x4d_avx2(const uint8_t *src, int src_stride,
     967             :                                   const uint8_t *const ref_array[],
     968             :                                   int ref_stride, uint32_t *sad_array) {
     969             :   uint32_t first_half[4];
     970             :   uint32_t second_half[4];
     971             :   const uint8_t *ref[4];
     972             :   const int shift_for_rows = 6;
     973             : 
     974             :   ref[0] = ref_array[0];
     975             :   ref[1] = ref_array[1];
     976             :   ref[2] = ref_array[2];
     977             :   ref[3] = ref_array[3];
     978             : 
     979             :   aom_highbd_sad64x64x4d_avx2(src, src_stride, ref, ref_stride, first_half);
     980             :   src += src_stride << shift_for_rows;
     981             :   ref[0] += ref_stride << shift_for_rows;
     982             :   ref[1] += ref_stride << shift_for_rows;
     983             :   ref[2] += ref_stride << shift_for_rows;
     984             :   ref[3] += ref_stride << shift_for_rows;
     985             :   aom_highbd_sad64x64x4d_avx2(src, src_stride, ref, ref_stride, second_half);
     986             :   sad_array[0] = first_half[0] + second_half[0];
     987             :   sad_array[1] = first_half[1] + second_half[1];
     988             :   sad_array[2] = first_half[2] + second_half[2];
     989             :   sad_array[3] = first_half[3] + second_half[3];
     990             : }
     991             : 
     992             : void aom_highbd_sad128x64x4d_avx2(const uint8_t *src, int src_stride,
     993             :                                   const uint8_t *const ref_array[],
     994             :                                   int ref_stride, uint32_t *sad_array) {
     995             :   __m256i sad_vec[4];
     996             :   const uint16_t *refp[4];
     997             :   const uint16_t *keep = CONVERT_TO_SHORTPTR(src);
     998             :   const uint16_t *srcp;
     999             :   int i;
    1000             :   int rows_section;
    1001             : 
    1002             :   init_sad(sad_vec);
    1003             :   convert_pointers(ref_array, refp);
    1004             : 
    1005             :   for (i = 0; i < 4; ++i) {
    1006             :     srcp = keep;
    1007             :     rows_section = 0;
    1008             :     while (rows_section < 64) {
    1009             :       sad128x1(srcp, refp[i], NULL, &sad_vec[i]);
    1010             :       srcp += src_stride;
    1011             :       refp[i] += ref_stride;
    1012             :       rows_section++;
    1013             :     }
    1014             :   }
    1015             :   get_4d_sad_from_mm256_epi32(sad_vec, sad_array);
    1016             : }
    1017             : 
    1018             : void aom_highbd_sad128x128x4d_avx2(const uint8_t *src, int src_stride,
    1019             :                                    const uint8_t *const ref_array[],
    1020             :                                    int ref_stride, uint32_t *sad_array) {
    1021             :   uint32_t first_half[4];
    1022             :   uint32_t second_half[4];
    1023             :   const uint8_t *ref[4];
    1024             :   const int shift_for_rows = 6;
    1025             : 
    1026             :   ref[0] = ref_array[0];
    1027             :   ref[1] = ref_array[1];
    1028             :   ref[2] = ref_array[2];
    1029             :   ref[3] = ref_array[3];
    1030             : 
    1031             :   aom_highbd_sad128x64x4d_avx2(src, src_stride, ref, ref_stride, first_half);
    1032             :   src += src_stride << shift_for_rows;
    1033             :   ref[0] += ref_stride << shift_for_rows;
    1034             :   ref[1] += ref_stride << shift_for_rows;
    1035             :   ref[2] += ref_stride << shift_for_rows;
    1036             :   ref[3] += ref_stride << shift_for_rows;
    1037             :   aom_highbd_sad128x64x4d_avx2(src, src_stride, ref, ref_stride, second_half);
    1038             :   sad_array[0] = first_half[0] + second_half[0];
    1039             :   sad_array[1] = first_half[1] + second_half[1];
    1040             :   sad_array[2] = first_half[2] + second_half[2];
    1041             :   sad_array[3] = first_half[3] + second_half[3];
    1042             : }
    1043             : #endif  // CONFIG_EXT_PARTITION

Generated by: LCOV version 1.13