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

#ifndef _AOM_DSP_X86_MASKED_VARIANCE_INTRIN_SSSE3_H
#define _AOM_DSP_X86_MASKED_VARIANCE_INTRIN_SSSE3_H

#include <stdlib.h>
#include <string.h>
#include <tmmintrin.h>

#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "aom_dsp/blend.h"

static INLINE void comp_mask_pred_16_ssse3(const uint8_t *src0,
                                           const uint8_t *src1,
                                           const uint8_t *mask, uint8_t *dst) {
  const __m128i alpha_max = _mm_set1_epi8(AOM_BLEND_A64_MAX_ALPHA);
  const __m128i round_offset =
      _mm_set1_epi16(1 << (15 - AOM_BLEND_A64_ROUND_BITS));

  const __m128i sA0 = _mm_lddqu_si128((const __m128i *)(src0));
  const __m128i sA1 = _mm_lddqu_si128((const __m128i *)(src1));
  const __m128i aA = _mm_load_si128((const __m128i *)(mask));

  const __m128i maA = _mm_sub_epi8(alpha_max, aA);

  const __m128i ssAL = _mm_unpacklo_epi8(sA0, sA1);
  const __m128i aaAL = _mm_unpacklo_epi8(aA, maA);
  const __m128i ssAH = _mm_unpackhi_epi8(sA0, sA1);
  const __m128i aaAH = _mm_unpackhi_epi8(aA, maA);

  const __m128i blendAL = _mm_maddubs_epi16(ssAL, aaAL);
  const __m128i blendAH = _mm_maddubs_epi16(ssAH, aaAH);

  const __m128i roundAL = _mm_mulhrs_epi16(blendAL, round_offset);
  const __m128i roundAH = _mm_mulhrs_epi16(blendAH, round_offset);
  _mm_store_si128((__m128i *)dst, _mm_packus_epi16(roundAL, roundAH));
}

static INLINE void comp_mask_pred_8_ssse3(uint8_t *comp_pred, int height,
                                          const uint8_t *src0, int stride0,
                                          const uint8_t *src1, int stride1,
                                          const uint8_t *mask,
                                          int mask_stride) {
  int i = 0;
  const __m128i alpha_max = _mm_set1_epi8(AOM_BLEND_A64_MAX_ALPHA);
  const __m128i round_offset =
      _mm_set1_epi16(1 << (15 - AOM_BLEND_A64_ROUND_BITS));
  do {
    // odd line A
    const __m128i sA0 = _mm_loadl_epi64((const __m128i *)(src0));
    const __m128i sA1 = _mm_loadl_epi64((const __m128i *)(src1));
    const __m128i aA = _mm_loadl_epi64((const __m128i *)(mask));
    // even line B
    const __m128i sB0 = _mm_loadl_epi64((const __m128i *)(src0 + stride0));
    const __m128i sB1 = _mm_loadl_epi64((const __m128i *)(src1 + stride1));
    const __m128i a = _mm_castps_si128(_mm_loadh_pi(
        _mm_castsi128_ps(aA), (const __m64 *)(mask + mask_stride)));

    const __m128i ssA = _mm_unpacklo_epi8(sA0, sA1);
    const __m128i ssB = _mm_unpacklo_epi8(sB0, sB1);

    const __m128i ma = _mm_sub_epi8(alpha_max, a);
    const __m128i aaA = _mm_unpacklo_epi8(a, ma);
    const __m128i aaB = _mm_unpackhi_epi8(a, ma);

    const __m128i blendA = _mm_maddubs_epi16(ssA, aaA);
    const __m128i blendB = _mm_maddubs_epi16(ssB, aaB);
    const __m128i roundA = _mm_mulhrs_epi16(blendA, round_offset);
    const __m128i roundB = _mm_mulhrs_epi16(blendB, round_offset);
    const __m128i round = _mm_packus_epi16(roundA, roundB);
    // comp_pred's stride == width == 8
    _mm_store_si128((__m128i *)(comp_pred), round);
    comp_pred += (8 << 1);
    src0 += (stride0 << 1);
    src1 += (stride1 << 1);
    mask += (mask_stride << 1);
    i += 2;
  } while (i < height);
}

#endif
