// Copyright 2022 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

$assert BATCH_TILE >= 8
$assert BATCH_TILE == 8 or BATCH_TILE % 16 == 0
$SIMD_TILE = BATCH_TILE // 16
$ABC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#include <assert.h>

#include <immintrin.h>

#include <xnnpack/common.h>
#include <xnnpack/intrinsics-polyfill.h>
#include <xnnpack/vlrelu.h>


$XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
$_MM_CVTEPX8_EPI16 = {"QS8": "_mm_cvtepi8_epi16", "QU8": "_mm_cvtepu8_epi16"}[DATATYPE]
$_MM_PACKXS_EPI16 = {"QS8": "_mm_packs_epi16", "QU8": "_mm_packus_epi16"}[DATATYPE]
$ISA = "avx" if AVX else "sse41"
void xnn_${DATATYPE.lower()}_vlrelu_ukernel__${ISA}_x${BATCH_TILE}(
    size_t n,
    const ${XINT8_T}* x,
    ${XINT8_T}* y,
    const union xnn_${DATATYPE.lower()}_lrelu_params params[restrict XNN_MIN_ELEMENTS(1)]) XNN_OOB_READS
{
  assert(n != 0);
  assert(n % sizeof(${XINT8_T}) == 0);
  assert(x != NULL);
  assert(y != NULL);

  $if AVX:
    const __m128i vinput_zero_point = _mm_load_si128((const __m128i*) params->avx.input_zero_point);
    const __m128i vpositive_multiplier = _mm_load_si128((const __m128i*) params->avx.positive_multiplier);
    const __m128i vnegative_multiplier = _mm_load_si128((const __m128i*) params->avx.negative_multiplier);
    const __m128i voutput_zero_point = _mm_load_si128((const __m128i*) params->avx.output_zero_point);
  $else:
    const __m128i vinput_zero_point = _mm_load_si128((const __m128i*) params->sse2.input_zero_point);
    const __m128i vmultiplier_diff = _mm_load_si128((const __m128i*) params->sse2.multiplier_diff);
    const __m128i vmultiplier_base = _mm_load_si128((const __m128i*) params->sse2.multiplier_base);
    const __m128i voutput_zero_point = _mm_load_si128((const __m128i*) params->sse2.output_zero_point);
  $if BATCH_TILE > 8:
    for (; n >= ${BATCH_TILE} * sizeof(${XINT8_T}); n -= ${BATCH_TILE} * sizeof(${XINT8_T})) {
      __m128i vacc${ABC[0]} = ${_MM_CVTEPX8_EPI16}(_mm_loadl_epi64((const __m128i*) x));
      $for N in range(1, 2*SIMD_TILE):
        __m128i vacc${ABC[N]} = ${_MM_CVTEPX8_EPI16}(_mm_loadl_epi64((const __m128i*) (x + ${N * 8})));
      x += ${BATCH_TILE};

      $for N in range(2*SIMD_TILE):
        __m128i vmultiplier${ABC[N]} = _mm_cmpgt_epi16(vacc${ABC[N]}, vinput_zero_point);
        vacc${ABC[N]} = _mm_sub_epi16(vinput_zero_point, vacc${ABC[N]});

      $for N in range(2*SIMD_TILE):
        $if AVX:
          vmultiplier${ABC[N]} = _mm_blendv_epi8(vnegative_multiplier, vpositive_multiplier, vmultiplier${ABC[N]});
        $else:
          vmultiplier${ABC[N]} = _mm_and_si128(vmultiplier${ABC[N]}, vmultiplier_diff);
        vacc${ABC[N]} = _mm_slli_epi16(vacc${ABC[N]}, 7);
        $if not AVX:
          vmultiplier${ABC[N]} = _mm_xor_si128(vmultiplier${ABC[N]}, vmultiplier_base);

      $for N in range(2*SIMD_TILE):
        vacc${ABC[N]} = _mm_mulhrs_epi16(vacc${ABC[N]}, vmultiplier${ABC[N]});

      $for N in range(2*SIMD_TILE):
        vacc${ABC[N]} = _mm_adds_epi16(vacc${ABC[N]}, voutput_zero_point);

      $for N in range(SIMD_TILE):
        const __m128i vy${ABC[N]} = ${_MM_PACKXS_EPI16}(vacc${ABC[2*N]}, vacc${ABC[2*N+1]});

      _mm_storeu_si128((__m128i*) y, vy${ABC[0]});
      $for N in range(1, SIMD_TILE):
        _mm_storeu_si128((__m128i*) (y + ${N * 16}), vy${ABC[N]});
      y += ${BATCH_TILE};
    }
  for (; n >= 8 * sizeof(${XINT8_T}); n -= 8 * sizeof(${XINT8_T})) {
    __m128i vacc = ${_MM_CVTEPX8_EPI16}(_mm_loadl_epi64((const __m128i*) x));
    __m128i vmultiplier = _mm_cmpgt_epi16(vacc, vinput_zero_point);
    vacc = _mm_sub_epi16(vinput_zero_point, vacc);
    $if AVX:
      vmultiplier = _mm_blendv_epi8(vnegative_multiplier, vpositive_multiplier, vmultiplier);
    $else:
      vmultiplier = _mm_and_si128(vmultiplier, vmultiplier_diff);
    vacc = _mm_slli_epi16(vacc, 7);
    $if not AVX:
      vmultiplier = _mm_xor_si128(vmultiplier, vmultiplier_base);
    vacc = _mm_mulhrs_epi16(vacc, vmultiplier);
    vacc = _mm_adds_epi16(vacc, voutput_zero_point);
    x += 8;

    const __m128i vy = ${_MM_PACKXS_EPI16}(vacc, vacc);
    _mm_storel_epi64((__m128i*) y, vy);
    y += 8;
  }
  if XNN_UNLIKELY(n != 0) {
    assert(n >= 1 * sizeof(${XINT8_T}));
    assert(n <= 7 * sizeof(${XINT8_T}));

    __m128i vacc = ${_MM_CVTEPX8_EPI16}(_mm_loadl_epi64((const __m128i*) x));
    __m128i vmultiplier = _mm_cmpgt_epi16(vacc, vinput_zero_point);
    vacc = _mm_sub_epi16(vinput_zero_point, vacc);
    $if AVX:
      vmultiplier = _mm_blendv_epi8(vnegative_multiplier, vpositive_multiplier, vmultiplier);
    $else:
      vmultiplier = _mm_and_si128(vmultiplier, vmultiplier_diff);
    vacc = _mm_slli_epi16(vacc, 7);
    $if not AVX:
      vmultiplier = _mm_xor_si128(vmultiplier, vmultiplier_base);
    vacc = _mm_mulhrs_epi16(vacc, vmultiplier);
    vacc = _mm_adds_epi16(vacc, voutput_zero_point);

    __m128i vy = ${_MM_PACKXS_EPI16}(vacc, vacc);
    if (n & (4 * sizeof(${XINT8_T}))) {
      _mm_storeu_si32(y, vy);
      vy = _mm_srli_epi64(vy, 32);
      y += 4;
    }
    if (n & (2 * sizeof(${XINT8_T}))) {
      _mm_storeu_si16(y, vy);
      vy = _mm_srli_epi32(vy, 16);
      y += 2;
    }
    if (n & (1 * sizeof(${XINT8_T}))) {
      *y = (${XINT8_T}) _mm_extract_epi8(vy, 0);
    }
  }
}
