// File: /workspace/github_cpp_makefile_star2_O3/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 $0xf8, %rsp
movq (%rdi), %rbx
movq 0x8(%rdi), %r14
movq %r14, -0x38(%rbp)
subq %rbx, %r14
movq 0x8(%rsi), %rax
subq (%rsi), %rax
cmpq %rax, %r14
jne 0x19e7
movq %r14, %r13
sarq $0x3, %r13
js 0x19c2
shrq $0x2, %r14
cmpq %rbx, -0x38(%rbp)
je 0x166e
movl $0x1, %r12d
testq %r12, %r12
js 0x19c2
addq %r12, %r12
cmpq %r14, %r12
jbe 0x165b
jmp 0x1674
movl $0x1, %r12d
movq %rdi, -0x78(%rbp)
movq %rsi, -0x80(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x50(%rbp), %rdx
movq %r13, %rsi
callq 0x1e84
leaq -0x50(%rbp), %rdi
leaq -0x108(%rbp), %rdx
movq %r13, %rsi
callq 0x1e84
movq %rbx, -0x70(%rbp)
cmpq %rbx, -0x38(%rbp)
je 0x171e
cvtsi2sd %r13, %xmm0
movsd %xmm0, -0x88(%rbp)
cmpq $0x1, %r13
movq %r13, %rbx
adcq $0x0, %rbx
xorl %r15d, %r15d
movq %r15, %rax
imulq %r15, %rax
xorl %edx, %edx
divq %r14
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
mulsd 0x1930(%rip), %xmm0     # 0x3010
divsd -0x88(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
callq 0x1170
movq -0x68(%rbp), %rax
movsd %xmm0, (%rax,%r15,8)
movsd -0x90(%rbp), %xmm0
callq 0x1030
movq -0x50(%rbp), %rax
movsd %xmm0, (%rax,%r15,8)
incq %r15
cmpq %r15, %rbx
jne 0x16c4
leaq -0x108(%rbp), %rdi
leaq -0xf0(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
leaq -0xf0(%rbp), %rdi
leaq -0xd8(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
movq -0x80(%rbp), %rbx
movq -0x78(%rbp), %r14
movq -0x70(%rbp), %r15
cmpq %r15, -0x38(%rbp)
je 0x17d2
movq (%r14), %rax
movq -0x68(%rbp), %rcx
movq (%rbx), %rdx
movq -0x50(%rbp), %rsi
movq -0x108(%rbp), %rdi
movq -0xf0(%rbp), %r8
cmpq $0x1, %r13
movq %r13, %r9
adcq $0x0, %r9
xorl %r10d, %r10d
movsd (%rax,%r10,8), %xmm0
movsd (%rdx,%r10,8), %xmm1
mulsd (%rsi,%r10,8), %xmm1
mulsd (%rcx,%r10,8), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rdi,%r10,8)
movsd (%rax,%r10,8), %xmm0
movsd (%rdx,%r10,8), %xmm1
mulsd (%rcx,%r10,8), %xmm1
mulsd (%rsi,%r10,8), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, (%r8,%r10,8)
incq %r10
cmpq %r10, %r9
jne 0x1786
leaq -0xd8(%rbp), %rdi
leaq -0xc0(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
leaq -0xc0(%rbp), %rdi
leaq -0xa8(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
movq -0x68(%rbp), %rax
movsd (%rax), %xmm0
movq -0xd8(%rbp), %rcx
movsd %xmm0, (%rcx)
movq -0x50(%rbp), %rdx
movsd (%rdx), %xmm0
movq -0xc0(%rbp), %rsi
movsd %xmm0, (%rsi)
cmpq $0x2, %r13
jb 0x1862
leaq -0x1(%r12), %rdi
movl $0x1, %r8d
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
cmpq %r8, %r13
jne 0x1835
leaq -0xa8(%rbp), %rdi
leaq -0x120(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
leaq -0x120(%rbp), %rdi
leaq -0x29(%rbp), %rdx
movq %r12, %rsi
callq 0x1e84
leaq -0x108(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
leaq -0xd8(%rbp), %rdx
leaq -0xc0(%rbp), %rcx
leaq -0xa8(%rbp), %r8
leaq -0x120(%rbp), %r9
callq 0x1abd
movq -0x120(%rbp), %rdi
cmpq %r15, -0x38(%rbp)
je 0x1935
movq -0xa8(%rbp), %rax
movq -0x68(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq (%r14), %rsi
movq (%rbx), %r8
cmpq $0x1, %r13
adcq $0x0, %r13
xorl %r9d, %r9d
movsd (%rax,%r9,8), %xmm0
movsd (%rdi,%r9,8), %xmm1
mulsd (%rdx,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rsi,%r9,8)
movsd (%rax,%r9,8), %xmm0
movsd (%rdi,%r9,8), %xmm1
mulsd (%rcx,%r9,8), %xmm1
mulsd (%rdx,%r9,8), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, (%r8,%r9,8)
incq %r9
cmpq %r9, %r13
jne 0x18e7
jmp 0x193a
testq %rdi, %rdi
je 0x193f
callq 0x10c0
movq -0xa8(%rbp), %rdi
testq %rdi, %rdi
je 0x1950
callq 0x10c0
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x1961
callq 0x10c0
movq -0xd8(%rbp), %rdi
testq %rdi, %rdi
je 0x1972
callq 0x10c0
movq -0xf0(%rbp), %rdi
testq %rdi, %rdi
je 0x1983
callq 0x10c0
movq -0x108(%rbp), %rdi
testq %rdi, %rdi
je 0x1994
callq 0x10c0
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x19a2
callq 0x10c0
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x19b0
callq 0x10c0
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x1070
leaq 0x169b(%rip), %rcx      # 0x306e
movq %rcx, (%rax)
movq 0x35eb(%rip), %rsi      # 0x4fc8
movq %rax, %rdi
xorl %edx, %edx
callq 0x1140
movl $0x8, %edi
callq 0x1070
leaq 0x1648(%rip), %rcx      # 0x3040
jmp 0x19d3
movq %rax, %rbx
movq -0x120(%rbp), %rdi
testq %rdi, %rdi
je 0x1a13
callq 0x10c0
jmp 0x1a13
movq %rax, %rbx
movq -0xa8(%rbp), %rdi
testq %rdi, %rdi
je 0x1a29
callq 0x10c0
jmp 0x1a29
movq %rax, %rbx
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x1a3f
callq 0x10c0
jmp 0x1a3f
movq %rax, %rbx
movq -0xd8(%rbp), %rdi
testq %rdi, %rdi
je 0x1a55
callq 0x10c0
jmp 0x1a55
movq %rax, %rbx
movq -0xf0(%rbp), %rdi
testq %rdi, %rdi
je 0x1a6b
callq 0x10c0
jmp 0x1a6b
movq %rax, %rbx
movq -0x108(%rbp), %rdi
testq %rdi, %rdi
je 0x1a81
callq 0x10c0
jmp 0x1a81
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x1a94
callq 0x10c0
jmp 0x1a94
movq %rax, %rbx
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x1aa2
callq 0x10c0
movq %rbx, %rdi
callq 0x1160