// 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 REQUANTIZATION == "FP32"
$assert DATATYPE in ["QC8", "QS8", "QU8"]
$assert VARIANT in ["LD64", "LD128", "EXTENDED"]
$assert MR <= 4
#include <assert.h>

#include <wasm_simd128.h>

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


$LOAD_SUFFIX = {"LD128": "_ld128", "LD64": "_ld64", "EXTENDED": ""}[VARIANT]
$GEMM_SUFFIX = "_xw" if VARIANT == "EXTENDED" else ""
$PARAMS_UNION = "xnn_qs8_minmax_params" if DATATYPE == "QC8" else "xnn_%s_conv_minmax_params" % DATATYPE.lower()
$PARAMS_STRUCT = "wasmsimd" if DATATYPE == "QC8" else "fp32_wasmsimd"
$XINT8_T = "uint8_t" if DATATYPE == "QU8" else "int8_t"
$WASM_X16X8_LOAD8X8 = "wasm_u16x8_load8x8" if DATATYPE == "QU8" else "wasm_i16x8_load8x8"
$WASM_X8X16_NARROW_I16X8 = "wasm_u8x16_narrow_i16x8" if DATATYPE == "QU8" else "wasm_i8x16_narrow_i16x8"
$WASM_X8X16_MIN = "wasm_u8x16_min" if DATATYPE == "QU8" else "wasm_i8x16_min"
void xnn_${DATATYPE.lower()}_gemm${GEMM_SUFFIX}_minmax_fp32_ukernel_${MR}x4c8__wasmsimd_dot16x2${LOAD_SUFFIX}(
    size_t mr,
    size_t nc,
    size_t kc,
    const ${XINT8_T}* restrict a,
    size_t a_stride,
    const void* restrict w,
    ${XINT8_T}* restrict c,
    size_t cm_stride,
    size_t cn_stride,
    const union ${PARAMS_UNION} params[restrict XNN_MIN_ELEMENTS(1)]) XNN_OOB_READS
{
  assert(mr != 0);
  assert(mr <= ${MR});
  assert(nc != 0);
  assert(kc != 0);
  assert(kc % sizeof(${XINT8_T}) == 0);
  assert(a != NULL);
  assert(w != NULL);
  assert(c != NULL);

  kc = round_up_po2(kc, 8);
  const ${XINT8_T}* a0 = a;
  ${XINT8_T}* c0 = c;
  $for M in range(1, MR):
    const ${XINT8_T}* a${M} = (const ${XINT8_T}*) ((uintptr_t) a${M-1} + a_stride);
    ${XINT8_T}* c${M} = (${XINT8_T}*) ((uintptr_t) c${M-1} + cm_stride);
    $if M % 2 == 0:
      if XNN_UNPREDICTABLE(mr <= ${M}) {
        a${M} = a${M-1};
        c${M} = c${M-1};
      }
    $elif M + 1 == MR:
      if XNN_UNPREDICTABLE(mr != ${M+1}) {
        a${M} = a${M-1};
        c${M} = c${M-1};
      }
    $else:
      if XNN_UNPREDICTABLE(mr < ${M+1}) {
        a${M} = a${M-1};
        c${M} = c${M-1};
      }

  $if DATATYPE == "QU8":
    const v128_t vb_zero_point = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.kernel_zero_point);
  do {
    v128_t vacc0x0 = wasm_v128_load32_zero(w);
    $for N in range(1, 4):
      v128_t vacc0x${N} = wasm_v128_load32_zero((const int32_t*) w + ${N});
    $for M in range(1, MR):
      $for N in range(4):
        v128_t vacc${M}x${N} = vacc0x${N};
    w = (const void*) ((const int32_t*) w + 4);

    size_t k = 0;
    while (k < kc) {
      $for M in range(MR):
        const v128_t vxa${M} = ${WASM_X16X8_LOAD8X8}(a${M});
        a${M} += 8;

      $if VARIANT == "LD128":
        $for N in range(0, 4, 2):
          $if N == 0:
            const v128_t vb${N}${N+1} = wasm_v128_load(w);
          $else:
            const v128_t vb${N}${N+1} = wasm_v128_load((const ${XINT8_T}*) w + ${N * 8});
          $if DATATYPE == "QU8":
            const v128_t vxb${N} = wasm_i16x8_sub(wasm_u16x8_extend_low_u8x16(vb${N}${N+1}), vb_zero_point);
            const v128_t vxb${N+1} = wasm_i16x8_sub(wasm_u16x8_extend_high_u8x16(vb${N}${N+1}), vb_zero_point);
          $else:
            const v128_t vxb${N} = wasm_i16x8_extend_low_i8x16(vb${N}${N+1});
            const v128_t vxb${N+1} = wasm_i16x8_extend_high_i8x16(vb${N}${N+1});

          $for M in range(MR):
            vacc${M}x${N} = wasm_i32x4_add(vacc${M}x${N}, wasm_i32x4_dot_i16x8(vxa${M}, vxb${N}));
            vacc${M}x${N+1} = wasm_i32x4_add(vacc${M}x${N+1}, wasm_i32x4_dot_i16x8(vxa${M}, vxb${N+1}));
      $else:
        $for N in range(4):
          $if VARIANT == "LD64":
            $if DATATYPE == "QU8":
              $if N == 0:
                const v128_t vxb${N} = wasm_i16x8_sub(wasm_u16x8_load8x8(w), vb_zero_point);
              $else:
                const v128_t vxb${N} = wasm_i16x8_sub(wasm_u16x8_load8x8((const int8_t*) w + ${N * 8}), vb_zero_point);
            $else:
              $if N == 0:
                const v128_t vxb${N} = wasm_i16x8_load8x8(w);
              $else:
                const v128_t vxb${N} = wasm_i16x8_load8x8((const int8_t*) w + ${N * 8});
          $elif VARIANT == "EXTENDED":
            $if N == 0:
              const v128_t vxb${N} = wasm_v128_load(w);
            $else:
              const v128_t vxb${N} = wasm_v128_load((const int16_t*) w + ${N * 8});

          $for M in range(MR):
            vacc${M}x${N} = wasm_i32x4_add(vacc${M}x${N}, wasm_i32x4_dot_i16x8(vxa${M}, vxb${N}));

      $if VARIANT == "EXTENDED":
        w = (const void*) ((const int16_t*) w + 32);
      $else:
        w = (const void*) ((const ${XINT8_T}*) w + 32);
      k += 8 * sizeof(${XINT8_T});
    }

    $for M in range(MR):
      const v128_t vacc${M}x02 = wasm_i32x4_add(wasm_v32x4_shuffle(vacc${M}x0, vacc${M}x2, 0, 4, 1, 5), wasm_v32x4_shuffle(vacc${M}x0, vacc${M}x2, 2, 6, 3, 7));
      const v128_t vacc${M}x13 = wasm_i32x4_add(wasm_v32x4_shuffle(vacc${M}x1, vacc${M}x3, 0, 4, 1, 5), wasm_v32x4_shuffle(vacc${M}x1, vacc${M}x3, 2, 6, 3, 7));

    $for M in range(MR):
      v128_t vacc${M}x0123 = wasm_i32x4_add(wasm_v32x4_shuffle(vacc${M}x02, vacc${M}x13, 0, 4, 1, 5), wasm_v32x4_shuffle(vacc${M}x02, vacc${M}x13, 2, 6, 3, 7));

    $for M in range(MR):
      vacc${M}x0123 = wasm_f32x4_convert_i32x4(vacc${M}x0123);

    $if DATATYPE == "QC8":
      const v128_t vscale0123 = wasm_v128_load(w);
      w = (const void*) ((const float*) w + 4);
      $for M in range(MR):
        vacc${M}x0123 = wasm_f32x4_mul(vacc${M}x0123, vscale0123);
    $else:
      const v128_t vscale = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.scale);
      $for M in range(MR):
        vacc${M}x0123 = wasm_f32x4_mul(vacc${M}x0123, vscale);

    const v128_t vmagic_bias = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.magic_bias);
    $for M in range(MR):
      vacc${M}x0123 = wasm_f32x4_add(vacc${M}x0123, vmagic_bias);

    const v128_t vmagic_min = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.magic_min);
    $for M in range(MR):
      vacc${M}x0123 = wasm_i32x4_max(vacc${M}x0123, vmagic_min);

    const v128_t vmagic_bias_less_output_zero_point = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.magic_bias_less_output_zero_point);
    $for M in range(MR):
      vacc${M}x0123 = wasm_i32x4_sub(vacc${M}x0123, vmagic_bias_less_output_zero_point);

    $for M in range(0, MR, 2):
      v128_t vacc${M}${min(M+1, MR-1)}x0123 = wasm_i16x8_narrow_i32x4(vacc${M}x0123, vacc${min(M+1, MR-1)}x0123);

    $if MR > 2:
      v128_t vout = ${WASM_X8X16_NARROW_I16X8}(vacc0${min(1, MR-1)}x0123, vacc${min(2, MR-1)}${min(3, MR-1)}x0123);
    $else:
      v128_t vout = ${WASM_X8X16_NARROW_I16X8}(vacc0${min(1, MR-1)}x0123, vacc0${min(1, MR-1)}x0123);

    const v128_t voutput_max = wasm_v128_load64_splat(params->${PARAMS_STRUCT}.output_max);
    vout = ${WASM_X8X16_MIN}(vout, voutput_max);

    if (nc >= 4) {
      $for M in range(MR):
        *((float*) c${M}) = (float) wasm_f32x4_extract_lane(vout, ${M});

      $for M in range(MR):
        c${M} = (${XINT8_T}*) ((uintptr_t) c${M} + cn_stride);

      $for M in range(MR):
        a${M} = (const ${XINT8_T}*) ((uintptr_t) a${M} - kc);

      nc -= 4;
    } else {
      $for M in range(MR):
        uint32_t vout${M} = wasm_i32x4_extract_lane(vout, ${M});
      if (nc & 2) {
        $for M in range(MR):
          *((uint16_t*) c${M}) = (uint16_t) vout${M};
          vout${M} >>= 16;
          c${M} += 2;
      }
      if (nc & 1) {
        $for M in range(MR):
          *c${M} = (${XINT8_T}) vout${M};
      }

      nc = 0;
    }
  } while (nc != 0);
}
