/*
 * Copyright (c) 2018, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
 */

#include <tmmintrin.h>

#include "config/av1_rtcd.h"

#include "aom/aom_integer.h"
#include "aom_dsp/blend.h"
#include "aom_dsp/x86/synonyms.h"
#include "av1/common/blockd.h"

void av1_build_compound_diffwtd_mask_highbd_ssse3(
    uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0,
    int src0_stride, const uint8_t *src1, int src1_stride, int h, int w,
    int bd) {
  if (w < 8) {
    av1_build_compound_diffwtd_mask_highbd_c(mask, mask_type, src0, src0_stride,
                                             src1, src1_stride, h, w, bd);
  } else {
    assert(bd >= 8);
    assert((w % 8) == 0);
#if !CONFIG_DIFFWTD_42
    assert(mask_type == DIFFWTD_38 || mask_type == DIFFWTD_38_INV);
#endif  // !CONFIG_DIFFWTD_42
    const __m128i x0 = _mm_setzero_si128();
    const __m128i xAOM_BLEND_A64_MAX_ALPHA =
        _mm_set1_epi16(AOM_BLEND_A64_MAX_ALPHA);
    const int mask_base = 38;
    const __m128i xmask_base = _mm_set1_epi16(mask_base);
    const uint16_t *ssrc0 = CONVERT_TO_SHORTPTR(src0);
    const uint16_t *ssrc1 = CONVERT_TO_SHORTPTR(src1);
    if (bd == 8) {
      // This function is not invoked if the experiment is on, but this is
      // needed to ensure the code compiles.
#if CONFIG_DIFFWTD_42
      if (mask_type == DIFFWTD_42_INV) {
#else
      if (mask_type == DIFFWTD_38_INV) {
#endif  // CONFIG_DIFFWTD_42
        for (int i = 0; i < h; ++i) {
          for (int j = 0; j < w; j += 8) {
            __m128i s0 = _mm_loadu_si128((const __m128i *)&ssrc0[j]);
            __m128i s1 = _mm_loadu_si128((const __m128i *)&ssrc1[j]);
            __m128i diff = _mm_srai_epi16(_mm_abs_epi16(_mm_sub_epi16(s0, s1)),
                                          DIFF_FACTOR_LOG2);
            __m128i m = _mm_min_epi16(
                _mm_max_epi16(x0, _mm_add_epi16(diff, xmask_base)),
                xAOM_BLEND_A64_MAX_ALPHA);
            m = _mm_sub_epi16(xAOM_BLEND_A64_MAX_ALPHA, m);
            m = _mm_packus_epi16(m, m);
            _mm_storel_epi64((__m128i *)&mask[j], m);
          }
          ssrc0 += src0_stride;
          ssrc1 += src1_stride;
          mask += w;
        }
      } else {
        for (int i = 0; i < h; ++i) {
          for (int j = 0; j < w; j += 8) {
            __m128i s0 = _mm_loadu_si128((const __m128i *)&ssrc0[j]);
            __m128i s1 = _mm_loadu_si128((const __m128i *)&ssrc1[j]);
            __m128i diff = _mm_srai_epi16(_mm_abs_epi16(_mm_sub_epi16(s0, s1)),
                                          DIFF_FACTOR_LOG2);
            __m128i m = _mm_min_epi16(
                _mm_max_epi16(x0, _mm_add_epi16(diff, xmask_base)),
                xAOM_BLEND_A64_MAX_ALPHA);
            m = _mm_packus_epi16(m, m);
            _mm_storel_epi64((__m128i *)&mask[j], m);
          }
          ssrc0 += src0_stride;
          ssrc1 += src1_stride;
          mask += w;
        }
      }
    } else {
      const __m128i xshift = xx_set1_64_from_32i(bd - 8 + DIFF_FACTOR_LOG2);
      // This function is not invoked if the experiment is on, but this is
      // needed to ensure the code compiles.
#if CONFIG_DIFFWTD_42
      if (mask_type == DIFFWTD_42_INV) {
#else
      if (mask_type == DIFFWTD_38_INV) {
#endif  // CONFIG_DIFFWTD_42
        for (int i = 0; i < h; ++i) {
          for (int j = 0; j < w; j += 8) {
            __m128i s0 = _mm_loadu_si128((const __m128i *)&ssrc0[j]);
            __m128i s1 = _mm_loadu_si128((const __m128i *)&ssrc1[j]);
            __m128i diff =
                _mm_sra_epi16(_mm_abs_epi16(_mm_sub_epi16(s0, s1)), xshift);
            __m128i m = _mm_min_epi16(
                _mm_max_epi16(x0, _mm_add_epi16(diff, xmask_base)),
                xAOM_BLEND_A64_MAX_ALPHA);
            m = _mm_sub_epi16(xAOM_BLEND_A64_MAX_ALPHA, m);
            m = _mm_packus_epi16(m, m);
            _mm_storel_epi64((__m128i *)&mask[j], m);
          }
          ssrc0 += src0_stride;
          ssrc1 += src1_stride;
          mask += w;
        }
      } else {
        for (int i = 0; i < h; ++i) {
          for (int j = 0; j < w; j += 8) {
            __m128i s0 = _mm_loadu_si128((const __m128i *)&ssrc0[j]);
            __m128i s1 = _mm_loadu_si128((const __m128i *)&ssrc1[j]);
            __m128i diff =
                _mm_sra_epi16(_mm_abs_epi16(_mm_sub_epi16(s0, s1)), xshift);
            __m128i m = _mm_min_epi16(
                _mm_max_epi16(x0, _mm_add_epi16(diff, xmask_base)),
                xAOM_BLEND_A64_MAX_ALPHA);
            m = _mm_packus_epi16(m, m);
            _mm_storel_epi64((__m128i *)&mask[j], m);
          }
          ssrc0 += src0_stride;
          ssrc1 += src1_stride;
          mask += w;
        }
      }
    }
  }
}
