// Copyright 2022 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.


#include <cassert>

#include <xnnpack.h>
#include <xnnpack/aarch32-assembler.h>
#include <xnnpack/allocator.h>
#include <xnnpack/gemm.h>

namespace xnnpack {
namespace aarch32 {
namespace {
class Generator : public Assembler {
  using Assembler::Assembler;
 public:
  void generate(size_t max_mr, size_t nc_mod_nr, size_t kc, const void* params);
};


// void xnn_qc8_gemm_minmax_fp32_ukernel_4x8c4__aarch32_neondot_ld64(
//     size_t mr,                            r0
//     size_t nc,                            r1
//     size_t kc,                            r2 -> r5
//     const uint8_t*restrict a,             r3
//     size_t a_stride,           sp + 80 -> (r7)
//     const void*restrict w,     sp + 84 -> r9
//     uint8_t*restrict c,        sp + 88 -> r11
//     size_t cm_stride,          sp + 92 -> (r6)
//     size_t cn_stride,          sp + 96 -> r7
//     xnn_qs8_minmax_params params)  sp + 100 -> (r5)

// d8-d15, r4-r11,r14(lr) need to be preserved if used. r13(sp),r15(pc) are reserved.

// Register usage

// A0   r3  d0
// A1  r12  d1
// A2  r10  d2
// A3   r0  d3

// B    r9  q2 q3 q4 q5

// C0  r11 d16-d17  q8  d18-d19  q9
// C1   r4 d20-d21 q10  d22-d23 q11
// C2   r8 d24-d25 q12  d26-d27 q13
// C3   r6 d28-d29 q14  d30-d31 q15

// unused q7

// params structure is 4 bytes
//  struct {
//    int16_t output_zero_point;  d13[2]
//    int8_t output_min;          d13[6]
//    int8_t output_max;          d13[7]
//  } xnn_qs8_minmax_params.neonv8;

void Generator::generate(size_t max_mr, size_t nc_mod_nr, size_t kc, const void* params)
{
  assert(nc_mod_nr < 8);
  assert(kc != 0);

  Label l0, l1, l2, l3, l4, l5, l6, l7;

  // Auto-generated file. Do not edit!
  // Push 80 bytes
  push({r4, r5, r6, r7, r8, r9, r10, r11}); // 32
  vpush({d8-d13}); // +48 = 80

  ldr(r7, mem[sp, 80]); // a_stride
  add(r2, r2, 3); // kc = (kc + 3) & ~3
  ldr(r11, mem[sp, 88]); // c
  ldr(r6, mem[sp, 92]); // cm_stride
  ldr(r9, mem[sp, 84]); // w
  bic(r2, r2, 3);
  ldr(r5, mem[sp, 100]); // params

  // Clamp A and C pointers
  cmp(r0, 2); // if mr >= 2
  add(r12, r3, r7); //   a1 = a0 + a_stride
  add(r4, r11, r6); //   c1 = c0 + cm_stride
  movlo(r12, r3); // a1
  movlo(r4, r11); // c1
  // if mr > 2
  add(r10, r12, r7); //   a2 = a1 + a_stride
  add(r8, r4, r6); //   c2 = c1 + cm_stride
  movls(r10, r12); // a2
  movls(r8, r4); // c2

  cmp(r0, 4); // if mr >=4
  add(r0, r10, r7); //   a3 = a2 + a_stride
  add(r6, r8, r6); //   c3 = c2 + cm_stride
  movlo(r0, r10); // a3
  movlo(r6, r8); // c3

  // Load params values
  vld1r_32({d13}, mem[r5]); // QC8 params
  ldr(r7, mem[sp, 96]); // cn_stride

  align(8);
  bind(l0);
  // Load initial bias from w into accumulators
  vldm(mem[r9]++, {d16-d19}); // Bias
  subs(r5, r2, 8); // k = kc - 8
  vmov(q10, q8);
  vmov(q11, q9);
  vmov(q12, q8);
  vmov(q13, q9);
  vmov(q14, q8);
  vmov(q15, q9);
  blo(l3); // less than 8 channels?

  // Main loop - 8 bytes of A.
  // 16 SDOT, 4 LD64 A, 4 LD128 B
  align(8);
  bind(l1);
  vld1_8({d0}, mem[r3]++); // A0
  vld1_8({q2}, mem[r9]++); // B0
  vld1_8({d1}, mem[r12]++); // A1
  vld1_8({q3}, mem[r9]++); // B1
  vld1_8({d2}, mem[r10]++); // A2
  vld1_8({q4}, mem[r9]++); // B2
  vld1_8({d3}, mem[r0]++); // A3
  vld1_8({q5}, mem[r9]++); // B3
  subs(r5, r5, 8);

  vsdot_s8(q8, q2, d0[0]);
  vsdot_s8(q9, q3, d0[0]);
  vsdot_s8(q10, q2, d1[0]);
  vsdot_s8(q11, q3, d1[0]);
  vsdot_s8(q12, q2, d2[0]);
  vsdot_s8(q13, q3, d2[0]);
  vsdot_s8(q14, q2, d3[0]);
  vsdot_s8(q15, q3, d3[0]);

  vsdot_s8(q8, q4, d0[1]);
  vsdot_s8(q9, q5, d0[1]);
  vsdot_s8(q10, q4, d1[1]);
  vsdot_s8(q11, q5, d1[1]);
  vsdot_s8(q12, q4, d2[1]);
  vsdot_s8(q13, q5, d2[1]);
  vsdot_s8(q14, q4, d3[1]);
  vsdot_s8(q15, q5, d3[1]);
  bhs(l1);

  // Is there a remainder?- 4 bytes of A
  adds(r5, r5, 8);
  bne(l3);

  bind(l2);
  // QC8 FP32 quantization
  vld1_8({q0-q1}, mem[r9]++);

  vcvt_f32_s32(q8, q8);
  vcvt_f32_s32(q9, q9);
  vcvt_f32_s32(q10, q10);
  vcvt_f32_s32(q11, q11);
  vcvt_f32_s32(q12, q12);
  vcvt_f32_s32(q13, q13);
  vcvt_f32_s32(q14, q14);
  vcvt_f32_s32(q15, q15);

  vmul_f32(q8, q8, q0); // multiplier
  vmul_f32(q9, q9, q1);
  vmul_f32(q10, q10, q0);
  vmul_f32(q11, q11, q1);
  vmul_f32(q12, q12, q0);
  vmul_f32(q13, q13, q1);
  vmul_f32(q14, q14, q0);
  vmul_f32(q15, q15, q1);

  vcvtn_s32_f32(q8, q8);
  vcvtn_s32_f32(q9, q9);
  vcvtn_s32_f32(q10, q10);
  vcvtn_s32_f32(q11, q11);
  vcvtn_s32_f32(q12, q12);
  vcvtn_s32_f32(q13, q13);
  vcvtn_s32_f32(q14, q14);
  vcvtn_s32_f32(q15, q15);

  vdup_16(q0, d13[2]); // output_zero_point

  vqmovn_s32(d16, q8);
  vqmovn_s32(d17, q9);
  vqmovn_s32(d18, q10);
  vqmovn_s32(d19, q11);
  vqmovn_s32(d20, q12);
  vqmovn_s32(d21, q13);
  vqmovn_s32(d22, q14);
  vqmovn_s32(d23, q15);

  vqadd_s16(q8, q8, q0);
  vqadd_s16(q9, q9, q0);
  vqadd_s16(q10, q10, q0);
  vqadd_s16(q11, q11, q0);

  vdup_8(q12, d13[6]); // output_min

  vqmovn_s16(d0, q8);
  vqmovn_s16(d1, q9);
  vqmovn_s16(d2, q10);
  vqmovn_s16(d3, q11);

  vdup_8(q13, d13[7]); // output_max

  vmax_s8(q0, q0, q12);
  vmax_s8(q1, q1, q12);

  subs(r1, r1, 8);

  vmin_s8(q0, q0, q13);
  vmin_s8(q1, q1, q13);

  // Store full 4 x 8
  blo(l4);
  vst1_8({d0}, mem[r11], r7);
  sub(r3, r3, r2);
  vst1_8({d1}, mem[r4], r7);
  sub(r12, r12, r2);
  vst1_8({d2}, mem[r8], r7);
  sub(r10, r10, r2);
  vst1_8({d3}, mem[r6], r7);
  sub(r0, r0, r2);
  bhi(l0);

  vpop({d8-d13});
  pop({r4, r5, r6, r7, r8, r9, r10, r11});
  bx(lr);

  // Remainder- 4 bytes of A
  align(8);
  bind(l3);
  vld1_32({d0[0]}, mem[r3]++); // A0
  vld1_32({q2}, mem[r9]++); // B0
  vld1_32({d1[0]}, mem[r12]++); // A1
  vld1_32({q3}, mem[r9]++); // B1
  vld1_32({d2[0]}, mem[r10]++); // A2
  vld1_32({d3[0]}, mem[r0]++); // A3

  vsdot_s8(q8, q2, d0[0]);
  vsdot_s8(q9, q3, d0[0]);
  vsdot_s8(q10, q2, d1[0]);
  vsdot_s8(q11, q3, d1[0]);
  vsdot_s8(q12, q2, d2[0]);
  vsdot_s8(q13, q3, d2[0]);
  vsdot_s8(q14, q2, d3[0]);
  vsdot_s8(q15, q3, d3[0]);
  b(l2);

  // Store odd width
  align(8);
  bind(l4);
  tst(r1, 4);
  beq(l5);
  vst1_32({d0[0]}, mem[r11]++);
  vst1_32({d1[0]}, mem[r4]++);
  vst1_32({d2[0]}, mem[r8]++);
  vst1_32({d3[0]}, mem[r6]++);
  vext_8(q0, q0, q0, 4);
  vext_8(q1, q1, q1, 4);
  bind(l5);
  tst(r1, 2);
  beq(l6);
  vst1_16({d0[0]}, mem[r11]++);
  vst1_16({d1[0]}, mem[r4]++);
  vst1_16({d2[0]}, mem[r8]++);
  vst1_16({d3[0]}, mem[r6]++);
  vext_8(q0, q0, q0, 2);
  vext_8(q1, q1, q1, 2);

  bind(l6);
  tst(r1, 1);
  beq(l7);
  vst1_8({d0[0]}, mem[r11]);
  vst1_8({d1[0]}, mem[r4]);
  vst1_8({d2[0]}, mem[r8]);
  vst1_8({d3[0]}, mem[r6]);

  bind(l7);
  vpop({d8-d13});
  pop({r4, r5, r6, r7, r8, r9, r10, r11});
  bx(lr);
}
}  // namespace
}  // aarch32
}  // xnnpack

xnn_status_t xnn_generate_qc8_gemm_fp32_ukernel_4x8c4__aarch32_neondot_ld64(xnn_code_buffer* code, size_t max_mr, size_t nc_mod_nr, size_t kc, const void* params) {
  using namespace xnnpack::aarch32;
  Generator g(code);
  g.generate(max_mr, nc_mod_nr, kc, nullptr);
  g.finalize();
  if (g.error() != xnnpack::Error::kNoError) {
    return xnn_status_invalid_state;
  }
  return xnn_status_success;
}
