// File: /workspace/github_cpp_makefile_star2_O2/hdlguy[P]fft_demo/fft.cpp
// Function: Fft::convolve(std::vector<double, std::allocator<double>> const&, std::vector<double, std::allocator<double>> const&, std::vector<double, std::allocator<double>> const&, std::vector<double, std::allocator<double>> const&, std::vector<double, std::allocator<double>>&, std::vector<double, std::allocator<double>>&)
void Fft::convolve(const vector<double> &xreal, const vector<double> &ximag, const vector<double> &yreal, const vector<double> &yimag, vector<double> &outreal, vector<double> &outimag) {
	if (xreal.size() != ximag.size() || xreal.size() != yreal.size() || yreal.size() != yimag.size() || xreal.size() != outreal.size() || outreal.size() != outimag.size())
		throw "Mismatched lengths";
	
	size_t n = xreal.size();
	vector<double> xr(xreal);
	vector<double> xi(ximag);
	vector<double> yr(yreal);
	vector<double> yi(yimag);
	
	transform(xr, xi);
	transform(yr, yi);
	for (size_t i = 0; i < n; i++) {
		double temp = xr[i] * yr[i] - xi[i] * yi[i];
		xi[i] = xi[i] * yr[i] + xr[i] * yi[i];
		xr[i] = temp;
	}
	inverseTransform(xr, xi);
	for (size_t i = 0; i < n; i++) {  // Scaling (because this FFT implementation omits it)
		outreal[i] = xr[i] / n;
		outimag[i] = xi[i] / n;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, -0x30(%rbp)
movq %rsi, %r13
movq 0x8(%rdi), %rbx
subq (%rdi), %rbx
movq 0x8(%rsi), %rax
subq (%rsi), %rax
cmpq %rax, %rbx
jne 0x1b75
movq %rdx, %r12
movq 0x8(%rdx), %rax
subq (%rdx), %rax
cmpq %rax, %rbx
jne 0x1b75
movq %rcx, %r15
movq 0x8(%rcx), %rax
subq (%rcx), %rax
cmpq %rax, %rbx
jne 0x1b75
movq %r8, %r14
movq 0x8(%r8), %rax
subq (%r8), %rax
cmpq %rax, %rbx
jne 0x1b75
movq -0x30(%rbp), %rcx
movq 0x8(%rcx), %rax
subq (%rcx), %rax
cmpq %rax, %rbx
jne 0x1b75
movq %rdi, %rsi
leaq -0x60(%rbp), %rdi
callq 0x1d30
leaq -0x48(%rbp), %rdi
movq %r13, %rsi
callq 0x1d30
leaq -0x90(%rbp), %rdi
movq %r12, %rsi
callq 0x1d30
leaq -0x78(%rbp), %rdi
movq %r15, %rsi
callq 0x1d30
leaq -0x60(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x12bc
leaq -0x90(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x12bc
sarq $0x3, %rbx
movq -0x60(%rbp), %rax
movq -0x90(%rbp), %rcx
movq -0x48(%rbp), %rdx
movq -0x78(%rbp), %rsi
xorl %edi, %edi
cmpq %rdi, %rbx
je 0x1ad7
movsd (%rax,%rdi,8), %xmm0
movsd (%rcx,%rdi,8), %xmm1
movsd (%rdx,%rdi,8), %xmm2
movsd (%rsi,%rdi,8), %xmm3
movapd %xmm0, %xmm4
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm3
mulsd %xmm1, %xmm4
subsd %xmm3, %xmm4
mulsd %xmm1, %xmm2
addsd %xmm0, %xmm2
movsd %xmm2, (%rdx,%rdi,8)
movsd %xmm4, (%rax,%rdi,8)
incq %rdi
jmp 0x1a93
leaq -0x48(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x12bc
movq %rbx, %xmm1
punpckldq 0x152f(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x1537(%rip), %xmm1     # 0x3030
movq -0x60(%rbp), %rax
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
movq (%r14), %rcx
movq -0x48(%rbp), %rdx
movq -0x30(%rbp), %rsi
movq (%rsi), %rsi
xorl %edi, %edi
cmpq %rdi, %rbx
je 0x1b3f
movsd (%rax,%rdi,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rcx,%rdi,8)
movsd (%rdx,%rdi,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsi,%rdi,8)
incq %rdi
jmp 0x1b19
leaq -0x78(%rbp), %rdi
callq 0x1dc2
leaq -0x90(%rbp), %rdi
callq 0x1dc2
leaq -0x48(%rbp), %rdi
callq 0x1dc2
leaq -0x60(%rbp), %rdi
callq 0x1dc2
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x8
popq %rdi
callq 0x1070
leaq 0x14bc(%rip), %rcx      # 0x3040
movq %rcx, (%rax)
movq 0x343a(%rip), %rsi      # 0x4fc8
movq %rax, %rdi
xorl %edx, %edx
callq 0x1130
movq %rax, %rbx
jmp 0x1bb3
movq %rax, %rbx
jmp 0x1bbf
movq %rax, %rbx
jmp 0x1bc8
movq %rax, %rbx
leaq -0x78(%rbp), %rdi
callq 0x1dc2
leaq -0x90(%rbp), %rdi
callq 0x1dc2
leaq -0x48(%rbp), %rdi
callq 0x1dc2
leaq -0x60(%rbp), %rdi
callq 0x1dc2
movq %rbx, %rdi
callq 0x1150