// File: /workspace/github_c_makefile_star2_O2/zpole[P]IICV/vl/imopv_sse2.c
// Function: vl_imconvcol_vf_sse2
void
VL_XCAT3(_vl_imconvcol_v, SFX, _sse2)
(T* dst, vl_size dst_stride,
 T const* src,
 vl_size src_width, vl_size src_height, vl_size src_stride,
 T const* filt, vl_index filt_begin, vl_index filt_end,
 int step, unsigned int flags)
{
  vl_index x = 0 ;
  vl_index y ;
  vl_index dheight = (src_height - 1) / step + 1 ;
  vl_bool use_simd  = VALIGNED(src_stride) ;
  vl_bool transp    = flags & VL_TRANSPOSE ;
  vl_bool zeropad   = (flags & VL_PAD_MASK) == VL_PAD_BY_ZERO ;
  double totcol = 0 ;
  double simdcol = 0 ;

  /* let filt point to the last sample of the filter */
  filt += filt_end - filt_begin ;

  while (x < (signed)src_width) {
    /* Calculate dest[x,y] = sum_p image[x,p] filt[y - p]
     * where supp(filt) = [filt_begin, filt_end] = [fb,fe].
     *
     * CHUNK_A: y - fe <= p < 0
     *          completes VL_MAX(fe - y, 0) samples
     * CHUNK_B: VL_MAX(y - fe, 0) <= p < VL_MIN(y - fb, height - 1)
     *          completes fe - VL_MAX(fb, height - y) + 1 samples
     * CHUNK_C: completes all samples
     */

    T const *filti ;
    vl_index stop ;

    if ((x + VSIZE < (signed)src_width) &
        VALIGNED(src + x) & use_simd)
    {
      /* ----------------------------------------------  Vectorized */
      for (y = 0 ; y < (signed)src_height ; y += step)  {
        union {VTYPE v ; T x [VSIZE] ; } acc ;
        VTYPE v, c ;
        T const *srci ;
        acc.v = VSTZ () ;
        v = VSTZ() ;

        filti = filt ;
        stop = filt_end - y ;
        srci = src + x - stop * src_stride ;

        if (stop > 0) {
          if (zeropad) {
            v = VSTZ () ;
          } else {
            v = * (VTYPE*) (src + x) ;
          }
          while (filti > filt - stop) {
            c = VLD1 (filti--) ;
            acc.v = VADD (acc.v,  VMUL (v, c)) ;
            srci += src_stride ;
          }
        }

        stop = filt_end - VL_MAX(filt_begin, y - (signed)src_height + 1) + 1 ;
        while (filti > filt - stop) {
          v = * (VTYPE*) srci ;
          c = VLD1 (filti--) ;
          acc.v = VADD (acc.v, VMUL (v, c)) ;
          srci += src_stride ;
        }

        if (zeropad) v = VSTZ () ;

        stop = filt_end - filt_begin + 1;
        while (filti > filt - stop) {
          c = VLD1 (filti--) ;
          acc.v = VADD (acc.v, VMUL (v, c)) ;
        }

        if (transp) {
          *dst = acc.x[0] ; dst += dst_stride ;
          *dst = acc.x[1] ; dst += dst_stride ;
#if(VSIZE == 4)
          *dst = acc.x[2] ; dst += dst_stride ;
          *dst = acc.x[3] ; dst += dst_stride ;
#endif
          dst += 1 * 1 - VSIZE * dst_stride ;
        } else {
          *dst = acc.x[0] ; dst += 1 ;
          *dst = acc.x[1] ; dst += 1 ;
#if(VSIZE == 4)
          *dst = acc.x[2] ; dst += 1 ;
          *dst = acc.x[3] ; dst += 1 ;
#endif
          dst += 1 * dst_stride - VSIZE * 1 ;
        }
      } /* next y */
      if (transp) {
        dst += VSIZE * dst_stride - dheight * 1 ;
      } else {
        dst += VSIZE * 1 - dheight * dst_stride ;
      }
      x       += VSIZE ;
      simdcol += VSIZE ;
      totcol  += VSIZE ;
    } else {
      /* -------------------------------------------------  Vanilla */
      for (y = 0 ; y < (signed)src_height ; y += step) {
        T acc = 0 ;
        T v = 0, c ;
        T const* srci ;

        filti = filt ;
        stop = filt_end - y ;
        srci = src + x - stop * src_stride ;

        if (stop > 0) {
          if (zeropad) {
            v = 0 ;
          } else {
            v = *(src + x) ;
          }
          while (filti > filt - stop) {
            c = *filti-- ;
            acc += v * c ;
            srci += src_stride ;
          }
        }

        stop = filt_end - VL_MAX(filt_begin, y - (signed)src_height + 1) + 1 ;
        while (filti > filt - (signed)stop) {
          v = *srci ;
          c = *filti-- ;
          acc += v * c ;
          srci += src_stride ;
        }

        if (zeropad) v = 0 ;

        stop = filt_end - filt_begin + 1 ;
        while (filti > filt - stop) {
          c = *filti-- ;
          acc += v * c ;
        }

        if (transp) {
          *dst = acc ; dst += 1 ;
        } else {
          *dst = acc ; dst += dst_stride ;
        }
      } /* next y */
      if (transp) {
        dst += 1 * dst_stride - dheight * 1 ;
      } else {
        dst += 1 * 1 - dheight * dst_stride ;
      }
      x      += 1 ;
      totcol += 1 ;
    } /* next x */
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %r9, %r10
movq %rcx, -0x80(%rsp)
movq %rdx, %r12
movslq 0x58(%rsp), %r13
leaq -0x1(%r8), %rax
xorl %edx, %edx
divq %r13
incq %rax
movq %rsi, %rcx
subq %rax, %rcx
leaq (,%rsi,4), %r9
movq %r9, %rdx
subq %rax, %rdx
imulq %rsi, %rax
movabsq $0x1, %r11
movq %r11, %rbx
subq %rax, %rbx
movabsq $0x4, %r14
subq %rax, %r14
movq 0x50(%rsp), %r15
movq 0x48(%rsp), %rbp
movq %r15, %rax
subq %rbp, %rax
movq %r9, (%rsp)
subq %r9, %r11
movq %r15, %r9
movq %r11, -0x18(%rsp)
movl 0x60(%rsp), %r11d
testb $0x4, %r11b
cmovneq %rcx, %rbx
movq %rbx, -0x30(%rsp)
cmovneq %rdx, %r14
movq %r14, -0x38(%rsp)
movq %r15, %rcx
imulq %r10, %rcx
shlq $0x2, %rcx
movq %r12, -0x20(%rsp)
movq %rsi, %rbx
movl %r11d, %esi
subq %rcx, %r12
movq %r12, -0x58(%rsp)
movslq -0x80(%rsp), %rdx
movslq %r8d, %rcx
movq %rcx, -0x40(%rsp)
movq %r15, %rcx
notq %rcx
movq 0x40(%rsp), %r15
leaq (%r15,%rax,4), %r11
leaq (%r11,%rcx,4), %rcx
movq %rcx, -0x8(%rsp)
leaq (,%rax,4), %rcx
movq %rcx, -0x50(%rsp)
notq %rax
movq %r11, -0x80(%rsp)
leaq (%r11,%rax,4), %r14
movq %rbx, %r11
movq %r10, %rax
imulq %r13, %rax
shlq $0x2, %rax
movq %rax, -0x48(%rsp)
movq %r10, -0x70(%rsp)
leaq (,%r10,4), %rax
xorl %r10d, %r10d
movq %rdx, -0x60(%rsp)
movq %rbx, -0x10(%rsp)
cmpq %rdx, %r10
jge 0x19b4d
leaq 0x4(%r10), %rbx
movq -0x20(%rsp), %rcx
leaq (%rcx,%r10,4), %r8
movq %rbx, -0x68(%rsp)
cmpq %rdx, %rbx
movq %r8, -0x78(%rsp)
jge 0x199c9
movq -0x70(%rsp), %rcx
orl %r8d, %ecx
andl $0xf, %ecx
jne 0x199c9
movq -0x58(%rsp), %rcx
leaq (%rcx,%r10,4), %rbx
xorl %ecx, %ecx
movq %rcx, %rdx
subq -0x40(%rsp), %rdx
jge 0x19b35
movq %r9, %r8
movq %r9, %r12
subq %rcx, %r12
testq %r12, %r12
jle 0x198e4
movq %rbp, %r10
movq %rbx, %rbp
movq %r13, %r9
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
testb $0x3, %sil
je 0x198a6
movq -0x78(%rsp), %r11
movaps (%r11), %xmm1
shlq $0x2, %r12
movq -0x80(%rsp), %r13
movq %r13, %rbx
subq %r12, %rbx
movq %rbp, %r11
movq %r13, %r12
cmpq %rbx, %r12
jbe 0x198d9
movss (%r12), %xmm2
addq $-0x4, %r12
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rax, %r11
jmp 0x198bb
movq %r9, %r13
movq %rbp, %rbx
movq %r10, %rbp
jmp 0x19901
imulq -0x70(%rsp), %r12
shlq $0x2, %r12
movq -0x78(%rsp), %r11
subq %r12, %r11
xorps %xmm0, %xmm0
movq -0x80(%rsp), %r12
xorps %xmm1, %xmm1
incq %rdx
cmpq %rbp, %rdx
cmovleq %rbp, %rdx
movq -0x8(%rsp), %r9
leaq (%r9,%rdx,4), %rdx
cmpq %rdx, %r12
jbe 0x19936
movaps (%r11), %xmm1
movss (%r12), %xmm2
addq $-0x4, %r12
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rax, %r11
jmp 0x19914
xorps %xmm2, %xmm2
testb $0x3, %sil
je 0x19942
movaps %xmm1, %xmm2
movq %r8, %r9
movq -0x10(%rsp), %r11
cmpq %r14, %r12
jbe 0x19965
movss (%r12), %xmm1
addq $-0x4, %r12
shufps $0x0, %xmm1, %xmm1      # xmm1 = xmm1[0,0,0,0]
mulps %xmm2, %xmm1
addps %xmm1, %xmm0
jmp 0x1994a
movss %xmm0, (%rdi)
movaps %xmm0, %xmm1
shufps $0x55, %xmm0, %xmm1     # xmm1 = xmm1[1,1],xmm0[1,1]
movaps %xmm0, %xmm2
unpckhpd %xmm0, %xmm2            # xmm2 = xmm2[1],xmm0[1]
shufps $0xff, %xmm0, %xmm0     # xmm0 = xmm0[3,3,3,3]
leaq (%rdi,%r11,4), %rdx
testb $0x4, %sil
jne 0x19996
movss %xmm1, 0x4(%rdi)
movss %xmm2, 0x8(%rdi)
movss %xmm0, 0xc(%rdi)
jmp 0x199b9
movss %xmm1, (%rdi,%r11,4)
leaq (%rdx,%r11,4), %rdx
movss %xmm2, (%rdx)
leaq (%rdx,%r11,4), %rdx
movss %xmm0, (%rdx)
leaq (%rdx,%r11,4), %rdx
movq -0x18(%rsp), %rdi
leaq (%rdx,%rdi,4), %rdx
addq %r13, %rcx
addq -0x48(%rsp), %rbx
movq %rdx, %rdi
jmp 0x1986c
movq -0x58(%rsp), %rcx
movq %r10, -0x28(%rsp)
leaq (%rcx,%r10,4), %r12
xorl %edx, %edx
movq %rdx, %r10
subq -0x40(%rsp), %r10
jge 0x19b1a
movq %r9, %rbx
subq %rdx, %rbx
testq %rbx, %rbx
movq %r12, -0x68(%rsp)
jle 0x19a53
movl %esi, %ecx
movq %rbp, %r8
movq %r9, %rbp
movq %r13, %r9
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
testb $0x3, %cl
je 0x19a16
movq -0x78(%rsp), %rcx
movss (%rcx), %xmm1
shlq $0x2, %rbx
movq -0x80(%rsp), %r13
subq %rbx, %r13
movq %r12, %rcx
movq -0x50(%rsp), %r12
leaq (%r15,%r12), %rbx
cmpq %r13, %rbx
jbe 0x19a48
addq $-0x4, %r12
movss (%rbx), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rax, %rcx
jmp 0x19a2a
movq %r9, %r13
movq %rbp, %r9
movq %r8, %rbp
jmp 0x19a70
imulq -0x70(%rsp), %rbx
shlq $0x2, %rbx
movq -0x78(%rsp), %rcx
subq %rbx, %rcx
xorps %xmm0, %xmm0
movq -0x50(%rsp), %r12
xorps %xmm1, %xmm1
incq %r10
cmpq %rbp, %r10
cmovleq %rbp, %r10
movq %r9, %r8
movl %r9d, %ebx
subl %r10d, %ebx
shlq $0x20, %rbx
movabsq $0x100000000, %r9       # imm = 0x100000000
addq %r9, %rbx
sarq $0x1e, %rbx
movq -0x80(%rsp), %r10
subq %rbx, %r10
leaq (%r15,%r12), %rbx
cmpq %r10, %rbx
jbe 0x19ac2
movss (%rcx), %xmm1
addq $-0x4, %r12
movss (%rbx), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rax, %rcx
jmp 0x19aa0
xorps %xmm2, %xmm2
testb $0x3, %sil
je 0x19ace
movaps %xmm1, %xmm2
movq %r8, %r9
cmpq $-0x3, %r12
jl 0x19aeb
movss (%r15,%r12), %xmm1
mulss %xmm2, %xmm1
addq $-0x4, %r12
addss %xmm1, %xmm0
jmp 0x19ad1
testb $0x4, %sil
movabsq $0x4, %rcx
cmoveq (%rsp), %rcx
addq %rdi, %rcx
movss %xmm0, (%rdi)
addq %r13, %rdx
movq -0x68(%rsp), %r12
addq -0x48(%rsp), %r12
movq %rcx, %rdi
jmp 0x199d9
movq -0x30(%rsp), %rcx
leaq (%rdi,%rcx,4), %rdi
movq -0x28(%rsp), %r10
incq %r10
movq -0x60(%rsp), %rdx
jmp 0x19827
movq -0x38(%rsp), %rcx
leaq (%rdi,%rcx,4), %rdi
movq -0x68(%rsp), %r10
movq -0x60(%rsp), %rdx
jmp 0x19827
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq