// File: /workspace/github_cpp_makefile_star2_O1/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 $0x108, %rsp            # imm = 0x108
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 0x1a14
movq %r14, %r13
sarq $0x3, %r13
js 0x19ef
sarq $0x2, %r14
cmpq %rbx, -0x38(%rbp)
je 0x1679
movl $0x1, %r12d
testq %r12, %r12
js 0x19ef
addq %r12, %r12
cmpq %r14, %r12
jbe 0x1666
jmp 0x167f
movl $0x1, %r12d
movq %rdi, -0x78(%rbp)
movq %rsi, -0x80(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x50(%rbp), %rdx
movq %r13, %rsi
callq 0x1eb0
leaq -0x50(%rbp), %rdi
leaq -0x118(%rbp), %rdx
movq %r13, %rsi
callq 0x1eb0
movq %rbx, -0x70(%rbp)
cmpq %rbx, -0x38(%rbp)
je 0x1746
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
movq %rdx, %xmm1
punpckldq 0x1934(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x193c(%rip), %xmm1     # 0x3030
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
mulsd 0x1908(%rip), %xmm0     # 0x3010
divsd -0x88(%rbp), %xmm0
movapd %xmm0, -0x130(%rbp)
callq 0x1170
movq -0x68(%rbp), %rax
movsd %xmm0, (%rax,%r15,8)
movapd -0x130(%rbp), %xmm0
callq 0x1030
movq -0x50(%rbp), %rax
movsd %xmm0, (%rax,%r15,8)
incq %r15
cmpq %r15, %rbx
jne 0x16d3
leaq -0x118(%rbp), %rdi
leaq -0x100(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
leaq -0x100(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
movq -0x80(%rbp), %rbx
movq -0x78(%rbp), %r14
movq -0x70(%rbp), %r15
cmpq %r15, -0x38(%rbp)
je 0x17fa
movq (%r14), %rax
movq -0x68(%rbp), %rcx
movq (%rbx), %rdx
movq -0x50(%rbp), %rsi
movq -0x118(%rbp), %rdi
movq -0x100(%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 0x17ae
leaq -0xe8(%rbp), %rdi
leaq -0xd0(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
leaq -0xd0(%rbp), %rdi
leaq -0xb8(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
movq -0x68(%rbp), %rax
movsd (%rax), %xmm0
movq -0xe8(%rbp), %rcx
movsd %xmm0, (%rcx)
movq -0x50(%rbp), %rdx
movsd (%rdx), %xmm0
movq -0xd0(%rbp), %rsi
movsd %xmm0, (%rsi)
cmpq $0x2, %r13
jb 0x188a
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 0x185d
leaq -0xb8(%rbp), %rdi
leaq -0xa0(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
leaq -0xa0(%rbp), %rdi
leaq -0x29(%rbp), %rdx
movq %r12, %rsi
callq 0x1eb0
leaq -0x118(%rbp), %rdi
leaq -0x100(%rbp), %rsi
leaq -0xe8(%rbp), %rdx
leaq -0xd0(%rbp), %rcx
leaq -0xb8(%rbp), %r8
leaq -0xa0(%rbp), %r9
callq 0x1aea
cmpq %r15, -0x38(%rbp)
je 0x195b
movq -0xb8(%rbp), %rax
movq -0x68(%rbp), %rcx
movq -0xa0(%rbp), %rdx
movq -0x50(%rbp), %rsi
movq (%r14), %rdi
movq (%rbx), %r8
cmpq $0x1, %r13
adcq $0x0, %r13
xorl %r9d, %r9d
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
cmpq %r9, %r13
jne 0x190f
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x196c
callq 0x10c0
movq -0xb8(%rbp), %rdi
testq %rdi, %rdi
je 0x197d
callq 0x10c0
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x198e
callq 0x10c0
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x199f
callq 0x10c0
movq -0x100(%rbp), %rdi
testq %rdi, %rdi
je 0x19b0
callq 0x10c0
movq -0x118(%rbp), %rdi
testq %rdi, %rdi
je 0x19c1
callq 0x10c0
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x19cf
callq 0x10c0
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x19dd
callq 0x10c0
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x1070
leaq 0x166e(%rip), %rcx      # 0x306e
movq %rcx, (%rax)
movq 0x35be(%rip), %rsi      # 0x4fc8
movq %rax, %rdi
xorl %edx, %edx
callq 0x1140
movl $0x8, %edi
callq 0x1070
leaq 0x161b(%rip), %rcx      # 0x3040
jmp 0x1a00
movq %rax, %rbx
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x1a40
callq 0x10c0
jmp 0x1a40
movq %rax, %rbx
movq -0xb8(%rbp), %rdi
testq %rdi, %rdi
je 0x1a56
callq 0x10c0
jmp 0x1a56
movq %rax, %rbx
movq -0xd0(%rbp), %rdi
testq %rdi, %rdi
je 0x1a6c
callq 0x10c0
jmp 0x1a6c
movq %rax, %rbx
movq -0xe8(%rbp), %rdi
testq %rdi, %rdi
je 0x1a82
callq 0x10c0
jmp 0x1a82
movq %rax, %rbx
movq -0x100(%rbp), %rdi
testq %rdi, %rdi
je 0x1a98
callq 0x10c0
jmp 0x1a98
movq %rax, %rbx
movq -0x118(%rbp), %rdi
testq %rdi, %rdi
je 0x1aae
callq 0x10c0
jmp 0x1aae
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x1ac1
callq 0x10c0
jmp 0x1ac1
movq %rax, %rbx
movq -0x68(%rbp), %rdi
testq %rdi, %rdi
je 0x1acf
callq 0x10c0
movq %rbx, %rdi
callq 0x1160