// File: /workspace/github_c_makefile_star2_O0/pavel-demin[P]ft8d-c/pffft.c
// Function: pffft_zconvolve_accumulate
void pffft_zconvolve_accumulate(PFFFT_Setup *s, const float *a, const float *b, float *ab, float scaling) {
  int Ncvec = s->Ncvec;
  const v4sf * RESTRICT va = (const v4sf*)a;
  const v4sf * RESTRICT vb = (const v4sf*)b;
  v4sf * RESTRICT vab = (v4sf*)ab;

#ifdef __arm__
  __builtin_prefetch(va);
  __builtin_prefetch(vb);
  __builtin_prefetch(vab);
  __builtin_prefetch(va+2);
  __builtin_prefetch(vb+2);
  __builtin_prefetch(vab+2);
  __builtin_prefetch(va+4);
  __builtin_prefetch(vb+4);
  __builtin_prefetch(vab+4);
  __builtin_prefetch(va+6);
  __builtin_prefetch(vb+6);
  __builtin_prefetch(vab+6);
# ifndef __clang__
#   define ZCONVOLVE_USING_INLINE_NEON_ASM
# endif
#endif

  float ar, ai, br, bi, abr, abi;
#ifndef ZCONVOLVE_USING_INLINE_ASM
  v4sf vscal = LD_PS1(scaling);
  int i;
#endif

  assert(VALIGNED(a) && VALIGNED(b) && VALIGNED(ab));
  ar = ((v4sf_union*)va)[0].f[0];
  ai = ((v4sf_union*)va)[1].f[0];
  br = ((v4sf_union*)vb)[0].f[0];
  bi = ((v4sf_union*)vb)[1].f[0];
  abr = ((v4sf_union*)vab)[0].f[0];
  abi = ((v4sf_union*)vab)[1].f[0];

#ifdef ZCONVOLVE_USING_INLINE_ASM // inline asm version, unfortunately miscompiled by clang 3.2, at least on ubuntu.. so this will be restricted to gcc
  const float *a_ = a, *b_ = b; float *ab_ = ab;
  int N = Ncvec;
  asm volatile("mov         r8, %2                  \n"
               "vdup.f32    q15, %4                 \n"
               "1:                                  \n"
               "pld         [%0,#64]                \n"
               "pld         [%1,#64]                \n"
               "pld         [%2,#64]                \n"
               "pld         [%0,#96]                \n"
               "pld         [%1,#96]                \n"
               "pld         [%2,#96]                \n"
               "vld1.f32    {q0,q1},   [%0,:128]!         \n"
               "vld1.f32    {q4,q5},   [%1,:128]!         \n"
               "vld1.f32    {q2,q3},   [%0,:128]!         \n"
               "vld1.f32    {q6,q7},   [%1,:128]!         \n"
               "vld1.f32    {q8,q9},   [r8,:128]!          \n"

               "vmul.f32    q10, q0, q4             \n"
               "vmul.f32    q11, q0, q5             \n"
               "vmul.f32    q12, q2, q6             \n"
               "vmul.f32    q13, q2, q7             \n"
               "vmls.f32    q10, q1, q5             \n"
               "vmla.f32    q11, q1, q4             \n"
               "vld1.f32    {q0,q1}, [r8,:128]!     \n"
               "vmls.f32    q12, q3, q7             \n"
               "vmla.f32    q13, q3, q6             \n"
               "vmla.f32    q8, q10, q15            \n"
               "vmla.f32    q9, q11, q15            \n"
               "vmla.f32    q0, q12, q15            \n"
               "vmla.f32    q1, q13, q15            \n"
               "vst1.f32    {q8,q9},[%2,:128]!    \n"
               "vst1.f32    {q0,q1},[%2,:128]!    \n"
               "subs        %3, #2                  \n"
               "bne         1b                      \n"
               : "+r"(a_), "+r"(b_), "+r"(ab_), "+r"(N) : "r"(scaling) : "r8", "q0","q1","q2","q3","q4","q5","q6","q7","q8","q9", "q10","q11","q12","q13","q15","memory");
#else // default routine, works fine for non-arm cpus with current compilers
  for (i=0; i < Ncvec; i += 2) {
    v4sf ar, ai, br, bi;
    ar = va[2*i+0]; ai = va[2*i+1];
    br = vb[2*i+0]; bi = vb[2*i+1];
    VCPLXMUL(ar, ai, br, bi);
    vab[2*i+0] = VMADD(ar, vscal, vab[2*i+0]);
    vab[2*i+1] = VMADD(ai, vscal, vab[2*i+1]);
    ar = va[2*i+2]; ai = va[2*i+3];
    br = vb[2*i+2]; bi = vb[2*i+3];
    VCPLXMUL(ar, ai, br, bi);
    vab[2*i+2] = VMADD(ar, vscal, vab[2*i+2]);
    vab[2*i+3] = VMADD(ai, vscal, vab[2*i+3]);
  }
#endif
  if (s->transform == PFFFT_REAL) {
    ((v4sf_union*)vab)[0].f[0] = abr + ar*br*scaling;
    ((v4sf_union*)vab)[1].f[0] = abi + ai*bi*scaling;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x380, %rsp            # imm = 0x380
movq %rdi, -0x2a8(%rbp)
movq %rsi, -0x2b0(%rbp)
movq %rdx, -0x2b8(%rbp)
movq %rcx, -0x2c0(%rbp)
movss %xmm0, -0x2c4(%rbp)
movq -0x2a8(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x2c8(%rbp)
movq -0x2b0(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movq -0x2b8(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movq -0x2c0(%rbp), %rax
movq %rax, -0x2e0(%rbp)
movss -0x2c4(%rbp), %xmm0
movss %xmm0, -0x50(%rbp)
movaps -0x50(%rbp), %xmm0
shufps $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movaps %xmm0, -0x60(%rbp)
movaps -0x60(%rbp), %xmm0
movaps %xmm0, -0x310(%rbp)
movq -0x2b0(%rbp), %rax
andq $0xf, %rax
cmpq $0x0, %rax
jne 0xd1c2
movq -0x2b8(%rbp), %rax
andq $0xf, %rax
cmpq $0x0, %rax
jne 0xd1c2
movq -0x2c0(%rbp), %rax
andq $0xf, %rax
cmpq $0x0, %rax
jne 0xd1c2
jmp 0xd1e1
leaq 0xb77b(%rip), %rdi      # 0x18944
leaq 0xb00e(%rip), %rsi      # 0x181de
movl $0x6ac, %edx            # imm = 0x6AC
leaq 0xb793(%rip), %rcx      # 0x1896f
callq 0x1090
movq -0x2d0(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x2e4(%rbp)
movq -0x2d0(%rbp), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x2e8(%rbp)
movq -0x2d8(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x2ec(%rbp)
movq -0x2d8(%rbp), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x2f0(%rbp)
movq -0x2e0(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x2f4(%rbp)
movq -0x2e0(%rbp), %rax
movss 0x10(%rax), %xmm0
movss %xmm0, -0x2f8(%rbp)
movl $0x0, -0x314(%rbp)
movl -0x314(%rbp), %eax
cmpl -0x2c8(%rbp), %eax
jge 0xd7d2
movq -0x2d0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x330(%rbp)
movq -0x2d0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x340(%rbp)
movq -0x2d8(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x350(%rbp)
movq -0x2d8(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x360(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x360(%rbp), %xmm0
movaps %xmm1, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
movaps -0x70(%rbp), %xmm0
mulps -0x80(%rbp), %xmm0
movaps %xmm0, -0x370(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x350(%rbp), %xmm0
movaps %xmm1, -0x90(%rbp)
movaps %xmm0, -0xa0(%rbp)
movaps -0x90(%rbp), %xmm0
mulps -0xa0(%rbp), %xmm0
movaps %xmm0, -0x330(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x340(%rbp), %xmm2
movaps -0x360(%rbp), %xmm0
movaps %xmm2, -0xb0(%rbp)
movaps %xmm0, -0xc0(%rbp)
movaps -0xb0(%rbp), %xmm0
mulps -0xc0(%rbp), %xmm0
movaps %xmm1, -0x10(%rbp)
movaps %xmm0, -0x20(%rbp)
movaps -0x10(%rbp), %xmm0
subps -0x20(%rbp), %xmm0
movaps %xmm0, -0x330(%rbp)
movaps -0x340(%rbp), %xmm1
movaps -0x350(%rbp), %xmm0
movaps %xmm1, -0xd0(%rbp)
movaps %xmm0, -0xe0(%rbp)
movaps -0xd0(%rbp), %xmm0
mulps -0xe0(%rbp), %xmm0
movaps %xmm0, -0x340(%rbp)
movaps -0x340(%rbp), %xmm1
movaps -0x370(%rbp), %xmm0
movaps %xmm1, -0x1f0(%rbp)
movaps %xmm0, -0x200(%rbp)
movaps -0x1f0(%rbp), %xmm0
addps -0x200(%rbp), %xmm0
movaps %xmm0, -0x340(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x310(%rbp), %xmm0
movaps %xmm1, -0xf0(%rbp)
movaps %xmm0, -0x100(%rbp)
movaps -0xf0(%rbp), %xmm1
mulps -0x100(%rbp), %xmm1
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm1, -0x210(%rbp)
movaps %xmm0, -0x220(%rbp)
movaps -0x210(%rbp), %xmm0
addps -0x220(%rbp), %xmm0
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x0, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps %xmm0, (%rax)
movaps -0x340(%rbp), %xmm1
movaps -0x310(%rbp), %xmm0
movaps %xmm1, -0x110(%rbp)
movaps %xmm0, -0x120(%rbp)
movaps -0x110(%rbp), %xmm1
mulps -0x120(%rbp), %xmm1
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm1, -0x230(%rbp)
movaps %xmm0, -0x240(%rbp)
movaps -0x230(%rbp), %xmm0
addps -0x240(%rbp), %xmm0
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps %xmm0, (%rax)
movq -0x2d0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x330(%rbp)
movq -0x2d0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x340(%rbp)
movq -0x2d8(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x350(%rbp)
movq -0x2d8(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm0, -0x360(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x360(%rbp), %xmm0
movaps %xmm1, -0x130(%rbp)
movaps %xmm0, -0x140(%rbp)
movaps -0x130(%rbp), %xmm0
mulps -0x140(%rbp), %xmm0
movaps %xmm0, -0x380(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x350(%rbp), %xmm0
movaps %xmm1, -0x150(%rbp)
movaps %xmm0, -0x160(%rbp)
movaps -0x150(%rbp), %xmm0
mulps -0x160(%rbp), %xmm0
movaps %xmm0, -0x330(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x340(%rbp), %xmm2
movaps -0x360(%rbp), %xmm0
movaps %xmm2, -0x170(%rbp)
movaps %xmm0, -0x180(%rbp)
movaps -0x170(%rbp), %xmm0
mulps -0x180(%rbp), %xmm0
movaps %xmm1, -0x30(%rbp)
movaps %xmm0, -0x40(%rbp)
movaps -0x30(%rbp), %xmm0
subps -0x40(%rbp), %xmm0
movaps %xmm0, -0x330(%rbp)
movaps -0x340(%rbp), %xmm1
movaps -0x350(%rbp), %xmm0
movaps %xmm1, -0x190(%rbp)
movaps %xmm0, -0x1a0(%rbp)
movaps -0x190(%rbp), %xmm0
mulps -0x1a0(%rbp), %xmm0
movaps %xmm0, -0x340(%rbp)
movaps -0x340(%rbp), %xmm1
movaps -0x380(%rbp), %xmm0
movaps %xmm1, -0x250(%rbp)
movaps %xmm0, -0x260(%rbp)
movaps -0x250(%rbp), %xmm0
addps -0x260(%rbp), %xmm0
movaps %xmm0, -0x340(%rbp)
movaps -0x330(%rbp), %xmm1
movaps -0x310(%rbp), %xmm0
movaps %xmm1, -0x1b0(%rbp)
movaps %xmm0, -0x1c0(%rbp)
movaps -0x1b0(%rbp), %xmm1
mulps -0x1c0(%rbp), %xmm1
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm1, -0x270(%rbp)
movaps %xmm0, -0x280(%rbp)
movaps -0x270(%rbp), %xmm0
addps -0x280(%rbp), %xmm0
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x2, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps %xmm0, (%rax)
movaps -0x340(%rbp), %xmm1
movaps -0x310(%rbp), %xmm0
movaps %xmm1, -0x1d0(%rbp)
movaps %xmm0, -0x1e0(%rbp)
movaps -0x1d0(%rbp), %xmm1
mulps -0x1e0(%rbp), %xmm1
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps (%rax), %xmm0
movaps %xmm1, -0x290(%rbp)
movaps %xmm0, -0x2a0(%rbp)
movaps -0x290(%rbp), %xmm0
addps -0x2a0(%rbp), %xmm0
movq -0x2e0(%rbp), %rax
movl -0x314(%rbp), %ecx
shll %ecx
addl $0x3, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movaps %xmm0, (%rax)
movl -0x314(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x314(%rbp)
jmp 0xd260
movq -0x2a8(%rbp), %rax
cmpl $0x0, 0x44(%rax)
jne 0xd846
movss -0x2f4(%rbp), %xmm1
movss -0x2e4(%rbp), %xmm0
mulss -0x2ec(%rbp), %xmm0
movss -0x2c4(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x2e0(%rbp), %rax
movss %xmm0, (%rax)
movss -0x2f8(%rbp), %xmm1
movss -0x2e8(%rbp), %xmm0
mulss -0x2f0(%rbp), %xmm0
movss -0x2c4(%rbp), %xmm2
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movq -0x2e0(%rbp), %rax
movss %xmm0, 0x10(%rax)
addq $0x380, %rsp            # imm = 0x380
popq %rbp
retq
nop