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