// Copyright 2020 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 % 16 == 0
$assert BATCH_TILE >= 16
$ABC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$assert OP in ["ABS", "NEG", "SQR"]
#include <assert.h>

#include <immintrin.h>

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


$__M512 = {
$  "ABS": "__m512i",
$  "NEG": "__m512i",
$  "SQR": "__m512",
$}[OP]
$_MM512_LOADU = {
$  "ABS": "_mm512_loadu_si512",
$  "NEG": "_mm512_loadu_si512",
$  "SQR": "_mm512_loadu_ps",
$}[OP]
$_MM512_MASK_LOADU = {
$  "ABS": "_mm512_maskz_loadu_epi32",
$  "NEG": "_mm512_maskz_loadu_epi32",
$  "SQR": "_mm512_maskz_loadu_ps",
$}[OP]
$_MM512_STOREU = {
$  "ABS": "_mm512_storeu_si512",
$  "NEG": "_mm512_storeu_si512",
$  "SQR": "_mm512_storeu_ps",
$}[OP]
$_MM512_MASK_STOREU = {
$  "ABS": "_mm512_mask_storeu_epi32",
$  "NEG": "_mm512_mask_storeu_epi32",
$  "SQR": "_mm512_mask_storeu_ps",
$}[OP]
$_MM512_OP = {
$  "ABS": lambda x: "_mm512_and_epi32(%s, vnonsign_mask)" % x,
$  "NEG": lambda x: "_mm512_xor_epi32(%s, vsign_mask)" % x,
$  "SQR": lambda x: "_mm512_mul_ps(%s, %s)" % (x, x),
$}[OP]
$PARAMS = {
$  "ABS": "xnn_f32_abs_params",
$  "NEG": "xnn_f32_neg_params",
$  "SQR": "xnn_f32_default_params",
$}[OP]
void xnn_f32_v${OP.lower()}_ukernel__avx512f_x${BATCH_TILE}(
    size_t n,
    const float* x,
    float* y,
    const union ${PARAMS} params[restrict XNN_MIN_ELEMENTS(1)])
{
  assert(n != 0);
  assert(n % sizeof(float) == 0);
  assert(x != NULL);
  assert(y != NULL);

  $if OP == "ABS":
    const __m512i vnonsign_mask = _mm512_set1_epi32((int) params->avx512.nonsign_mask);
  $elif OP == "NEG":
    const __m512i vsign_mask = _mm512_set1_epi32((int) params->avx512.sign_mask);
  for (; n >= ${BATCH_TILE} * sizeof(float); n -= ${BATCH_TILE} * sizeof(float)) {
    const ${__M512} vx${ABC[0:16]} = ${_MM512_LOADU}(x);
    $for N in range(16, BATCH_TILE, 16):
      const ${__M512} vx${ABC[N:N+16]} = ${_MM512_LOADU}(x + ${N});
    x += ${BATCH_TILE};

    $for N in range(0, BATCH_TILE, 16):
      const ${__M512} vy${ABC[N:N+16]} = ${_MM512_OP("vx" + ABC[N:N+16])};

    ${_MM512_STOREU}(y, vy${ABC[0:16]});
    $for N in range(16, BATCH_TILE, 16):
      ${_MM512_STOREU}(y + ${N}, vy${ABC[N:N+16]});
    y += ${BATCH_TILE};
  }
  $if BATCH_TILE > 16:
    for (; n >= 16 * sizeof(float); n -= 16 * sizeof(float)) {
      const ${__M512} vx = ${_MM512_LOADU}(x);
      x += 16;

      const ${__M512} vy = ${_MM512_OP("vx")};

      ${_MM512_STOREU}(y, vy);
      y += 16;
    }
  if XNN_UNLIKELY(n != 0) {
    assert(n >= 1 * sizeof(float));
    assert(n <= 15 * sizeof(float));
    // Prepare mask for valid 32-bit elements (depends on n).
    n >>= 2 /* log2(sizeof(float)) */;
    const __mmask16 vmask = _cvtu32_mask16((uint16_t) ((uint32_t) (UINT32_C(1) << n) - UINT32_C(1)));

    const ${__M512} vx = ${_MM512_MASK_LOADU}(vmask, x);
    const ${__M512} vy = ${_MM512_OP("vx")};
    ${_MM512_MASK_STOREU}(y, vmask, vy);
  }
}
