/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

#ifndef AOM_AOM_DSP_X86_CONVOLVE_SSE4_1_H_
#define AOM_AOM_DSP_X86_CONVOLVE_SSE4_1_H_

// Note:
//  This header file should be put below any x86 intrinsics head file

static INLINE void mult_add_store(CONV_BUF_TYPE *const dst,
                                  const __m128i *const res,
                                  const __m128i *const wt0,
                                  const __m128i *const wt1,
                                  const int do_average) {
  __m128i d;
  if (do_average) {
    d = _mm_loadu_si128((__m128i *)dst);
    d = _mm_add_epi32(_mm_mullo_epi32(d, *wt0), _mm_mullo_epi32(*res, *wt1));
    d = _mm_srai_epi32(d, DIST_PRECISION_BITS);
  } else {
    d = *res;
  }
  _mm_store_si128((__m128i *)dst, d);
}

static INLINE __m128i highbd_comp_avg_sse4_1(const __m128i *const data_ref_0,
                                             const __m128i *const res_unsigned,
                                             const __m128i *const wt0,
                                             const __m128i *const wt1,
                                             const int use_dist_wtd_avg) {
  __m128i res;
  if (use_dist_wtd_avg) {
    const __m128i wt0_res = _mm_mullo_epi32(*data_ref_0, *wt0);
    const __m128i wt1_res = _mm_mullo_epi32(*res_unsigned, *wt1);

    const __m128i wt_res = _mm_add_epi32(wt0_res, wt1_res);
    res = _mm_srai_epi32(wt_res, DIST_PRECISION_BITS);
  } else {
    const __m128i wt_res = _mm_add_epi32(*data_ref_0, *res_unsigned);
    res = _mm_srai_epi32(wt_res, 1);
  }
  return res;
}

#endif  // AOM_AOM_DSP_X86_CONVOLVE_SSE4_1_H_
