// Copyright 2021 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 >= 1
#include <assert.h>

#include <xnnpack/common.h>
#include <xnnpack/math.h>
#include <xnnpack/vcvt.h>


$XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
$MIN_F32 = "__builtin_wasm_min_f32" if WASM else "math_min_f32"
$MAX_F32 = "__builtin_wasm_max_f32" if WASM else "math_max_f32"
void xnn_f32_${DATATYPE.lower()}_vcvt_ukernel__${"wasm" if WASM else "scalar"}_fmagic_x${BATCH_TILE}(
    size_t n,
    const float* x,
    ${XINT8_T}* y,
    const union xnn_f32_${DATATYPE.lower()}_cvt_params params[restrict XNN_MIN_ELEMENTS(1)])
{
  assert(n != 0);
  assert(n % sizeof(float) == 0);
  assert(x != NULL);
  assert(y != NULL);

  const float vscale = params->scalar_fmagic.scale;
  const float voutput_min_less_zero_point = params->scalar_fmagic.output_min_less_zero_point;
  const float voutput_max_less_zero_point = params->scalar_fmagic.output_max_less_zero_point;
  const float vmagic_bias = params->scalar_fmagic.magic_bias;
  const int32_t vmagic_bias_less_zero_point = params->scalar_fmagic.magic_bias_less_zero_point;

  $if BATCH_TILE > 1:
    for (; n >= ${BATCH_TILE} * sizeof(float); n -= ${BATCH_TILE} * sizeof(float)) {
      $for N in range(BATCH_TILE):
        float vx${N} = x[${N}];
      x += ${BATCH_TILE};

      $for N in range(BATCH_TILE):
        vx${N} *= vscale;

      $for N in range(BATCH_TILE):
        vx${N} = ${MAX_F32}(vx${N}, voutput_min_less_zero_point);

      $for N in range(BATCH_TILE):
        vx${N} = ${MIN_F32}(vx${N}, voutput_max_less_zero_point);

      $for N in range(BATCH_TILE):
        vx${N} += vmagic_bias;

      $for N in range(BATCH_TILE):
        int32_t vy${N} = (int32_t) float_as_uint32(vx${N});

      $for N in range(BATCH_TILE):
        vy${N} -= vmagic_bias_less_zero_point;

      $for N in range(BATCH_TILE):
        y[${N}] = (${XINT8_T}) vy${N};
      y += ${BATCH_TILE};
    }
  $if BATCH_TILE == 1:
    do {
      float vx = *x++;
      vx *= vscale;
      vx = ${MAX_F32}(vx, voutput_min_less_zero_point);
      vx = ${MIN_F32}(vx, voutput_max_less_zero_point);
      vx += vmagic_bias;

      int32_t vy = (int32_t) float_as_uint32(vx);
      vy -= vmagic_bias_less_zero_point;

      *y++ = (${XINT8_T}) vy;

      n -= sizeof(float);
    } while (n != 0);
  $elif BATCH_TILE == 2:
    if XNN_UNLIKELY(n != 0) {
      float vx = *x;
      vx *= vscale;
      vx = ${MAX_F32}(vx, voutput_min_less_zero_point);
      vx = ${MIN_F32}(vx, voutput_max_less_zero_point);
      vx += vmagic_bias;

      int32_t vy = (int32_t) float_as_uint32(vx);
      vy -= vmagic_bias_less_zero_point;

      *y = (${XINT8_T}) vy;
    }
  $else:
    if XNN_UNLIKELY(n != 0) {
      do {
        float vx = *x++;
        vx *= vscale;
        vx = ${MAX_F32}(vx, voutput_min_less_zero_point);
        vx = ${MIN_F32}(vx, voutput_max_less_zero_point);
        vx += vmagic_bias;

        int32_t vy = (int32_t) float_as_uint32(vx);
        vy -= vmagic_bias_less_zero_point;

        *y++ = (${XINT8_T}) vy;

        n -= sizeof(float);
      } while (n != 0);
    }
}
