/*
 * Copyright (c) 2017, 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 <immintrin.h>

#include "config/av1_rtcd.h"

#include "aom/aom_integer.h"
#include "aom_dsp/aom_dsp_common.h"

static INLINE void write_zero(tran_low_t *qcoeff) {
  const __m256i zero = _mm256_setzero_si256();
  _mm256_storeu_si256((__m256i *)qcoeff, zero);
  _mm256_storeu_si256((__m256i *)qcoeff + 1, zero);
}

static INLINE void init_one_qp(const __m128i *p, __m256i *qp) {
  const __m128i ac = _mm_unpackhi_epi64(*p, *p);
  *qp = _mm256_insertf128_si256(_mm256_castsi128_si256(*p), ac, 1);
}

static INLINE void init_qp(const int16_t *round_ptr, const int16_t *quant_ptr,
                           const int16_t *dequant_ptr, int log_scale,
                           __m256i *thr, __m256i *qp) {
  __m128i round = _mm_loadu_si128((const __m128i *)round_ptr);
  const __m128i quant = _mm_loadu_si128((const __m128i *)quant_ptr);
  const __m128i dequant = _mm_loadu_si128((const __m128i *)dequant_ptr);

  if (log_scale > 0) {
    const __m128i rnd = _mm_set1_epi16((int16_t)1 << (log_scale - 1));
    round = _mm_add_epi16(round, rnd);
    round = _mm_srai_epi16(round, log_scale);
  }

  init_one_qp(&round, &qp[0]);
  init_one_qp(&quant, &qp[1]);

  if (log_scale == 1) {
    qp[1] = _mm256_slli_epi16(qp[1], log_scale);
  }

  init_one_qp(&dequant, &qp[2]);
  *thr = _mm256_srai_epi16(qp[2], 1 + log_scale);
  // Subtracting 1 here eliminates a _mm256_cmpeq_epi16() instruction when
  // calculating the zbin mask.
  *thr = _mm256_sub_epi16(*thr, _mm256_set1_epi16(1));
}

static INLINE void update_qp(__m256i *thr, __m256i *qp) {
  qp[0] = _mm256_permute2x128_si256(qp[0], qp[0], 0x11);
  qp[1] = _mm256_permute2x128_si256(qp[1], qp[1], 0x11);
  qp[2] = _mm256_permute2x128_si256(qp[2], qp[2], 0x11);
  *thr = _mm256_permute2x128_si256(*thr, *thr, 0x11);
}

static INLINE __m256i load_coefficients_avx2(const tran_low_t *coeff_ptr) {
  const __m256i coeff1 = _mm256_load_si256((__m256i *)coeff_ptr);
  const __m256i coeff2 = _mm256_load_si256((__m256i *)(coeff_ptr + 8));
  return _mm256_packs_epi32(coeff1, coeff2);
}

static INLINE void store_coefficients_avx2(__m256i coeff_vals,
                                           tran_low_t *coeff_ptr) {
  __m256i coeff_sign = _mm256_srai_epi16(coeff_vals, 15);
  __m256i coeff_vals_lo = _mm256_unpacklo_epi16(coeff_vals, coeff_sign);
  __m256i coeff_vals_hi = _mm256_unpackhi_epi16(coeff_vals, coeff_sign);
  _mm256_store_si256((__m256i *)coeff_ptr, coeff_vals_lo);
  _mm256_store_si256((__m256i *)(coeff_ptr + 8), coeff_vals_hi);
}

static INLINE uint16_t quant_gather_eob(__m256i eob) {
  const __m128i eob_lo = _mm256_castsi256_si128(eob);
  const __m128i eob_hi = _mm256_extractf128_si256(eob, 1);
  __m128i eob_s = _mm_max_epi16(eob_lo, eob_hi);
  eob_s = _mm_subs_epu16(_mm_set1_epi16(INT16_MAX), eob_s);
  eob_s = _mm_minpos_epu16(eob_s);
  return INT16_MAX - _mm_extract_epi16(eob_s, 0);
}

static INLINE int16_t accumulate_eob256(__m256i eob256) {
  const __m128i eob_lo = _mm256_castsi256_si128(eob256);
  const __m128i eob_hi = _mm256_extractf128_si256(eob256, 1);
  __m128i eob = _mm_max_epi16(eob_lo, eob_hi);
  __m128i eob_shuffled = _mm_shuffle_epi32(eob, 0xe);
  eob = _mm_max_epi16(eob, eob_shuffled);
  eob_shuffled = _mm_shufflelo_epi16(eob, 0xe);
  eob = _mm_max_epi16(eob, eob_shuffled);
  eob_shuffled = _mm_shufflelo_epi16(eob, 0x1);
  eob = _mm_max_epi16(eob, eob_shuffled);
  return _mm_extract_epi16(eob, 1);
}

static AOM_FORCE_INLINE void quantize_lp_16_first(
    const int16_t *coeff_ptr, const int16_t *iscan_ptr, int16_t *qcoeff_ptr,
    int16_t *dqcoeff_ptr, __m256i *round256, __m256i *quant256,
    __m256i *dequant256, __m256i *eob) {
  const __m256i coeff = _mm256_loadu_si256((const __m256i *)coeff_ptr);
  const __m256i abs_coeff = _mm256_abs_epi16(coeff);
  const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, *round256);
  const __m256i abs_qcoeff = _mm256_mulhi_epi16(tmp_rnd, *quant256);
  const __m256i qcoeff = _mm256_sign_epi16(abs_qcoeff, coeff);
  const __m256i dqcoeff = _mm256_mullo_epi16(qcoeff, *dequant256);
  const __m256i nz_mask =
      _mm256_cmpgt_epi16(abs_qcoeff, _mm256_setzero_si256());

  _mm256_storeu_si256((__m256i *)qcoeff_ptr, qcoeff);
  _mm256_storeu_si256((__m256i *)dqcoeff_ptr, dqcoeff);

  const __m256i iscan = _mm256_loadu_si256((const __m256i *)iscan_ptr);
  const __m256i iscan_plus1 = _mm256_sub_epi16(iscan, nz_mask);
  const __m256i nz_iscan = _mm256_and_si256(iscan_plus1, nz_mask);
  *eob = _mm256_max_epi16(*eob, nz_iscan);
}

static AOM_FORCE_INLINE void quantize_lp_16(
    const int16_t *coeff_ptr, intptr_t n_coeffs, const int16_t *iscan_ptr,
    int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, __m256i *round256,
    __m256i *quant256, __m256i *dequant256, __m256i *eob) {
  const __m256i coeff =
      _mm256_loadu_si256((const __m256i *)(coeff_ptr + n_coeffs));
  const __m256i abs_coeff = _mm256_abs_epi16(coeff);
  const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, *round256);
  const __m256i abs_qcoeff = _mm256_mulhi_epi16(tmp_rnd, *quant256);
  const __m256i qcoeff = _mm256_sign_epi16(abs_qcoeff, coeff);
  const __m256i dqcoeff = _mm256_mullo_epi16(qcoeff, *dequant256);
  const __m256i nz_mask =
      _mm256_cmpgt_epi16(abs_qcoeff, _mm256_setzero_si256());

  _mm256_storeu_si256((__m256i *)(qcoeff_ptr + n_coeffs), qcoeff);
  _mm256_storeu_si256((__m256i *)(dqcoeff_ptr + n_coeffs), dqcoeff);

  const __m256i iscan =
      _mm256_loadu_si256((const __m256i *)(iscan_ptr + n_coeffs));
  const __m256i iscan_plus1 = _mm256_sub_epi16(iscan, nz_mask);
  const __m256i nz_iscan = _mm256_and_si256(iscan_plus1, nz_mask);
  *eob = _mm256_max_epi16(*eob, nz_iscan);
}

void av1_quantize_lp_avx2(const int16_t *coeff_ptr, intptr_t n_coeffs,
                          const int16_t *round_ptr, const int16_t *quant_ptr,
                          int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
                          const int16_t *dequant_ptr, uint16_t *eob_ptr,
                          const int16_t *scan, const int16_t *iscan) {
  (void)scan;
  __m256i eob256 = _mm256_setzero_si256();

  // Setup global values.
  __m256i round256 =
      _mm256_castsi128_si256(_mm_load_si128((const __m128i *)round_ptr));
  __m256i quant256 =
      _mm256_castsi128_si256(_mm_load_si128((const __m128i *)quant_ptr));
  __m256i dequant256 =
      _mm256_castsi128_si256(_mm_load_si128((const __m128i *)dequant_ptr));

  // Populate upper AC values.
  round256 = _mm256_permute4x64_epi64(round256, 0x54);
  quant256 = _mm256_permute4x64_epi64(quant256, 0x54);
  dequant256 = _mm256_permute4x64_epi64(dequant256, 0x54);

  // Process DC and the first 15 AC coeffs.
  quantize_lp_16_first(coeff_ptr, iscan, qcoeff_ptr, dqcoeff_ptr, &round256,
                       &quant256, &dequant256, &eob256);

  if (n_coeffs > 16) {
    // Overwrite the DC constants with AC constants
    dequant256 = _mm256_permute2x128_si256(dequant256, dequant256, 0x31);
    quant256 = _mm256_permute2x128_si256(quant256, quant256, 0x31);
    round256 = _mm256_permute2x128_si256(round256, round256, 0x31);

    // AC only loop.
    for (int idx = 16; idx < n_coeffs; idx += 16) {
      quantize_lp_16(coeff_ptr, idx, iscan, qcoeff_ptr, dqcoeff_ptr, &round256,
                     &quant256, &dequant256, &eob256);
    }
  }

  *eob_ptr = accumulate_eob256(eob256);
}

static AOM_FORCE_INLINE __m256i get_max_lane_eob(const int16_t *iscan,
                                                 __m256i v_eobmax,
                                                 __m256i v_mask) {
  const __m256i v_iscan = _mm256_loadu_si256((const __m256i *)iscan);
  const __m256i v_iscan_perm = _mm256_permute4x64_epi64(v_iscan, 0xD8);
  const __m256i v_iscan_plus1 = _mm256_sub_epi16(v_iscan_perm, v_mask);
  const __m256i v_nz_iscan = _mm256_and_si256(v_iscan_plus1, v_mask);
  return _mm256_max_epi16(v_eobmax, v_nz_iscan);
}

static AOM_FORCE_INLINE void quantize_fp_16(
    const __m256i *thr, const __m256i *qp, const tran_low_t *coeff_ptr,
    const int16_t *iscan_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    __m256i *eob) {
  const __m256i coeff = load_coefficients_avx2(coeff_ptr);
  const __m256i abs_coeff = _mm256_abs_epi16(coeff);
  const __m256i mask = _mm256_cmpgt_epi16(abs_coeff, *thr);
  const int nzflag = _mm256_movemask_epi8(mask);

  if (nzflag) {
    const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, qp[0]);
    const __m256i abs_q = _mm256_mulhi_epi16(tmp_rnd, qp[1]);
    const __m256i q = _mm256_sign_epi16(abs_q, coeff);
    const __m256i dq = _mm256_mullo_epi16(q, qp[2]);
    const __m256i nz_mask = _mm256_cmpgt_epi16(abs_q, _mm256_setzero_si256());

    store_coefficients_avx2(q, qcoeff_ptr);
    store_coefficients_avx2(dq, dqcoeff_ptr);

    *eob = get_max_lane_eob(iscan_ptr, *eob, nz_mask);
  } else {
    write_zero(qcoeff_ptr);
    write_zero(dqcoeff_ptr);
  }
}

void av1_quantize_fp_avx2(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
                          const int16_t *zbin_ptr, const int16_t *round_ptr,
                          const int16_t *quant_ptr,
                          const int16_t *quant_shift_ptr,
                          tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
                          const int16_t *dequant_ptr, uint16_t *eob_ptr,
                          const int16_t *scan_ptr, const int16_t *iscan_ptr) {
  (void)scan_ptr;
  (void)zbin_ptr;
  (void)quant_shift_ptr;

  const int log_scale = 0;
  const int step = 16;
  __m256i qp[3], thr;
  __m256i eob = _mm256_setzero_si256();

  init_qp(round_ptr, quant_ptr, dequant_ptr, log_scale, &thr, qp);

  quantize_fp_16(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr, &eob);

  coeff_ptr += step;
  qcoeff_ptr += step;
  dqcoeff_ptr += step;
  iscan_ptr += step;
  n_coeffs -= step;

  update_qp(&thr, qp);

  while (n_coeffs > 0) {
    quantize_fp_16(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr,
                   &eob);

    coeff_ptr += step;
    qcoeff_ptr += step;
    dqcoeff_ptr += step;
    iscan_ptr += step;
    n_coeffs -= step;
  }
  *eob_ptr = quant_gather_eob(eob);
}

static AOM_FORCE_INLINE void quantize_fp_32x32(
    const __m256i *thr, const __m256i *qp, const tran_low_t *coeff_ptr,
    const int16_t *iscan_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
    __m256i *eob) {
  const __m256i coeff = load_coefficients_avx2(coeff_ptr);
  const __m256i abs_coeff = _mm256_abs_epi16(coeff);
  const __m256i mask = _mm256_cmpgt_epi16(abs_coeff, *thr);
  const int nzflag = _mm256_movemask_epi8(mask);

  if (nzflag) {
    const __m256i tmp_rnd = _mm256_adds_epi16(abs_coeff, qp[0]);
    const __m256i abs_q = _mm256_mulhi_epu16(tmp_rnd, qp[1]);
    const __m256i q = _mm256_sign_epi16(abs_q, coeff);
    const __m256i abs_dq =
        _mm256_srli_epi16(_mm256_mullo_epi16(abs_q, qp[2]), 1);
    const __m256i nz_mask = _mm256_cmpgt_epi16(abs_q, _mm256_setzero_si256());
    const __m256i dq = _mm256_sign_epi16(abs_dq, coeff);

    store_coefficients_avx2(q, qcoeff_ptr);
    store_coefficients_avx2(dq, dqcoeff_ptr);

    *eob = get_max_lane_eob(iscan_ptr, *eob, nz_mask);
  } else {
    write_zero(qcoeff_ptr);
    write_zero(dqcoeff_ptr);
  }
}

void av1_quantize_fp_32x32_avx2(
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
    const int16_t *round_ptr, const int16_t *quant_ptr,
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
    const int16_t *scan_ptr, const int16_t *iscan_ptr) {
  (void)scan_ptr;
  (void)zbin_ptr;
  (void)quant_shift_ptr;

  const int log_scale = 1;
  const unsigned int step = 16;
  __m256i qp[3], thr;
  __m256i eob = _mm256_setzero_si256();

  init_qp(round_ptr, quant_ptr, dequant_ptr, log_scale, &thr, qp);

  quantize_fp_32x32(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr,
                    &eob);

  coeff_ptr += step;
  qcoeff_ptr += step;
  dqcoeff_ptr += step;
  iscan_ptr += step;
  n_coeffs -= step;

  update_qp(&thr, qp);

  while (n_coeffs > 0) {
    quantize_fp_32x32(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr,
                      &eob);

    coeff_ptr += step;
    qcoeff_ptr += step;
    dqcoeff_ptr += step;
    iscan_ptr += step;
    n_coeffs -= step;
  }
  *eob_ptr = quant_gather_eob(eob);
}

static INLINE void quantize_fp_64x64(const __m256i *thr, const __m256i *qp,
                                     const tran_low_t *coeff_ptr,
                                     const int16_t *iscan_ptr,
                                     tran_low_t *qcoeff_ptr,
                                     tran_low_t *dqcoeff_ptr, __m256i *eob) {
  const __m256i coeff = load_coefficients_avx2(coeff_ptr);
  const __m256i abs_coeff = _mm256_abs_epi16(coeff);
  const __m256i mask = _mm256_cmpgt_epi16(abs_coeff, *thr);
  const int nzflag = _mm256_movemask_epi8(mask);

  if (nzflag) {
    const __m256i tmp_rnd =
        _mm256_and_si256(_mm256_adds_epi16(abs_coeff, qp[0]), mask);
    const __m256i qh = _mm256_slli_epi16(_mm256_mulhi_epi16(tmp_rnd, qp[1]), 2);
    const __m256i ql =
        _mm256_srli_epi16(_mm256_mullo_epi16(tmp_rnd, qp[1]), 14);
    const __m256i abs_q = _mm256_or_si256(qh, ql);
    const __m256i dqh = _mm256_slli_epi16(_mm256_mulhi_epi16(abs_q, qp[2]), 14);
    const __m256i dql = _mm256_srli_epi16(_mm256_mullo_epi16(abs_q, qp[2]), 2);
    const __m256i abs_dq = _mm256_or_si256(dqh, dql);
    const __m256i q = _mm256_sign_epi16(abs_q, coeff);
    const __m256i dq = _mm256_sign_epi16(abs_dq, coeff);
    // Check the signed q/dq value here instead of the absolute value. When
    // dequant equals 4, the dequant threshold (*thr) becomes 0 after being
    // scaled down by (1 + log_scale). See init_qp(). When *thr is 0 and the
    // abs_coeff is 0, the nzflag will be set. As a result, the eob will be
    // incorrectly calculated. The psign instruction corrects the error by
    // zeroing out q/dq if coeff is zero.
    const __m256i z_mask = _mm256_cmpeq_epi16(dq, _mm256_setzero_si256());
    const __m256i nz_mask = _mm256_cmpeq_epi16(z_mask, _mm256_setzero_si256());

    store_coefficients_avx2(q, qcoeff_ptr);
    store_coefficients_avx2(dq, dqcoeff_ptr);

    *eob = get_max_lane_eob(iscan_ptr, *eob, nz_mask);
  } else {
    write_zero(qcoeff_ptr);
    write_zero(dqcoeff_ptr);
  }
}

void av1_quantize_fp_64x64_avx2(
    const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
    const int16_t *round_ptr, const int16_t *quant_ptr,
    const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
    tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
    const int16_t *scan_ptr, const int16_t *iscan_ptr) {
  (void)scan_ptr;
  (void)zbin_ptr;
  (void)quant_shift_ptr;

  const int log_scale = 2;
  const unsigned int step = 16;
  __m256i qp[3], thr;
  __m256i eob = _mm256_setzero_si256();

  init_qp(round_ptr, quant_ptr, dequant_ptr, log_scale, &thr, qp);

  quantize_fp_64x64(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr,
                    &eob);

  coeff_ptr += step;
  qcoeff_ptr += step;
  dqcoeff_ptr += step;
  iscan_ptr += step;
  n_coeffs -= step;

  update_qp(&thr, qp);

  while (n_coeffs > 0) {
    quantize_fp_64x64(&thr, qp, coeff_ptr, iscan_ptr, qcoeff_ptr, dqcoeff_ptr,
                      &eob);

    coeff_ptr += step;
    qcoeff_ptr += step;
    dqcoeff_ptr += step;
    iscan_ptr += step;
    n_coeffs -= step;
  }
  *eob_ptr = quant_gather_eob(eob);
}
