tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cfl_sse2.c (3573B)


      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 <emmintrin.h>
     13 
     14 #include "av1/common/cfl.h"
     15 #include "config/av1_rtcd.h"
     16 
     17 static inline __m128i fill_sum_epi32(__m128i l0) {
     18  l0 = _mm_add_epi32(l0, _mm_shuffle_epi32(l0, _MM_SHUFFLE(1, 0, 3, 2)));
     19  return _mm_add_epi32(l0, _mm_shuffle_epi32(l0, _MM_SHUFFLE(2, 3, 0, 1)));
     20 }
     21 
     22 static inline void subtract_average_sse2(const uint16_t *src_ptr,
     23                                         int16_t *dst_ptr, int width,
     24                                         int height, int round_offset,
     25                                         int num_pel_log2) {
     26  const __m128i zeros = _mm_setzero_si128();
     27  const __m128i round_offset_epi32 = _mm_set1_epi32(round_offset);
     28  const __m128i *src = (__m128i *)src_ptr;
     29  const __m128i *const end = src + height * CFL_BUF_LINE_I128;
     30  const int step = CFL_BUF_LINE_I128 * (1 + (width == 8) + 3 * (width == 4));
     31 
     32  __m128i sum = zeros;
     33  do {
     34    __m128i l0;
     35    if (width == 4) {
     36      l0 = _mm_add_epi16(_mm_loadl_epi64(src),
     37                         _mm_loadl_epi64(src + CFL_BUF_LINE_I128));
     38      __m128i l1 = _mm_add_epi16(_mm_loadl_epi64(src + 2 * CFL_BUF_LINE_I128),
     39                                 _mm_loadl_epi64(src + 3 * CFL_BUF_LINE_I128));
     40      sum = _mm_add_epi32(sum, _mm_add_epi32(_mm_unpacklo_epi16(l0, zeros),
     41                                             _mm_unpacklo_epi16(l1, zeros)));
     42    } else {
     43      if (width == 8) {
     44        l0 = _mm_add_epi16(_mm_loadu_si128(src),
     45                           _mm_loadu_si128(src + CFL_BUF_LINE_I128));
     46      } else {
     47        l0 = _mm_add_epi16(_mm_loadu_si128(src), _mm_loadu_si128(src + 1));
     48      }
     49      sum = _mm_add_epi32(sum, _mm_add_epi32(_mm_unpacklo_epi16(l0, zeros),
     50                                             _mm_unpackhi_epi16(l0, zeros)));
     51      if (width == 32) {
     52        l0 = _mm_add_epi16(_mm_loadu_si128(src + 2), _mm_loadu_si128(src + 3));
     53        sum = _mm_add_epi32(sum, _mm_add_epi32(_mm_unpacklo_epi16(l0, zeros),
     54                                               _mm_unpackhi_epi16(l0, zeros)));
     55      }
     56    }
     57    src += step;
     58  } while (src < end);
     59 
     60  sum = fill_sum_epi32(sum);
     61 
     62  __m128i avg_epi16 =
     63      _mm_srli_epi32(_mm_add_epi32(sum, round_offset_epi32), num_pel_log2);
     64  avg_epi16 = _mm_packs_epi32(avg_epi16, avg_epi16);
     65 
     66  src = (__m128i *)src_ptr;
     67  __m128i *dst = (__m128i *)dst_ptr;
     68  do {
     69    if (width == 4) {
     70      _mm_storel_epi64(dst, _mm_sub_epi16(_mm_loadl_epi64(src), avg_epi16));
     71    } else {
     72      _mm_storeu_si128(dst, _mm_sub_epi16(_mm_loadu_si128(src), avg_epi16));
     73      if (width > 8) {
     74        _mm_storeu_si128(dst + 1,
     75                         _mm_sub_epi16(_mm_loadu_si128(src + 1), avg_epi16));
     76        if (width == 32) {
     77          _mm_storeu_si128(dst + 2,
     78                           _mm_sub_epi16(_mm_loadu_si128(src + 2), avg_epi16));
     79          _mm_storeu_si128(dst + 3,
     80                           _mm_sub_epi16(_mm_loadu_si128(src + 3), avg_epi16));
     81        }
     82      }
     83    }
     84    src += CFL_BUF_LINE_I128;
     85    dst += CFL_BUF_LINE_I128;
     86  } while (src < end);
     87 }
     88 
     89 CFL_SUB_AVG_FN(sse2)