/*
 *  Copyright (c) 2018, Alliance for Open Media. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef AV1_COMMON_ARM_CONVOLVE_NEON_H_
#define AV1_COMMON_ARM_CONVOLVE_NEON_H_

#include <arm_neon.h>

#define HORIZ_EXTRA_ROWS ((SUBPEL_TAPS + 7) & ~0x07)

static INLINE uint8x8_t wiener_convolve8_vert_4x8(
    const int16x8_t s0, const int16x8_t s1, const int16x8_t s2,
    const int16x8_t s3, const int16x8_t s4, const int16x8_t s5,
    const int16x8_t s6, int16_t *filter_y, const int bd,
    const int round1_bits) {
  int16x8_t ss0, ss1, ss2;
  int32x4_t sum0, sum1;
  uint16x4_t tmp0, tmp1;
  uint16x8_t tmp;
  uint8x8_t res;

  const int32_t round_const = (1 << (bd + round1_bits - 1));
  const int32x4_t round_bits = vdupq_n_s32(-round1_bits);
  const int32x4_t zero = vdupq_n_s32(0);
  const int32x4_t round_vec = vdupq_n_s32(round_const);

  ss0 = vaddq_s16(s0, s6);
  ss1 = vaddq_s16(s1, s5);
  ss2 = vaddq_s16(s2, s4);

  sum0 = vmull_n_s16(vget_low_s16(ss0), filter_y[0]);
  sum0 = vmlal_n_s16(sum0, vget_low_s16(ss1), filter_y[1]);
  sum0 = vmlal_n_s16(sum0, vget_low_s16(ss2), filter_y[2]);
  sum0 = vmlal_n_s16(sum0, vget_low_s16(s3), filter_y[3]);

  sum1 = vmull_n_s16(vget_high_s16(ss0), filter_y[0]);
  sum1 = vmlal_n_s16(sum1, vget_high_s16(ss1), filter_y[1]);
  sum1 = vmlal_n_s16(sum1, vget_high_s16(ss2), filter_y[2]);
  sum1 = vmlal_n_s16(sum1, vget_high_s16(s3), filter_y[3]);

  sum0 = vsubq_s32(sum0, round_vec);
  sum1 = vsubq_s32(sum1, round_vec);

  /* right shift & rounding */
  sum0 = vrshlq_s32(sum0, round_bits);
  sum1 = vrshlq_s32(sum1, round_bits);

  sum0 = vmaxq_s32(sum0, zero);
  sum1 = vmaxq_s32(sum1, zero);

  /* from int32x4_t to uint8x8_t */
  tmp0 = vqmovn_u32(vreinterpretq_u32_s32(sum0));
  tmp1 = vqmovn_u32(vreinterpretq_u32_s32(sum1));
  tmp = vcombine_u16(tmp0, tmp1);
  res = vqmovn_u16(tmp);

  return res;
}

static INLINE uint16x8_t wiener_convolve8_horiz_8x8(
    const int16x8_t s0, const int16x8_t s1, const int16x8_t s2,
    const int16x8_t s3, int16_t *filter_x, const int bd,
    const int round0_bits) {
  int16x8_t sum;
  uint16x8_t res;
  int32x4_t sum_0, sum_1;
  int32x4_t s3_0, s3_1;
  const int32_t round_const_0 = (1 << (bd + FILTER_BITS - 1));
  const int32_t round_const_1 = (1 << ((bd) + 1 + FILTER_BITS - round0_bits));

  /* for the purpose of right shift by { conv_params->round_0 } */
  const int32x4_t round_bits = vdupq_n_s32(-round0_bits);

  const int32x4_t round_vec_0 = vdupq_n_s32(round_const_0);
  const int32x4_t round_vec_1 = vdupq_n_s32(round_const_1);

  sum = vmulq_n_s16(s0, filter_x[0]);
  sum = vmlaq_n_s16(sum, s1, filter_x[1]);
  sum = vmlaq_n_s16(sum, s2, filter_x[2]);

  /* sum from 16x8 to 2 32x4 registers */
  sum_0 = vmovl_s16(vget_low_s16(sum));
  sum_1 = vmovl_s16(vget_high_s16(sum));

  /* s[3]*128 -- and filter coef max can be 128
   *  then max value possible = 128*128*255 exceeding 16 bit
   */

  s3_0 = vmull_n_s16(vget_low_s16(s3), filter_x[3]);
  s3_1 = vmull_n_s16(vget_high_s16(s3), filter_x[3]);
  sum_0 = vaddq_s32(sum_0, s3_0);
  sum_1 = vaddq_s32(sum_1, s3_1);

  /* Add the constant value */
  sum_0 = vaddq_s32(sum_0, round_vec_0);
  sum_1 = vaddq_s32(sum_1, round_vec_0);

  /* right shift & rounding & saturating */
  sum_0 = vqrshlq_s32(sum_0, round_bits);
  sum_1 = vqrshlq_s32(sum_1, round_bits);

  /* Clipping to max value */
  sum_0 = vminq_s32(sum_0, round_vec_1);
  sum_1 = vminq_s32(sum_1, round_vec_1);

  res = vcombine_u16(vqmovun_s32(sum_0), vqmovun_s32(sum_1));
  return res;
}

static INLINE uint16x4_t wiener_convolve8_horiz_4x8(
    const int16x4_t s0, const int16x4_t s1, const int16x4_t s2,
    const int16x4_t s3, const int16x4_t s4, const int16x4_t s5,
    const int16x4_t s6, int16_t *filter_x, const int bd,
    const int round0_bits) {
  uint16x4_t res;
  int32x4_t sum_0, s3_0;
  int16x4_t sum, temp0, temp1, temp2;

  const int32_t round_const_0 = (1 << (bd + FILTER_BITS - 1));
  const int32_t round_const_1 = (1 << ((bd) + 1 + FILTER_BITS - round0_bits));
  const int32x4_t round_bits = vdupq_n_s32(-round0_bits);
  const int32x4_t zero = vdupq_n_s32(0);
  const int32x4_t round_vec_0 = vdupq_n_s32(round_const_0);
  const int32x4_t round_vec_1 = vdupq_n_s32(round_const_1);

  temp0 = vadd_s16(s0, s6);
  temp1 = vadd_s16(s1, s5);
  temp2 = vadd_s16(s2, s4);

  sum = vmul_n_s16(temp0, filter_x[0]);
  sum = vmla_n_s16(sum, temp1, filter_x[1]);
  sum = vmla_n_s16(sum, temp2, filter_x[2]);
  sum_0 = vmovl_s16(sum);

  /* s[3]*128 -- and filter coff max can be 128.
   * then max value possible = 128*128*255 Therefore, 32 bits are required to
   * hold the result.
   */
  s3_0 = vmull_n_s16(s3, filter_x[3]);
  sum_0 = vaddq_s32(sum_0, s3_0);

  sum_0 = vaddq_s32(sum_0, round_vec_0);
  sum_0 = vrshlq_s32(sum_0, round_bits);

  sum_0 = vmaxq_s32(sum_0, zero);
  sum_0 = vminq_s32(sum_0, round_vec_1);
  res = vqmovun_s32(sum_0);
  return res;
}

static INLINE int16x8_t
convolve8_8x8_s16(const int16x8_t s0, const int16x8_t s1, const int16x8_t s2,
                  const int16x8_t s3, const int16x8_t s4, const int16x8_t s5,
                  const int16x8_t s6, const int16x8_t s7, const int16_t *filter,
                  const int16x8_t horiz_const, const int16x8_t shift_round_0) {
  int16x8_t sum;
  int16x8_t res;

  sum = horiz_const;
  sum = vmlaq_n_s16(sum, s0, filter[0]);
  sum = vmlaq_n_s16(sum, s1, filter[1]);
  sum = vmlaq_n_s16(sum, s2, filter[2]);
  sum = vmlaq_n_s16(sum, s3, filter[3]);
  sum = vmlaq_n_s16(sum, s4, filter[4]);
  sum = vmlaq_n_s16(sum, s5, filter[5]);
  sum = vmlaq_n_s16(sum, s6, filter[6]);
  sum = vmlaq_n_s16(sum, s7, filter[7]);

  res = vqrshlq_s16(sum, shift_round_0);

  return res;
}

static INLINE int16x4_t
convolve8_4x4_s16(const int16x4_t s0, const int16x4_t s1, const int16x4_t s2,
                  const int16x4_t s3, const int16x4_t s4, const int16x4_t s5,
                  const int16x4_t s6, const int16x4_t s7, const int16_t *filter,
                  const int16x4_t horiz_const, const int16x4_t shift_round_0) {
  int16x4_t sum;
  sum = horiz_const;
  sum = vmla_n_s16(sum, s0, filter[0]);
  sum = vmla_n_s16(sum, s1, filter[1]);
  sum = vmla_n_s16(sum, s2, filter[2]);
  sum = vmla_n_s16(sum, s3, filter[3]);
  sum = vmla_n_s16(sum, s4, filter[4]);
  sum = vmla_n_s16(sum, s5, filter[5]);
  sum = vmla_n_s16(sum, s6, filter[6]);
  sum = vmla_n_s16(sum, s7, filter[7]);

  sum = vqrshl_s16(sum, shift_round_0);

  return sum;
}

static INLINE uint16x4_t convolve8_4x4_s32(
    const int16x4_t s0, const int16x4_t s1, const int16x4_t s2,
    const int16x4_t s3, const int16x4_t s4, const int16x4_t s5,
    const int16x4_t s6, const int16x4_t s7, const int16_t *y_filter,
    const int32x4_t round_shift_vec, const int32x4_t offset_const) {
  int32x4_t sum0;
  uint16x4_t res;
  const int32x4_t zero = vdupq_n_s32(0);

  sum0 = vmull_n_s16(s0, y_filter[0]);
  sum0 = vmlal_n_s16(sum0, s1, y_filter[1]);
  sum0 = vmlal_n_s16(sum0, s2, y_filter[2]);
  sum0 = vmlal_n_s16(sum0, s3, y_filter[3]);
  sum0 = vmlal_n_s16(sum0, s4, y_filter[4]);
  sum0 = vmlal_n_s16(sum0, s5, y_filter[5]);
  sum0 = vmlal_n_s16(sum0, s6, y_filter[6]);
  sum0 = vmlal_n_s16(sum0, s7, y_filter[7]);

  sum0 = vaddq_s32(sum0, offset_const);
  sum0 = vqrshlq_s32(sum0, round_shift_vec);
  sum0 = vmaxq_s32(sum0, zero);
  res = vmovn_u32(vreinterpretq_u32_s32(sum0));

  return res;
}

#endif  // AV1_COMMON_ARM_CONVOLVE_NEON_H_
