// 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 DATATYPE in ["QS8", "QU8"]
$assert BATCH_TILE >= 1
#include <assert.h>

#include <xnnpack/math.h>
#include <xnnpack/vadd.h>


$XINT8_T = {"QS8": "int8_t", "QU8": "uint8_t"}[DATATYPE]
void xnn_${DATATYPE.lower()}_vaddc_minmax_ukernel__scalar_x${BATCH_TILE}(
    size_t n,
    const ${XINT8_T}* input_a,
    const ${XINT8_T}* input_b,
    ${XINT8_T}* output,
    const union xnn_${DATATYPE.lower()}_add_minmax_params params[restrict XNN_MIN_ELEMENTS(1)])
{
  const int32_t vbias = params->scalar.bias + (int32_t) *input_b * params->scalar.b_multiplier;
  const int32_t va_multiplier = params->scalar.a_multiplier;
  const uint32_t vshift = params->scalar.shift;
  const int32_t voutput_min_less_zero_point = params->scalar.output_min_less_zero_point;
  const int32_t voutput_max_less_zero_point = params->scalar.output_max_less_zero_point;
  const int32_t voutput_zero_point = params->scalar.output_zero_point;

  $if BATCH_TILE == 1:
    do {
      const int32_t va = *input_a++;
      const int32_t vacc = vbias + va * va_multiplier;

      int32_t vout = math_asr_s32(vacc, vshift);
      vout = math_max_s32(vout, voutput_min_less_zero_point);
      vout = math_min_s32(vout, voutput_max_less_zero_point);
      *output++ = (${XINT8_T}) (vout + voutput_zero_point);

      n -= sizeof(${XINT8_T});
    } while (n != 0);
  $else:
    for (; n >= ${BATCH_TILE} * sizeof(${XINT8_T}); n -= ${BATCH_TILE} * sizeof(${XINT8_T})) {
      $for N in range(BATCH_TILE):
        const int32_t va${N} = input_a[${N}];
      input_a += ${BATCH_TILE};

      $for N in range(BATCH_TILE):
        const int32_t vacc${N} = vbias + va${N} * va_multiplier;
      input_b += ${BATCH_TILE};

      $for N in range(BATCH_TILE):
        int32_t vout${N} = math_asr_s32(vacc${N}, vshift);

      $for N in range(BATCH_TILE):
        vout${N} = math_max_s32(vout${N}, voutput_min_less_zero_point);

      $for N in range(BATCH_TILE):
        vout${N} = math_min_s32(vout${N}, voutput_max_less_zero_point);

      $for N in range(BATCH_TILE):
        vout${N} += voutput_zero_point;

      $for N in range(BATCH_TILE):
        output[${N}] = (${XINT8_T}) vout${N};
      output += ${BATCH_TILE};
    }
    if XNN_UNLIKELY(n != 0) {
      $if BATCH_TILE == 2:
        const int32_t va = *input_a;
        const int32_t vacc = vbias + va * va_multiplier;

        int32_t vout = math_asr_s32(vacc, vshift);
        vout = math_max_s32(vout, voutput_min_less_zero_point);
        vout = math_min_s32(vout, voutput_max_less_zero_point);
        *output++ = (${XINT8_T}) (vout + voutput_zero_point);
      $else:
        do {
          const int32_t va = *input_a++;
          const int32_t vacc = vbias + va * va_multiplier;

          int32_t vout = math_asr_s32(vacc, vshift);
          vout = math_max_s32(vout, voutput_min_less_zero_point);
          vout = math_min_s32(vout, voutput_max_less_zero_point);
          *output++ = (${XINT8_T}) (vout + voutput_zero_point);

          n -= sizeof(${XINT8_T});
        } while (n != 0);
    }
}
