• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019, 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 #include <stdio.h>
14 #include "aom/aom_integer.h"
15 #include "av1/common/common.h"
16 
av1_highbd_block_error_avx2(tran_low_t * coeff,tran_low_t * dqcoeff,intptr_t block_size,int64_t * ssz,int bps)17 int64_t av1_highbd_block_error_avx2(tran_low_t *coeff, tran_low_t *dqcoeff,
18                                     intptr_t block_size, int64_t *ssz,
19                                     int bps) {
20   int i;
21   int64_t temp1[8];
22   int64_t error = 0, sqcoeff = 0;
23   const int shift = 2 * (bps - 8);
24   const int rounding = shift > 0 ? 1 << (shift - 1) : 0;
25 
26   for (i = 0; i < block_size; i += 16) {
27     __m256i mm256_coeff = _mm256_loadu_si256((__m256i *)(coeff + i));
28     __m256i mm256_coeff2 = _mm256_loadu_si256((__m256i *)(coeff + i + 8));
29     __m256i mm256_dqcoeff = _mm256_loadu_si256((__m256i *)(dqcoeff + i));
30     __m256i mm256_dqcoeff2 = _mm256_loadu_si256((__m256i *)(dqcoeff + i + 8));
31 
32     __m256i diff1 = _mm256_sub_epi32(mm256_coeff, mm256_dqcoeff);
33     __m256i diff2 = _mm256_sub_epi32(mm256_coeff2, mm256_dqcoeff2);
34     __m256i diff1h = _mm256_srli_epi64(diff1, 32);
35     __m256i diff2h = _mm256_srli_epi64(diff2, 32);
36     __m256i res = _mm256_mul_epi32(diff1, diff1);
37     __m256i res1 = _mm256_mul_epi32(diff1h, diff1h);
38     __m256i res2 = _mm256_mul_epi32(diff2, diff2);
39     __m256i res3 = _mm256_mul_epi32(diff2h, diff2h);
40     __m256i res_diff = _mm256_add_epi64(_mm256_add_epi64(res, res1),
41                                         _mm256_add_epi64(res2, res3));
42     __m256i mm256_coeffh = _mm256_srli_epi64(mm256_coeff, 32);
43     __m256i mm256_coeffh2 = _mm256_srli_epi64(mm256_coeff2, 32);
44     res = _mm256_mul_epi32(mm256_coeff, mm256_coeff);
45     res1 = _mm256_mul_epi32(mm256_coeffh, mm256_coeffh);
46     res2 = _mm256_mul_epi32(mm256_coeff2, mm256_coeff2);
47     res3 = _mm256_mul_epi32(mm256_coeffh2, mm256_coeffh2);
48     __m256i res_sqcoeff = _mm256_add_epi64(_mm256_add_epi64(res, res1),
49                                            _mm256_add_epi64(res2, res3));
50     _mm256_storeu_si256((__m256i *)temp1, res_diff);
51     _mm256_storeu_si256((__m256i *)temp1 + 1, res_sqcoeff);
52 
53     error += temp1[0] + temp1[1] + temp1[2] + temp1[3];
54     sqcoeff += temp1[4] + temp1[5] + temp1[6] + temp1[7];
55   }
56   assert(error >= 0 && sqcoeff >= 0);
57   error = (error + rounding) >> shift;
58   sqcoeff = (sqcoeff + rounding) >> shift;
59 
60   *ssz = sqcoeff;
61   return error;
62 }
63