// 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 % 4 == 0
$assert BATCH_TILE >= 4
$ABC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
$assert OP in ["ADD", "DIV", "RDIV", "MAX", "MIN", "MUL", "SUB", "RSUB", "SQRDIFF"]
$assert ACTIVATION in ["LINEAR", "MINMAX", "RELU"]
#include <assert.h>

#include <wasm_simd128.h>

#include <xnnpack/common.h>
#include <xnnpack/vbinary.h>


$WASM_F32X4_OP = {
$  "ADD": lambda x: "wasm_f32x4_add(%s, vb)" % x,
$  "DIV": lambda x: "wasm_f32x4_div(%s, vb)" % x,
$  "RDIV": lambda x: "wasm_f32x4_div(vb, %s)" % x,
$  "MAX": lambda x: ("wasm_f32x4_pmax(vb, %s)" if X86 else "wasm_f32x4_max(%s, vb)") % x,
$  "MIN": lambda x: ("wasm_f32x4_pmin(vb, %s)" if X86 else "wasm_f32x4_min(%s, vb)") % x,
$  "MUL": lambda x: "wasm_f32x4_mul(%s, vb)" % x,
$  "SUB": lambda x: "wasm_f32x4_sub(%s, vb)" % x,
$  "RSUB": lambda x: "wasm_f32x4_sub(vb, %s)" % x,
$  "SQRDIFF": lambda x: "wasm_f32x4_sub(%s, vb)" % x,
$}[OP]
$assert ACTIVATION in ["LINEAR", "RELU", "MINMAX"]
$ARCH_SUFFIX = "" if ACTIVATION in ["LINEAR", "RELU"] and OP not in ["MIN", "MAX"] else "_x86" if X86 else "_arm"
$ACTIVATION_SUFFIX = {"LINEAR": ""}.get(ACTIVATION, "_" + ACTIVATION.lower())
$PARAMS = {"LINEAR": "xnn_f32_default_params", "RELU": "xnn_f32_relu_params", "MINMAX": "xnn_f32_minmax_params"}[ACTIVATION]
void xnn_f32_v${OP.lower()}c${ACTIVATION_SUFFIX}_ukernel__wasmsimd${ARCH_SUFFIX}_x${BATCH_TILE}(
    size_t n,
    const float* a,
    const float* b,
    float* y,
    const union ${PARAMS} params[restrict XNN_MIN_ELEMENTS(1)]) XNN_OOB_READS
{
  assert(n != 0);
  assert(n % sizeof(float) == 0);
  assert(a != NULL);
  assert(b != NULL);
  assert(y != NULL);

  $if ACTIVATION == "MINMAX":
    const v128_t vy_min = wasm_v128_load64_splat(params->wasmsimd.min);
    const v128_t vy_max = wasm_v128_load64_splat(params->wasmsimd.max);
  $elif ACTIVATION == "RELU":
    const v128_t vzero = wasm_i32x4_const_splat(0);
  const v128_t vb = wasm_v128_load32_splat(b);
  for (; n >= ${BATCH_TILE} * sizeof(float); n -= ${BATCH_TILE} * sizeof(float)) {
    const v128_t va${ABC[0:4]} = wasm_v128_load(a);
    $for N in range(4, BATCH_TILE, 4):
      const v128_t va${ABC[N:N+4]} = wasm_v128_load(a + ${N});
    a += ${BATCH_TILE};

    $for N in range(0, BATCH_TILE, 4):
      v128_t vy${ABC[N:N+4]} = ${WASM_F32X4_OP("va" + ABC[N:N+4])};

    $if OP == "SQRDIFF":
      $for N in range(0, BATCH_TILE, 4):
        vy${ABC[N:N+4]} = wasm_f32x4_mul(vy${ABC[N:N+4]}, vy${ABC[N:N+4]});

    $if ACTIVATION == "MINMAX":
      $if X86:
        $for N in range(0, BATCH_TILE, 4):
          vy${ABC[N:N+4]} = wasm_f32x4_pmax(vy_min, vy${ABC[N:N+4]});

        $for N in range(0, BATCH_TILE, 4):
          vy${ABC[N:N+4]} = wasm_f32x4_pmin(vy_max, vy${ABC[N:N+4]});
      $else:
        $for N in range(0, BATCH_TILE, 4):
          vy${ABC[N:N+4]} = wasm_f32x4_max(vy${ABC[N:N+4]}, vy_min);

        $for N in range(0, BATCH_TILE, 4):
          vy${ABC[N:N+4]} = wasm_f32x4_min(vy${ABC[N:N+4]}, vy_max);
    $elif ACTIVATION == "RELU":
      $for N in range(0, BATCH_TILE, 4):
        vy${ABC[N:N+4]} = wasm_i32x4_max(vy${ABC[N:N+4]}, vzero);

    wasm_v128_store(y, vy${ABC[0:4]});
    $for N in range(4, BATCH_TILE, 4):
      wasm_v128_store(y + ${N}, vy${ABC[N:N+4]});
    y += ${BATCH_TILE};
  }
  $if BATCH_TILE > 4:
    for (; n >= 4 * sizeof(float); n -= 4 * sizeof(float)) {
      const v128_t va = wasm_v128_load(a);
      a += 4;

      v128_t vy = ${WASM_F32X4_OP("va")};
      $if OP == "SQRDIFF":
        vy = wasm_f32x4_mul(vy, vy);

      $if ACTIVATION == "MINMAX":
        $if X86:
          vy = wasm_f32x4_pmax(vy_min, vy);
          vy = wasm_f32x4_pmin(vy_max, vy);
        $else:
          vy = wasm_f32x4_max(vy, vy_min);
          vy = wasm_f32x4_min(vy, vy_max);
      $elif ACTIVATION == "RELU":
        vy = wasm_i32x4_max(vy, vzero);

      wasm_v128_store(y, vy);
      y += 4;
    }
  if XNN_UNLIKELY(n != 0) {
    const v128_t va = wasm_v128_load(a);

    v128_t vy = ${WASM_F32X4_OP("va")};
    $if OP == "SQRDIFF":
      vy = wasm_f32x4_mul(vy, vy);

    $if ACTIVATION == "MINMAX":
      $if X86:
        vy = wasm_f32x4_pmax(vy_min, vy);
        vy = wasm_f32x4_pmin(vy_max, vy);
      $else:
        vy = wasm_f32x4_max(vy, vy_min);
        vy = wasm_f32x4_min(vy, vy_max);
    $elif ACTIVATION == "RELU":
      vy = wasm_i32x4_max(vy, vzero);

    if (n & (2 * sizeof(float))) {
      *((double*) y) = wasm_f64x2_extract_lane(vy, 0);
      vy = wasm_v32x4_shuffle(vy, vy, 2, 3, 2, 3);
      y += 2;
    }
    if (n & (1 * sizeof(float))) {
      *y = wasm_f32x4_extract_lane(vy, 0);
    }
  }
}
