// File: /workspace/github_c_makefile_star2_O1/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
movq %r9, -0x80(%rsp)
movq %rdx, -0x60(%rsp)
movq %rsi, -0x70(%rsp)
movslq %ecx, %r11
testq %r11, %r11
jle 0x1cb6e
movl 0x58(%rsp), %esi
movq 0x48(%rsp), %rbx
movq 0x38(%rsp), %r15
movslq 0x50(%rsp), %r14
movq %rbx, %rcx
subq 0x40(%rsp), %rcx
leaq (%r15,%rcx,4), %r12
leaq -0x1(%r8), %rax
xorl %edx, %edx
divq %r14
incq %rax
movq -0x70(%rsp), %r10
movq %r10, %rdx
subq %rax, %rdx
leaq (,%r10,4), %r13
movq %r13, %r9
subq %rax, %r9
imulq %r10, %rax
movl $0x1, %r10d
subq %rax, %r10
movl $0x4, %ebp
subq %rax, %rbp
movl $0x1, %eax
movq %r13, -0x8(%rsp)
subq %r13, %rax
movq %rax, -0x20(%rsp)
testb $0x4, %sil
cmovneq %rdx, %r10
movq %r10, -0x40(%rsp)
movl $0x0, %r10d
movslq %r8d, %r8
cmovneq %r9, %rbp
movq %rbp, -0x48(%rsp)
movq %rbx, %rax
movq -0x80(%rsp), %rdx
imulq %rdx, %rax
shlq $0x2, %rax
movq -0x60(%rsp), %r9
subq %rax, %r9
movq %r9, -0x68(%rsp)
movq %rbx, %rax
notq %rax
leaq (%r12,%rax,4), %rax
movq %rax, -0x10(%rsp)
leaq (,%rcx,4), %rax
notq %rcx
leaq (%r12,%rcx,4), %rcx
movq %rdx, %r9
movq %r14, -0x50(%rsp)
imulq %r14, %r9
shlq $0x2, %r9
movq %r9, -0x58(%rsp)
movq %rax, -0x78(%rsp)
addq %r15, %rax
movq %rax, -0x18(%rsp)
leaq (,%rdx,4), %rdx
movq %r11, -0x28(%rsp)
leaq 0x4(%r10), %r9
movq -0x60(%rsp), %rax
leaq (%rax,%r10,4), %r14
cmpq %r11, %r9
jge 0x1c9f8
movl %r14d, %eax
orl -0x80(%rsp), %eax
andl $0xf, %eax
jne 0x1c9f8
movq %r9, -0x38(%rsp)
testq %r8, %r8
movq 0x48(%rsp), %r11
jle 0x1c9e2
movq -0x68(%rsp), %rax
leaq (%rax,%r10,4), %r10
xorl %ebp, %ebp
movq %r11, %rax
subq %rbp, %rax
testq %rax, %rax
jle 0x1c8f4
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
testb $0x3, %sil
je 0x1c8c8
movaps (%r14), %xmm1
shlq $0x2, %rax
movq %r12, %r13
subq %rax, %r13
movq %r10, %rbx
movq %r12, %rax
movss (%rax), %xmm2
addq $-0x4, %rax
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rdx, %rbx
cmpq %r13, %rax
ja 0x1c8d8
jmp 0x1c90d
imulq -0x80(%rsp), %rax
shlq $0x2, %rax
movq %r14, %rbx
subq %rax, %rbx
xorps %xmm0, %xmm0
movq %r12, %rax
xorps %xmm1, %xmm1
movq %rbp, %r13
subq %r8, %r13
incq %r13
movq 0x40(%rsp), %r9
cmpq %r9, %r13
cmovleq %r9, %r13
movq -0x10(%rsp), %r9
leaq (%r9,%r13,4), %r13
cmpq %r13, %rax
jbe 0x1c94a
movaps (%rbx), %xmm1
movss (%rax), %xmm2
addq $-0x4, %rax
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rdx, %rbx
jmp 0x1c92b
xorps %xmm2, %xmm2
testb $0x3, %sil
je 0x1c96a
movaps %xmm1, %xmm2
jmp 0x1c96a
movss (%rax), %xmm1
addq $-0x4, %rax
shufps $0x0, %xmm1, %xmm1      # xmm1 = xmm1[0,0,0,0]
mulps %xmm2, %xmm1
addps %xmm1, %xmm0
cmpq %rcx, %rax
ja 0x1c958
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]
testb $0x4, %sil
jne 0x1c9a5
movss %xmm1, 0x4(%rdi)
movss %xmm2, 0x8(%rdi)
movss %xmm0, 0xc(%rdi)
movq -0x70(%rsp), %rax
leaq (%rdi,%rax,4), %rdi
jmp 0x1c9cf
movq -0x70(%rsp), %r9
leaq (%rdi,%r9,4), %rax
movss %xmm1, (%rax)
leaq (%rax,%r9,4), %rax
movss %xmm2, (%rax)
leaq (%rax,%r9,4), %rax
movss %xmm0, (%rax)
leaq (%rax,%r9,4), %rax
movq -0x20(%rsp), %rdi
leaq (%rax,%rdi,4), %rdi
addq -0x50(%rsp), %rbp
addq -0x58(%rsp), %r10
cmpq %r8, %rbp
jl 0x1c8ad
movq -0x48(%rsp), %rax
leaq (%rdi,%rax,4), %rdi
movq -0x38(%rsp), %rax
movq %rax, %r10
jmp 0x1cb60
testq %r8, %r8
movq 0x48(%rsp), %r11
movq %r10, -0x30(%rsp)
jle 0x1cb4c
movq -0x68(%rsp), %rax
leaq (%rax,%r10,4), %r10
xorl %ebp, %ebp
movq %r11, %rbx
subq %rbp, %rbx
movq %rbx, %r13
imulq -0x80(%rsp), %r13
shlq $0x2, %r13
movq %r14, %rax
subq %r13, %rax
xorps %xmm0, %xmm0
testq %rbx, %rbx
jle 0x1ca82
xorps %xmm1, %xmm1
testb $0x3, %sil
je 0x1ca45
movss (%r14), %xmm1
shlq $0x2, %rbx
movq %r12, %r13
subq %rbx, %r13
cmpq %r13, -0x18(%rsp)
jbe 0x1ca8c
movq %r10, %rax
movq -0x78(%rsp), %rbx
leaq (%r15,%rbx), %r9
addq $-0x4, %r9
addq $-0x4, %rbx
movss 0x4(%r9), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rdx, %rax
cmpq %r13, %r9
ja 0x1ca5e
jmp 0x1ca91
movq -0x78(%rsp), %rbx
xorps %xmm1, %xmm1
jmp 0x1ca91
movq -0x78(%rsp), %rbx
movq %rbp, %r9
subq %r8, %r9
incq %r9
movq 0x40(%rsp), %r13
cmpq %r13, %r9
cmovleq %r13, %r9
subl %r9d, %r11d
shlq $0x20, %r11
movabsq $0x100000000, %r9       # imm = 0x100000000
addq %r9, %r11
sarq $0x1e, %r11
movq %r12, %r13
subq %r11, %r13
leaq (%r15,%rbx), %r9
cmpq %r13, %r9
jbe 0x1caf0
movss (%rax), %xmm1
leaq (%r15,%rbx), %r9
addq $-0x4, %r9
addq $-0x4, %rbx
movss 0x4(%r9), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rdx, %rax
jmp 0x1cac8
xorps %xmm2, %xmm2
testb $0x3, %sil
movq 0x48(%rsp), %r11
je 0x1cb01
movaps %xmm1, %xmm2
cmpq $-0x3, %rbx
jl 0x1cb23
addq $0x4, %rbx
movss -0x4(%r15,%rbx), %xmm1
mulss %xmm2, %xmm1
addss %xmm1, %xmm0
addq $-0x4, %rbx
testq %rbx, %rbx
jg 0x1cb0b
testb $0x4, %sil
movss %xmm0, (%rdi)
movl $0x4, %eax
cmoveq -0x8(%rsp), %rax
addq %rax, %rdi
addq -0x50(%rsp), %rbp
addq -0x58(%rsp), %r10
cmpq %r8, %rbp
jl 0x1ca16
movq -0x40(%rsp), %rax
leaq (%rdi,%rax,4), %rdi
movq -0x30(%rsp), %r10
incq %r10
movq %r10, %rax
movq -0x28(%rsp), %r11
cmpq %r11, %rax
jl 0x1c869
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq