// File: /workspace/github_c_makefile_star2_O3/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, -0x70(%rsp)
movq %rdx, -0x60(%rsp)
movslq %ecx, %r10
testq %r10, %r10
jle 0x1c9d8
movl 0x58(%rsp), %ebx
movq 0x48(%rsp), %r11
movq 0x38(%rsp), %r15
movslq 0x50(%rsp), %r14
subq 0x40(%rsp), %r11
leaq (%r15,%r11,4), %r12
leaq -0x1(%r8), %rax
xorl %edx, %edx
divq %r14
incq %rax
movslq %r8d, %rdx
movq %rsi, %r8
subq %rax, %r8
leaq (,%rsi,4), %r13
movq %r13, %r9
subq %rax, %r9
imulq %rsi, %rax
movl $0x1, %ebp
subq %rax, %rbp
movl $0x4, %ecx
subq %rax, %rcx
movl $0x1, %eax
movq %r13, -0x8(%rsp)
subq %r13, %rax
movq %rax, -0x18(%rsp)
testb $0x4, %bl
movl $0x0, %ebx
cmovneq %r8, %rbp
movq %rbp, -0x38(%rsp)
cmovneq %r9, %rcx
movq %rcx, -0x40(%rsp)
movq 0x48(%rsp), %r9
movq %r9, %rax
movq -0x70(%rsp), %r8
imulq %r8, %rax
shlq $0x2, %rax
movq -0x60(%rsp), %rcx
subq %rax, %rcx
movq %rcx, -0x68(%rsp)
movq %r9, %rax
notq %rax
leaq (%r12,%rax,4), %rax
movq %rax, -0x10(%rsp)
leaq (,%r11,4), %rax
movq %rax, -0x58(%rsp)
notq %r11
leaq (%r12,%r11,4), %rcx
movq %r8, %rax
movq %r14, -0x48(%rsp)
imulq %r14, %rax
shlq $0x2, %rax
movq %rax, -0x50(%rsp)
leaq (,%r8,4), %rax
movq %r10, -0x20(%rsp)
leaq 0x4(%rbx), %r14
movq -0x60(%rsp), %r8
leaq (%r8,%rbx,4), %r11
cmpq %r10, %r14
jge 0x1c83e
movl %r11d, %r10d
orl -0x70(%rsp), %r10d
andl $0xf, %r10d
jne 0x1c83e
movq %r14, -0x30(%rsp)
testq %rdx, %rdx
movl 0x58(%rsp), %r8d
jle 0x1c9b6
movq %r11, -0x78(%rsp)
movq -0x68(%rsp), %r10
leaq (%r10,%rbx,4), %rbp
xorl %r10d, %r10d
movq %r9, %rbx
subq %r10, %rbx
testq %rbx, %rbx
jle 0x1c752
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
testb $0x3, %r8b
je 0x1c726
movq -0x78(%rsp), %r11
movaps (%r11), %xmm1
shlq $0x2, %rbx
movq %r12, %r13
subq %rbx, %r13
movq %rbp, %r14
movq %r12, %rbx
movss (%rbx), %xmm2
addq $-0x4, %rbx
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rax, %r14
cmpq %r13, %rbx
ja 0x1c736
jmp 0x1c76d
imulq -0x70(%rsp), %rbx
shlq $0x2, %rbx
movq -0x78(%rsp), %r14
subq %rbx, %r14
xorps %xmm0, %xmm0
movq %r12, %rbx
xorps %xmm1, %xmm1
movq %r10, %r13
subq %rdx, %r13
incq %r13
movq 0x40(%rsp), %r11
cmpq %r11, %r13
cmovleq %r11, %r13
movq -0x10(%rsp), %r11
leaq (%r11,%r13,4), %r13
cmpq %r13, %rbx
jbe 0x1c7ab
movaps (%r14), %xmm1
movss (%rbx), %xmm2
addq $-0x4, %rbx
shufps $0x0, %xmm2, %xmm2      # xmm2 = xmm2[0,0,0,0]
mulps %xmm1, %xmm2
addps %xmm2, %xmm0
addq %rax, %r14
jmp 0x1c78b
xorps %xmm2, %xmm2
testb $0x3, %r8b
je 0x1c7cb
movaps %xmm1, %xmm2
jmp 0x1c7cb
movss (%rbx), %xmm1
addq $-0x4, %rbx
shufps $0x0, %xmm1, %xmm1      # xmm1 = xmm1[0,0,0,0]
mulps %xmm2, %xmm1
addps %xmm1, %xmm0
cmpq %rcx, %rbx
ja 0x1c7b9
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,%rsi,4), %rbx
testb $0x4, %r8b
jne 0x1c801
movss %xmm1, 0x4(%rdi)
movss %xmm2, 0x8(%rdi)
movss %xmm0, 0xc(%rdi)
jmp 0x1c823
movss %xmm1, (%rdi,%rsi,4)
leaq (%rbx,%rsi,4), %rdi
movss %xmm2, (%rdi)
leaq (%rdi,%rsi,4), %rdi
movss %xmm0, (%rdi)
leaq (%rdi,%rsi,4), %rdi
movq -0x18(%rsp), %r11
leaq (%rdi,%r11,4), %rbx
addq -0x48(%rsp), %r10
addq -0x50(%rsp), %rbp
movq %rbx, %rdi
cmpq %rdx, %r10
jl 0x1c706
jmp 0x1c9b9
testq %rdx, %rdx
movl 0x58(%rsp), %r8d
movq %rbx, -0x28(%rsp)
jle 0x1c99d
movq %r11, -0x78(%rsp)
movq -0x68(%rsp), %r10
leaq (%r10,%rbx,4), %r14
xorl %ebp, %ebp
movq %r9, %rbx
subq %rbp, %rbx
testq %rbx, %rbx
jle 0x1c8b8
xorps %xmm0, %xmm0
xorps %xmm1, %xmm1
testb $0x3, %r8b
je 0x1c882
movq -0x78(%rsp), %r8
movss (%r8), %xmm1
shlq $0x2, %rbx
movq %r12, %r13
subq %rbx, %r13
movq %r14, %r10
movq -0x58(%rsp), %rbx
leaq (%r15,%rbx), %r8
addq $-0x4, %r8
addq $-0x4, %rbx
movss 0x4(%r8), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rax, %r10
cmpq %r13, %r8
ja 0x1c894
jmp 0x1c8d5
imulq -0x70(%rsp), %rbx
shlq $0x2, %rbx
movq -0x78(%rsp), %r10
subq %rbx, %r10
xorps %xmm0, %xmm0
movq -0x58(%rsp), %rbx
xorps %xmm1, %xmm1
movq %rbp, %r8
subq %rdx, %r8
incq %r8
movq 0x40(%rsp), %r11
cmpq %r11, %r8
cmovleq %r11, %r8
movq %r9, %r11
subl %r8d, %r9d
shlq $0x20, %r9
movabsq $0x100000000, %r8       # imm = 0x100000000
addq %r8, %r9
sarq $0x1e, %r9
movq %r12, %r13
subq %r9, %r13
leaq (%r15,%rbx), %r8
cmpq %r13, %r8
jbe 0x1c938
movss (%r10), %xmm1
leaq (%r15,%rbx), %r8
addq $-0x4, %r8
addq $-0x4, %rbx
movss 0x4(%r8), %xmm2
mulss %xmm1, %xmm2
addss %xmm2, %xmm0
addq %rax, %r10
jmp 0x1c90f
xorps %xmm2, %xmm2
movl 0x58(%rsp), %r8d
testb $0x3, %r8b
movq %r11, %r9
je 0x1c94c
movaps %xmm1, %xmm2
cmpq $-0x3, %rbx
jl 0x1c96e
addq $0x4, %rbx
movss -0x4(%r15,%rbx), %xmm1
mulss %xmm2, %xmm1
addss %xmm1, %xmm0
addq $-0x4, %rbx
testq %rbx, %rbx
jg 0x1c956
testb $0x4, %r8b
movl $0x4, %r10d
cmoveq -0x8(%rsp), %r10
addq %rdi, %r10
movss %xmm0, (%rdi)
addq -0x48(%rsp), %rbp
addq -0x50(%rsp), %r14
movq %r10, %rdi
cmpq %rdx, %rbp
jl 0x1c861
jmp 0x1c9a0
movq %rdi, %r10
movq -0x38(%rsp), %rdi
leaq (%r10,%rdi,4), %rdi
movq -0x28(%rsp), %rbx
incq %rbx
movq %rbx, %r8
jmp 0x1c9ca
movq %rdi, %rbx
movq -0x40(%rsp), %rdi
leaq (%rbx,%rdi,4), %rdi
movq -0x30(%rsp), %r8
movq %r8, %rbx
movq -0x20(%rsp), %r10
cmpq %r10, %r8
jl 0x1c6ba
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq