/*
 * 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/.
 */

#include <assert.h>
#include <emmintrin.h>  // SSE2

#include "config/aom_config.h"
#include "config/aom_dsp_rtcd.h"
#include "config/av1_rtcd.h"

#include "aom_dsp/blend.h"
#include "aom_dsp/x86/mem_sse2.h"
#include "aom_dsp/x86/synonyms.h"

#include "aom_ports/mem.h"

#include "av1/common/av1_common_int.h"
#include "av1/common/filter.h"
#include "av1/common/reconinter.h"
#include "av1/encoder/reconinter_enc.h"

unsigned int aom_get_mb_ss_sse2(const int16_t *src) {
  __m128i vsum = _mm_setzero_si128();
  int i;

  for (i = 0; i < 32; ++i) {
    const __m128i v = xx_loadu_128(src);
    vsum = _mm_add_epi32(vsum, _mm_madd_epi16(v, v));
    src += 8;
  }

  vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8));
  vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 4));
  return _mm_cvtsi128_si32(vsum);
}

static INLINE __m128i highbd_comp_mask_pred_line_sse2(const __m128i s0,
                                                      const __m128i s1,
                                                      const __m128i a) {
  const __m128i alpha_max = _mm_set1_epi16((1 << AOM_BLEND_A64_ROUND_BITS));
  const __m128i round_const =
      _mm_set1_epi32((1 << AOM_BLEND_A64_ROUND_BITS) >> 1);
  const __m128i a_inv = _mm_sub_epi16(alpha_max, a);

  const __m128i s_lo = _mm_unpacklo_epi16(s0, s1);
  const __m128i a_lo = _mm_unpacklo_epi16(a, a_inv);
  const __m128i pred_lo = _mm_madd_epi16(s_lo, a_lo);
  const __m128i pred_l = _mm_srai_epi32(_mm_add_epi32(pred_lo, round_const),
                                        AOM_BLEND_A64_ROUND_BITS);

  const __m128i s_hi = _mm_unpackhi_epi16(s0, s1);
  const __m128i a_hi = _mm_unpackhi_epi16(a, a_inv);
  const __m128i pred_hi = _mm_madd_epi16(s_hi, a_hi);
  const __m128i pred_h = _mm_srai_epi32(_mm_add_epi32(pred_hi, round_const),
                                        AOM_BLEND_A64_ROUND_BITS);

  const __m128i comp = _mm_packs_epi32(pred_l, pred_h);

  return comp;
}

void aom_highbd_comp_mask_pred_sse2(uint8_t *comp_pred8, const uint8_t *pred8,
                                    int width, int height, const uint8_t *ref8,
                                    int ref_stride, const uint8_t *mask,
                                    int mask_stride, int invert_mask) {
  int i = 0;
  uint16_t *comp_pred = CONVERT_TO_SHORTPTR(comp_pred8);
  uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
  uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
  const uint16_t *src0 = invert_mask ? pred : ref;
  const uint16_t *src1 = invert_mask ? ref : pred;
  const int stride0 = invert_mask ? width : ref_stride;
  const int stride1 = invert_mask ? ref_stride : width;
  const __m128i zero = _mm_setzero_si128();

  if (width == 8) {
    do {
      const __m128i s0 = _mm_loadu_si128((const __m128i *)(src0));
      const __m128i s1 = _mm_loadu_si128((const __m128i *)(src1));
      const __m128i m_8 = _mm_loadl_epi64((const __m128i *)mask);
      const __m128i m_16 = _mm_unpacklo_epi8(m_8, zero);

      const __m128i comp = highbd_comp_mask_pred_line_sse2(s0, s1, m_16);

      _mm_storeu_si128((__m128i *)comp_pred, comp);

      src0 += stride0;
      src1 += stride1;
      mask += mask_stride;
      comp_pred += width;
      i += 1;
    } while (i < height);
  } else if (width == 16) {
    do {
      const __m128i s0 = _mm_loadu_si128((const __m128i *)(src0));
      const __m128i s2 = _mm_loadu_si128((const __m128i *)(src0 + 8));
      const __m128i s1 = _mm_loadu_si128((const __m128i *)(src1));
      const __m128i s3 = _mm_loadu_si128((const __m128i *)(src1 + 8));

      const __m128i m_8 = _mm_loadu_si128((const __m128i *)mask);
      const __m128i m01_16 = _mm_unpacklo_epi8(m_8, zero);
      const __m128i m23_16 = _mm_unpackhi_epi8(m_8, zero);

      const __m128i comp = highbd_comp_mask_pred_line_sse2(s0, s1, m01_16);
      const __m128i comp1 = highbd_comp_mask_pred_line_sse2(s2, s3, m23_16);

      _mm_storeu_si128((__m128i *)comp_pred, comp);
      _mm_storeu_si128((__m128i *)(comp_pred + 8), comp1);

      src0 += stride0;
      src1 += stride1;
      mask += mask_stride;
      comp_pred += width;
      i += 1;
    } while (i < height);
  } else if (width == 32) {
    do {
      for (int j = 0; j < 2; j++) {
        const __m128i s0 = _mm_loadu_si128((const __m128i *)(src0 + j * 16));
        const __m128i s2 =
            _mm_loadu_si128((const __m128i *)(src0 + 8 + j * 16));
        const __m128i s1 = _mm_loadu_si128((const __m128i *)(src1 + j * 16));
        const __m128i s3 =
            _mm_loadu_si128((const __m128i *)(src1 + 8 + j * 16));

        const __m128i m_8 = _mm_loadu_si128((const __m128i *)(mask + j * 16));
        const __m128i m01_16 = _mm_unpacklo_epi8(m_8, zero);
        const __m128i m23_16 = _mm_unpackhi_epi8(m_8, zero);

        const __m128i comp = highbd_comp_mask_pred_line_sse2(s0, s1, m01_16);
        const __m128i comp1 = highbd_comp_mask_pred_line_sse2(s2, s3, m23_16);

        _mm_storeu_si128((__m128i *)(comp_pred + j * 16), comp);
        _mm_storeu_si128((__m128i *)(comp_pred + 8 + j * 16), comp1);
      }
      src0 += stride0;
      src1 += stride1;
      mask += mask_stride;
      comp_pred += width;
      i += 1;
    } while (i < height);
  }
}
