// File: /workspace/github_cpp_makefile_star2_O2/hdlguy[P]fft_demo/fft.cpp
// Function: Fft::transformBluestein(std::vector<double, std::allocator<double>>&, std::vector<double, std::allocator<double>>&)
void Fft::transformBluestein(vector<double> &real, vector<double> &imag) {
	// Find a power-of-2 convolution length m such that m >= n * 2 + 1
	if (real.size() != imag.size())
		throw "Mismatched lengths";
	size_t n = real.size();
	size_t m;
	{
		size_t target;
		if (n > (SIZE_MAX - 1) / 2)
			throw "Vector too large";
		target = n * 2 + 1;
		for (m = 1; m < target; m *= 2) {
			if (SIZE_MAX / 2 < m)
				throw "Vector too large";
		}
	}
	
	// Trignometric tables
	vector<double> cosTable(n), sinTable(n);
	for (size_t i = 0; i < n; i++) {
		double temp = M_PI * (size_t)((unsigned long long)i * i % ((unsigned long long)n * 2)) / n;
		// Less accurate version if long long is unavailable: double temp = M_PI * i * i / n;
		cosTable[i] = cos(temp);
		sinTable[i] = sin(temp);
	}
	
	// Temporary vectors and preprocessing
	vector<double> areal(m), aimag(m);
	for (size_t i = 0; i < n; i++) {
		areal[i] =  real[i] * cosTable[i] + imag[i] * sinTable[i];
		aimag[i] = -real[i] * sinTable[i] + imag[i] * cosTable[i];
	}
	vector<double> breal(m), bimag(m);
	breal[0] = cosTable[0];
	bimag[0] = sinTable[0];
	for (size_t i = 1; i < n; i++) {
		breal[i] = breal[m - i] = cosTable[i];
		bimag[i] = bimag[m - i] = sinTable[i];
	}
	
	// Convolution
	vector<double> creal(m), cimag(m);
	convolve(areal, aimag, breal, bimag, creal, cimag);
	
	// Postprocessing
	for (size_t i = 0; i < n; i++) {
		real[i] =  creal[i] * cosTable[i] + cimag[i] * sinTable[i];
		imag[i] = -creal[i] * sinTable[i] + cimag[i] * cosTable[i];
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq 0x8(%rdi), %r13
movq %rdi, -0x68(%rbp)
subq (%rdi), %r13
movq 0x8(%rsi), %rax
subq (%rsi), %rax
cmpq %rax, %r13
jne 0x18df
movq %r13, %rbx
sarq $0x3, %rbx
js 0x18f0
shrq $0x2, %r13
pushq $0x1
popq %rax
movq %rax, %r12
addq %rax, %rax
cmpq %r13, %r12
jbe 0x15f6
movq %rsi, %r15
leaq -0x60(%rbp), %rdi
leaq -0x48(%rbp), %rdx
movq %rbx, %rsi
callq 0x1cde
leaq -0x48(%rbp), %rdi
leaq -0x108(%rbp), %rdx
movq %rbx, %rsi
callq 0x1cde
cvtsi2sd %rbx, %xmm0
movsd %xmm0, -0x70(%rbp)
xorl %r14d, %r14d
cmpq %r14, %rbx
je 0x1684
movq %r14, %rax
imulq %r14, %rax
xorl %edx, %edx
divq %r13
cvtsi2sd %rdx, %xmm0
mulsd 0x19be(%rip), %xmm0     # 0x3010
divsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
callq 0x1160
movq -0x60(%rbp), %rax
movsd %xmm0, (%rax,%r14,8)
movsd -0x78(%rbp), %xmm0
callq 0x1030
movq -0x48(%rbp), %rax
movsd %xmm0, (%rax,%r14,8)
incq %r14
jmp 0x1634
leaq -0x108(%rbp), %rdi
leaq -0xf0(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
leaq -0xf0(%rbp), %rdi
leaq -0xd8(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
movq %r15, %r14
movq -0x68(%rbp), %r15
movq (%r15), %rax
movq -0x60(%rbp), %rcx
movq (%r14), %rdx
movq -0x48(%rbp), %rsi
movq -0x108(%rbp), %rdi
movq -0xf0(%rbp), %r8
xorl %r9d, %r9d
cmpq %r9, %rbx
je 0x1724
movsd (%rax,%r9,8), %xmm0
movsd (%rdx,%r9,8), %xmm1
mulsd (%rsi,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rdi,%r9,8)
movsd (%rax,%r9,8), %xmm0
movsd (%rdx,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm1
mulsd (%rsi,%r9,8), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, (%r8,%r9,8)
incq %r9
jmp 0x16d6
leaq -0xd8(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
leaq -0xc0(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
movq -0x60(%rbp), %rax
movsd (%rax), %xmm0
movq -0xd8(%rbp), %rcx
movsd %xmm0, (%rcx)
movq -0x48(%rbp), %rdx
movsd (%rdx), %xmm0
movq -0xc0(%rbp), %rsi
movsd %xmm0, (%rsi)
leaq -0x1(%r12), %rdi
pushq $0x1
popq %r8
cmpq %rbx, %r8
jae 0x17ae
movsd (%rax,%r8,8), %xmm0
movsd %xmm0, (%rcx,%rdi,8)
movsd %xmm0, (%rcx,%r8,8)
movsd (%rdx,%r8,8), %xmm0
movsd %xmm0, (%rsi,%rdi,8)
movsd %xmm0, (%rsi,%r8,8)
incq %r8
decq %rdi
jmp 0x177f
leaq -0xa8(%rbp), %rdi
leaq -0x90(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
leaq -0x90(%rbp), %rdi
leaq -0x29(%rbp), %rdx
movq %r12, %rsi
callq 0x1cde
leaq -0x108(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
leaq -0xd8(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
leaq -0xa8(%rbp), %r8
leaq -0x90(%rbp), %r9
callq 0x19ae
movq -0xa8(%rbp), %rax
movq -0x60(%rbp), %rcx
movq -0x90(%rbp), %rdx
movq -0x48(%rbp), %rsi
movq (%r15), %rdi
movq (%r14), %r8
xorl %r9d, %r9d
cmpq %r9, %rbx
je 0x1873
movsd (%rax,%r9,8), %xmm0
movsd (%rdx,%r9,8), %xmm1
mulsd (%rsi,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rdi,%r9,8)
movsd (%rax,%r9,8), %xmm0
movsd (%rdx,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm1
mulsd (%rsi,%r9,8), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, (%r8,%r9,8)
incq %r9
jmp 0x1825
leaq -0x90(%rbp), %rdi
callq 0x1dc2
leaq -0xa8(%rbp), %rdi
callq 0x1dc2
leaq -0xc0(%rbp), %rdi
callq 0x1dc2
leaq -0xd8(%rbp), %rdi
callq 0x1dc2
leaq -0xf0(%rbp), %rdi
callq 0x1dc2
leaq -0x108(%rbp), %rdi
callq 0x1dc2
leaq -0x48(%rbp), %rdi
callq 0x1dc2
leaq -0x60(%rbp), %rdi
callq 0x1dc2
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x8
popq %rdi
callq 0x1070
leaq 0x1752(%rip), %rcx      # 0x3040
jmp 0x18ff
pushq $0x8
popq %rdi
callq 0x1070
leaq 0x176f(%rip), %rcx      # 0x306e
movq %rcx, (%rax)
movq 0x36bf(%rip), %rsi      # 0x4fc8
movq %rax, %rdi
xorl %edx, %edx
callq 0x1130
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x1dc2
jmp 0x1927
movq %rax, %rbx
leaq -0xa8(%rbp), %rdi
callq 0x1dc2
jmp 0x1938
movq %rax, %rbx
leaq -0xc0(%rbp), %rdi
callq 0x1dc2
jmp 0x1949
movq %rax, %rbx
leaq -0xd8(%rbp), %rdi
callq 0x1dc2
jmp 0x195a
movq %rax, %rbx
leaq -0xf0(%rbp), %rdi
callq 0x1dc2
leaq -0x108(%rbp), %rdi
callq 0x1dc2
leaq -0x48(%rbp), %rdi
callq 0x1dc2
leaq -0x60(%rbp), %rdi
callq 0x1dc2
movq %rbx, %rdi
callq 0x1150
movq %rax, %rbx
jmp 0x1966
movq %rax, %rbx
jmp 0x1972
movq %rax, %rbx
jmp 0x197b